diff options
author | marha <marha@users.sourceforge.net> | 2013-12-22 12:51:45 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-12-22 12:51:45 +0100 |
commit | c81020559f329a516191927222b3698ba7370aca (patch) | |
tree | 6f004f5723ca41881b2ba703ed619a92faebfe16 /mesalib/src/mesa | |
parent | c043f97a8572e1f509251288d8bcd70d0fb96770 (diff) | |
download | vcxsrv-c81020559f329a516191927222b3698ba7370aca.tar.gz vcxsrv-c81020559f329a516191927222b3698ba7370aca.tar.bz2 vcxsrv-c81020559f329a516191927222b3698ba7370aca.zip |
libxtrans fontconfig glproto libX11 libxcb xcbproto mesa xserver pixman xkeyboard-config git update 22 Dec 2013
xserver commit a68df147421da21528b5be2d34678383922fa352
libxcb commit f653464554469b5767f1c99abced25a76bace047
libxcb/xcb-proto commit 4087fc682c5ceb849b74442e17a6b73176e5eecb
xkeyboard-config commit a224a636139d22e1dc7ca7d23782cd656e87bcf5
libX11 commit 3d69b0a83e62f8f6fbdd952fc49cdbdf8825e1e6
libXdmcp commit 089081dca4ba3598c6f9bf401c029378943b5854
libXext commit bb24f2970f2e425f4df90c9b73d078ad15a73fbb
libfontenc commit 3acba630d8b57084f7e92c15732408711ed5137a
libXinerama commit edd95182b26eb5d576d4878c559e0f17dddaa909
libXau commit 304a11be4727c5a7feeb2501e8e001466f8ce84e
xkbcomp commit e3e6e938535532bfad175c1635256ab7fb3ac943
pixman commit 945ab7a6f3eb6241f07e8f094dc0e647d1f10d9d
xextproto commit 3f355f138d6df57e067458a20f47307883048adb
randrproto commit e7526e6b5fe0966929cda10b2ded0258413744db
glproto commit f84853d97d5749308992412a215fa518b6536eb3
mkfontscale commit 880a0c4733e62e54e6a0f1238c7430727d23657b
xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13
libXft commit 4acfdaf95adb0a05c2a25550bdde036c865902f4
libXmu commit 22d9c590901e121936f50dee97dc60c4f7defb63
libxtrans commit 2c0a7840a28ae696e80e73157856d7a049fdf6c7
fontconfig commit 5c725f2f5829238d16116f782d00d8bb0defaf08
mesa commit 2efe7927d38983029784825fc4897e9b77aa237e
Diffstat (limited to 'mesalib/src/mesa')
71 files changed, 2537 insertions, 3038 deletions
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am index a60600e03..884383652 100644 --- a/mesalib/src/mesa/Makefile.am +++ b/mesalib/src/mesa/Makefile.am @@ -103,7 +103,11 @@ noinst_PROGRAMS = gen_matypes gen_matypes_SOURCES = x86/gen_matypes.c BUILT_SOURCES += matypes.h -ARCH_LIBS = libmesa_sse41.la +ARCH_LIBS = + +if SSE41_SUPPORTED +ARCH_LIBS += libmesa_sse41.la +endif if HAVE_X86_64_ASM MESA_ASM_FILES_FOR_ARCH += $(X86_64_FILES) diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources index a84f8a788..39525bc5b 100644 --- a/mesalib/src/mesa/Makefile.sources +++ b/mesalib/src/mesa/Makefile.sources @@ -103,6 +103,7 @@ MAIN_FILES = \ $(SRCDIR)main/texstate.c \ $(SRCDIR)main/texstorage.c \ $(SRCDIR)main/texstore.c \ + $(SRCDIR)main/textureview.c \ $(SRCDIR)main/texturebarrier.c \ $(SRCDIR)main/transformfeedback.c \ $(SRCDIR)main/uniforms.c \ diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index a2bb9f131..bb9b304ef 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -133,6 +133,7 @@ main_sources = [ 'main/texstorage.c', 'main/texstore.c', 'main/texturebarrier.c', + 'main/textureview.c', 'main/transformfeedback.c', 'main/uniform_query.cpp', 'main/uniforms.c', diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c index 5faa98af1..f18568827 100644 --- a/mesalib/src/mesa/drivers/common/driverfuncs.c +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -211,6 +211,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) /* GL_ARB_texture_storage */ driver->AllocTextureStorage = _mesa_alloc_texture_storage; + /* GL_ARB_texture_view */ + driver->TextureView = NULL; + /* GL_ARB_texture_multisample */ driver->GetSamplePosition = NULL; } diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 0bce77ea9..d64821112 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -438,16 +438,19 @@ driCreateContextAttribs(__DRIscreen *screen, int api, return NULL; } - struct gl_context *ctx = context->driverPrivate; + *error = __DRI_CTX_ERROR_SUCCESS; + return context; +} + +void +driContextSetFlags(struct gl_context *ctx, uint32_t flags) +{ if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; ctx->Debug.DebugOutput = GL_TRUE; } - - *error = __DRI_CTX_ERROR_SUCCESS; - return context; } static __DRIcontext * @@ -873,3 +876,18 @@ const __DRIimageDriverExtension driImageDriverExtension = { .getAPIMask = driGetAPIMask, .createContextAttribs = driCreateContextAttribs, }; + +/* swrast copy sub buffer entrypoint. */ +static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y, + int w, int h) +{ + assert(pdp->driScreenPriv->swrast_loader); + + pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h); +} + +/* for swrast only */ +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + { __DRI_COPY_SUB_BUFFER, 1 }, + .copySubBuffer = driCopySubBuffer, +}; diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h index 79a8564ad..a79a4ed7a 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.h +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h @@ -66,7 +66,7 @@ extern const __DRIcoreExtension driCoreExtension; extern const __DRIswrastExtension driSWRastExtension; extern const __DRIdri2Extension driDRI2Extension; extern const __DRI2configQueryExtension dri2ConfigQueryExtension; - +extern const __DRIcopySubBufferExtension driCopySubBufferExtension; /** * Driver callback functions. * @@ -115,6 +115,9 @@ struct __DriverAPIRec { int width, int height); void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer); + + void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y, + int w, int h); }; extern const struct __DriverAPIRec driDriverAPI; @@ -289,6 +292,9 @@ dri2InvalidateDrawable(__DRIdrawable *drawable); extern void driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv); +extern void +driContextSetFlags(struct gl_context *ctx, uint32_t flags); + extern const __DRIimageDriverExtension driImageDriverExtension; #endif /* _DRI_UTIL_H_ */ diff --git a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c index 6bf5d7327..a8217703d 100644 --- a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c +++ b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c @@ -23,6 +23,132 @@ #include <stdio.h> #include "dri_util.h" +#include <dlfcn.h> +#include "main/macros.h" + +/* We need GNU extensions to dlfcn.h in order to provide backward + * compatibility for the older DRI driver loader mechanism. (dladdr, + * Dl_info, and RTLD_DEFAULT are only defined when _GNU_SOURCE is + * defined.) + */ +#ifdef _GNU_SOURCE + +#define MEGADRIVER_STUB_MAX_EXTENSIONS 10 +#define LIB_PATH_SUFFIX "_dri.so" +#define LIB_PATH_SUFFIX_LENGTH (sizeof(LIB_PATH_SUFFIX)-1) + +/* This is the table of extensions that the loader will dlsym() for. + * + * Initially it is empty for the megadriver stub, but the library + * constructor may initialize it based on the name of the library that + * is being loaded. + */ +PUBLIC const __DRIextension * +__driDriverExtensions[MEGADRIVER_STUB_MAX_EXTENSIONS] = { + NULL +}; + +/** + * This is a constructor function for the megadriver dynamic library. + * + * When the driver is dlopen'ed, this function will run. It will + * search for the name of the foo_dri.so file that was opened using + * the dladdr function. + * + * After finding foo's name, it will call __driDriverGetExtensions_foo + * and use the return to update __driDriverExtensions to enable + * compatibility with older DRI driver loaders. + */ +__attribute__((constructor)) static void +megadriver_stub_init(void) +{ + Dl_info info; + char *driver_name; + size_t name_len; + char *get_extensions_name; + const __DRIextension **(*get_extensions)(void); + const __DRIextension **extensions; + int i; + + /* Call dladdr on __driDriverExtensions. We are really + * interested in the returned info.dli_fname so we can + * figure out the path name of the library being loaded. + */ + i = dladdr((void*) __driDriverExtensions, &info); + if (i == 0) + return; + + /* Search for the last '/' character in the path. */ + driver_name = strrchr(info.dli_fname, '/'); + if (driver_name != NULL) { + /* Skip '/' character */ + driver_name++; + } else { + /* Try using the start of the path */ + driver_name = (char*) info.dli_fname; + } + + /* Make sure the path ends with _dri.so */ + name_len = strlen(driver_name); + i = name_len - LIB_PATH_SUFFIX_LENGTH; + if (i < 0 || strcmp(driver_name + i, LIB_PATH_SUFFIX) != 0) + return; + + /* Duplicate the string so we can modify it. + * So far we've been using info.dli_fname. + */ + driver_name = strdup(driver_name); + if (!driver_name) + return; + + /* The path ends with _dri.so. Chop this part of the + * string off. Then we'll have the driver's final name. + */ + driver_name[i] = '\0'; + + i = asprintf(&get_extensions_name, "%s_%s", + __DRI_DRIVER_GET_EXTENSIONS, driver_name); + free(driver_name); + if (i == -1) + return; + + /* dlsym to get the driver's get extensions function. We + * don't have the dlopen handle, so we have to use + * RTLD_DEFAULT. It seems unlikely that the symbol will + * be found in another library, but this isn't optimal. + */ + get_extensions = dlsym(RTLD_DEFAULT, get_extensions_name); + free(get_extensions_name); + if (!get_extensions) + return; + + /* Use the newer DRI loader entrypoint to find extensions. + * We will then expose these extensions via the older + * __driDriverExtensions symbol. + */ + extensions = get_extensions(); + + /* Copy the extensions into the __driDriverExtensions array + * we declared. + */ + for (i = 0; i < ARRAY_SIZE(__driDriverExtensions); i++) { + __driDriverExtensions[i] = extensions[i]; + if (extensions[i] == NULL) + break; + } + + /* If the driver had more extensions than we reserved, then + * bail out. + */ + if (i == ARRAY_SIZE(__driDriverExtensions)) { + __driDriverExtensions[0] = NULL; + fprintf(stderr, "Megadriver stub did not reserve enough extension " + "slots.\n"); + return; + } +} + +#endif /* _GNU_SOURCE */ static const __DRIconfig **stub_error_init_screen(__DRIscreen *psp) diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 73dc5c4c0..79a27408f 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -402,7 +402,7 @@ swrast_map_renderbuffer(struct gl_context *ctx, stride = w * cpp; xrb->Base.Buffer = malloc(h * stride); - sPriv->swrast_loader->getImage(dPriv, x, y, w, h, + sPriv->swrast_loader->getImage(dPriv, x, rb->Height - y - h, w, h, (char *) xrb->Base.Buffer, dPriv->loaderPrivate); @@ -705,6 +705,8 @@ dri_create_context(gl_api api, goto context_fail; } + driContextSetFlags(mesaCtx, flags); + /* do bounds checking to prevent segfaults and server crashes! */ mesaCtx->Const.CheckArrayBounds = GL_TRUE; @@ -820,6 +822,39 @@ dri_unbind_context(__DRIcontext * cPriv) return GL_TRUE; } +static void +dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y, + int w, int h) +{ + __DRIscreen *sPriv = dPriv->driScreenPriv; + void *data; + int iy; + struct dri_drawable *drawable = dri_drawable(dPriv); + struct gl_framebuffer *fb; + struct dri_swrast_renderbuffer *frontrb, *backrb; + + TRACE; + + fb = &drawable->Base; + + frontrb = + dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + backrb = + dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + + /* check for signle-buffered */ + if (backrb == NULL) + return; + + iy = frontrb->Base.Base.Height - y - h; + data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8)); + sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, + x, iy, w, h, + frontrb->pitch, + data, + dPriv->loaderPrivate); +} + static const struct __DriverAPIRec swrast_driver_api = { .InitScreen = dri_init_screen, @@ -831,6 +866,7 @@ static const struct __DriverAPIRec swrast_driver_api = { .SwapBuffers = dri_swap_buffers, .MakeCurrent = dri_make_current, .UnbindContext = dri_unbind_context, + .CopySubBuffer = dri_copy_sub_buffer, }; static const struct __DRIDriverVtableExtensionRec swrast_vtable = { @@ -841,6 +877,7 @@ static const struct __DRIDriverVtableExtensionRec swrast_vtable = { static const __DRIextension *swrast_driver_extensions[] = { &driCoreExtension.base, &driSWRastExtension.base, + &driCopySubBufferExtension.base, &swrast_vtable.base, NULL }; diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index c9332bd52..30c815d67 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -182,7 +182,7 @@ struct texture_state * Allocate new attribute node of given type/kind. Attach payload data. * Insert it into the linked list named by 'head'. */ -static void +static bool save_attrib_data(struct gl_attrib_node **head, GLbitfield kind, void *payload) { @@ -196,7 +196,42 @@ save_attrib_data(struct gl_attrib_node **head, } else { /* out of memory! */ + return false; + } + return true; +} + + +/** + * Helper function for_mesa_PushAttrib for simple attributes. + * Allocates memory for attribute data and copies the given attribute data. + * \param head head of linked list to insert attribute data into + * \param attr_bit one of the GL_<attrib>_BIT flags + * \param attr_size number of bytes to allocate for attribute data + * \param attr_data the attribute data to copy + * \return true for success, false for out of memory + */ +static bool +push_attrib(struct gl_context *ctx, struct gl_attrib_node **head, + GLbitfield attr_bit, GLuint attr_size, const void *attr_data) +{ + void *attribute; + + attribute = MALLOC(attr_size); + if (attribute == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + return false; + } + + if (save_attrib_data(head, attr_bit, attribute)) { + memcpy(attribute, attr_data, attr_size); } + else { + FREE(attribute); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + return false; + } + return true; } @@ -220,42 +255,58 @@ _mesa_PushAttrib(GLbitfield mask) head = NULL; if (mask & GL_ACCUM_BUFFER_BIT) { - struct gl_accum_attrib *attr; - attr = MALLOC_STRUCT( gl_accum_attrib ); - memcpy( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); - save_attrib_data(&head, GL_ACCUM_BUFFER_BIT, attr); + if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT, + sizeof(struct gl_accum_attrib), + (void*)&ctx->Accum)) + goto end; } if (mask & GL_COLOR_BUFFER_BIT) { GLuint i; struct gl_colorbuffer_attrib *attr; attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); - memcpy( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); - /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */ - for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++) - attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; - save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr); + if (attr == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } + + if (save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr)) { + memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib)); + /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */ + for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++) + attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; + } + else { + FREE(attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } } if (mask & GL_CURRENT_BIT) { - struct gl_current_attrib *attr; - FLUSH_CURRENT( ctx, 0 ); - attr = MALLOC_STRUCT( gl_current_attrib ); - memcpy( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); - save_attrib_data(&head, GL_CURRENT_BIT, attr); + FLUSH_CURRENT(ctx, 0); + if (!push_attrib(ctx, &head, GL_CURRENT_BIT, + sizeof(struct gl_current_attrib), + (void*)&ctx->Current)) + goto end; } if (mask & GL_DEPTH_BUFFER_BIT) { - struct gl_depthbuffer_attrib *attr; - attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); - memcpy( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); - save_attrib_data(&head, GL_DEPTH_BUFFER_BIT, attr); + if (!push_attrib(ctx, &head, GL_DEPTH_BUFFER_BIT, + sizeof(struct gl_depthbuffer_attrib), + (void*)&ctx->Depth)) + goto end; } if (mask & GL_ENABLE_BIT) { struct gl_enable_attrib *attr; GLuint i; attr = MALLOC_STRUCT( gl_enable_attrib ); + if (attr == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } + /* Copy enable flags from all other attributes into the enable struct. */ attr->AlphaTest = ctx->Color.AlphaEnabled; attr->AutoNormal = ctx->Eval.AutoNormal; @@ -322,97 +373,112 @@ _mesa_PushAttrib(GLbitfield mask) /* GL_ARB_fragment_program */ attr->FragmentProgram = ctx->FragmentProgram.Enabled; - save_attrib_data(&head, GL_ENABLE_BIT, attr); + if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) { + FREE(attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ attr->sRGBEnabled = ctx->Color.sRGBEnabled; } if (mask & GL_EVAL_BIT) { - struct gl_eval_attrib *attr; - attr = MALLOC_STRUCT( gl_eval_attrib ); - memcpy( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); - save_attrib_data(&head, GL_EVAL_BIT, attr); + if (!push_attrib(ctx, &head, GL_EVAL_BIT, + sizeof(struct gl_eval_attrib), + (void*)&ctx->Eval)) + goto end; } if (mask & GL_FOG_BIT) { - struct gl_fog_attrib *attr; - attr = MALLOC_STRUCT( gl_fog_attrib ); - memcpy( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); - save_attrib_data(&head, GL_FOG_BIT, attr); + if (!push_attrib(ctx, &head, GL_FOG_BIT, + sizeof(struct gl_fog_attrib), + (void*)&ctx->Fog)) + goto end; } if (mask & GL_HINT_BIT) { - struct gl_hint_attrib *attr; - attr = MALLOC_STRUCT( gl_hint_attrib ); - memcpy( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); - save_attrib_data(&head, GL_HINT_BIT, attr); + if (!push_attrib(ctx, &head, GL_HINT_BIT, + sizeof(struct gl_hint_attrib), + (void*)&ctx->Hint)) + goto end; } if (mask & GL_LIGHTING_BIT) { - struct gl_light_attrib *attr; - FLUSH_CURRENT(ctx, 0); /* flush material changes */ - attr = MALLOC_STRUCT( gl_light_attrib ); - memcpy( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); - save_attrib_data(&head, GL_LIGHTING_BIT, attr); + FLUSH_CURRENT(ctx, 0); /* flush material changes */ + if (!push_attrib(ctx, &head, GL_LIGHTING_BIT, + sizeof(struct gl_light_attrib), + (void*)&ctx->Light)) + goto end; } if (mask & GL_LINE_BIT) { - struct gl_line_attrib *attr; - attr = MALLOC_STRUCT( gl_line_attrib ); - memcpy( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); - save_attrib_data(&head, GL_LINE_BIT, attr); + if (!push_attrib(ctx, &head, GL_LINE_BIT, + sizeof(struct gl_line_attrib), + (void*)&ctx->Line)) + goto end; } if (mask & GL_LIST_BIT) { - struct gl_list_attrib *attr; - attr = MALLOC_STRUCT( gl_list_attrib ); - memcpy( attr, &ctx->List, sizeof(struct gl_list_attrib) ); - save_attrib_data(&head, GL_LIST_BIT, attr); + if (!push_attrib(ctx, &head, GL_LIST_BIT, + sizeof(struct gl_list_attrib), + (void*)&ctx->List)) + goto end; } if (mask & GL_PIXEL_MODE_BIT) { struct gl_pixel_attrib *attr; attr = MALLOC_STRUCT( gl_pixel_attrib ); - memcpy( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); - /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ - attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; - save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr); + if (attr == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } + + if (save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr)) { + memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib)); + /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ + attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; + } + else { + FREE(attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); + goto end; + } } if (mask & GL_POINT_BIT) { - struct gl_point_attrib *attr; - attr = MALLOC_STRUCT( gl_point_attrib ); - memcpy( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); - save_attrib_data(&head, GL_POINT_BIT, attr); + if (!push_attrib(ctx, &head, GL_POINT_BIT, + sizeof(struct gl_point_attrib), + (void*)&ctx->Point)) + goto end; } if (mask & GL_POLYGON_BIT) { - struct gl_polygon_attrib *attr; - attr = MALLOC_STRUCT( gl_polygon_attrib ); - memcpy( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); - save_attrib_data(&head, GL_POLYGON_BIT, attr); + if (!push_attrib(ctx, &head, GL_POLYGON_BIT, + sizeof(struct gl_polygon_attrib), + (void*)&ctx->Polygon)) + goto end; } if (mask & GL_POLYGON_STIPPLE_BIT) { - GLuint *stipple; - stipple = malloc( 32*sizeof(GLuint) ); - memcpy( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); - save_attrib_data(&head, GL_POLYGON_STIPPLE_BIT, stipple); + if (!push_attrib(ctx, &head, GL_POLYGON_STIPPLE_BIT, + sizeof(ctx->PolygonStipple), + (void*)&ctx->PolygonStipple)) + goto end; } if (mask & GL_SCISSOR_BIT) { - struct gl_scissor_attrib *attr; - attr = MALLOC_STRUCT( gl_scissor_attrib ); - memcpy( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); - save_attrib_data(&head, GL_SCISSOR_BIT, attr); + if (!push_attrib(ctx, &head, GL_SCISSOR_BIT, + sizeof(struct gl_scissor_attrib), + (void*)&ctx->Scissor)) + goto end; } if (mask & GL_STENCIL_BUFFER_BIT) { - struct gl_stencil_attrib *attr; - attr = MALLOC_STRUCT( gl_stencil_attrib ); - memcpy( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); - save_attrib_data(&head, GL_STENCIL_BUFFER_BIT, attr); + if (!push_attrib(ctx, &head, GL_STENCIL_BUFFER_BIT, + sizeof(struct gl_stencil_attrib), + (void*)&ctx->Stencil)) + goto end; } if (mask & GL_TEXTURE_BIT) { @@ -424,6 +490,12 @@ _mesa_PushAttrib(GLbitfield mask) goto end; } + if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) { + FREE(texstate); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); + goto end; + } + _mesa_lock_context_textures(ctx); /* copy/save the bulk of texture state here */ @@ -450,35 +522,35 @@ _mesa_PushAttrib(GLbitfield mask) _mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared); _mesa_unlock_context_textures(ctx); - - save_attrib_data(&head, GL_TEXTURE_BIT, texstate); } if (mask & GL_TRANSFORM_BIT) { - struct gl_transform_attrib *attr; - attr = MALLOC_STRUCT( gl_transform_attrib ); - memcpy( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); - save_attrib_data(&head, GL_TRANSFORM_BIT, attr); + if (!push_attrib(ctx, &head, GL_TRANSFORM_BIT, + sizeof(struct gl_transform_attrib), + (void*)&ctx->Transform)) + goto end; } if (mask & GL_VIEWPORT_BIT) { - struct gl_viewport_attrib *attr; - attr = MALLOC_STRUCT( gl_viewport_attrib ); - memcpy( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); - save_attrib_data(&head, GL_VIEWPORT_BIT, attr); + if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT, + sizeof(struct gl_viewport_attrib), + (void*)&ctx->Viewport)) + goto end; } /* GL_ARB_multisample */ if (mask & GL_MULTISAMPLE_BIT_ARB) { - struct gl_multisample_attrib *attr; - attr = MALLOC_STRUCT( gl_multisample_attrib ); - memcpy( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) ); - save_attrib_data(&head, GL_MULTISAMPLE_BIT_ARB, attr); + if (!push_attrib(ctx, &head, GL_MULTISAMPLE_BIT_ARB, + sizeof(struct gl_multisample_attrib), + (void*)&ctx->Multisample)) + goto end; } end: - ctx->AttribStack[ctx->AttribStackDepth] = head; - ctx->AttribStackDepth++; + if (head != NULL) { + ctx->AttribStack[ctx->AttribStackDepth] = head; + ctx->AttribStackDepth++; + } } @@ -641,12 +713,6 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, !!(enabled & TEXTURE_CUBE_BIT)); } - if (ctx->Extensions.MESA_texture_array) { - _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT, - !!(enabled & TEXTURE_1D_ARRAY_BIT)); - _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT, - !!(enabled & TEXTURE_2D_ARRAY_BIT)); - } } if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) { @@ -688,12 +754,6 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV, !!(unit->Enabled & TEXTURE_RECT_BIT)); } - if (ctx->Extensions.MESA_texture_array) { - _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT, - !!(unit->Enabled & TEXTURE_1D_ARRAY_BIT)); - _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT, - !!(unit->Enabled & TEXTURE_2D_ARRAY_BIT)); - } _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode); @@ -768,7 +828,7 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) } else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT || obj->Target == GL_TEXTURE_2D_ARRAY_EXT) && - !ctx->Extensions.MESA_texture_array) { + !ctx->Extensions.EXT_texture_array) { continue; } else if (obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY && @@ -1482,13 +1542,20 @@ restore_array_attrib(struct gl_context *ctx, * init/alloc the fields of 'attrib'. * Needs to the init part matching free_array_attrib_data below. */ -static void +static bool init_array_attrib_data(struct gl_context *ctx, struct gl_array_attrib *attrib) { /* Get a non driver gl_array_object. */ attrib->ArrayObj = CALLOC_STRUCT( gl_array_object ); + + if (attrib->ArrayObj == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + return false; + } + _mesa_initialize_array_object(ctx, attrib->ArrayObj, 0); + return true; } /** @@ -1529,24 +1596,65 @@ _mesa_PushClientAttrib(GLbitfield mask) struct gl_pixelstore_attrib *attr; /* packing attribs */ attr = CALLOC_STRUCT( gl_pixelstore_attrib ); - copy_pixelstore(ctx, attr, &ctx->Pack); - save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr); + if (attr == NULL) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); + goto end; + } + if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) { + copy_pixelstore(ctx, attr, &ctx->Pack); + } + else { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); + FREE(attr); + goto end; + } + /* unpacking attribs */ attr = CALLOC_STRUCT( gl_pixelstore_attrib ); - copy_pixelstore(ctx, attr, &ctx->Unpack); - save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr); + if (attr == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + goto end; + } + + if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) { + copy_pixelstore(ctx, attr, &ctx->Unpack); + } + else { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); + FREE(attr); + goto end; + } } if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { struct gl_array_attrib *attr; attr = CALLOC_STRUCT( gl_array_attrib ); - init_array_attrib_data(ctx, attr); - save_array_attrib(ctx, attr, &ctx->Array); - save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr); - } + if (attr == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + goto end; + } - ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; - ctx->ClientAttribStackDepth++; + if (!init_array_attrib_data(ctx, attr)) { + FREE(attr); + goto end; + } + + if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) { + save_array_attrib(ctx, attr, &ctx->Array); + } + else { + free_array_attrib_data(ctx, attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + FREE(attr); + /* goto to keep safe from possible later changes */ + goto end; + } + } +end: + if (head != NULL) { + ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; + ctx->ClientAttribStackDepth++; + } } diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 8b5ebc489..a3d8f24b1 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -41,6 +41,9 @@ #include "fbobject.h" #include "mtypes.h" #include "texobj.h" +#include "teximage.h" +#include "glformats.h" +#include "texstore.h" #include "transformfeedback.h" #include "dispatch.h" @@ -124,11 +127,13 @@ get_buffer_target(struct gl_context *ctx, GLenum target) * Get the buffer object bound to the specified target in a GL context. * \param ctx the GL context * \param target the buffer object target to be retrieved. + * \param error the GL error to record if target is illegal. * \return pointer to the buffer object bound to \c target in the * specified context or \c NULL if \c target is invalid. */ static inline struct gl_buffer_object * -get_buffer(struct gl_context *ctx, const char *func, GLenum target) +get_buffer(struct gl_context *ctx, const char *func, GLenum target, + GLenum error) { struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); @@ -138,7 +143,7 @@ get_buffer(struct gl_context *ctx, const char *func, GLenum target) } if (!_mesa_is_bufferobj(*bufObj)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer 0)", func); + _mesa_error(ctx, error, "%s(no buffer bound)", func); return NULL; } @@ -186,25 +191,58 @@ simplified_access_mode(struct gl_context *ctx, GLbitfield access) /** + * Test if the buffer is mapped, and if so, if the mapped range overlaps the + * given range. + * The regions do not overlap if and only if the end of the given + * region is before the mapped region or the start of the given region + * is after the mapped region. + * + * \param obj Buffer object target on which to operate. + * \param offset Offset of the first byte of the subdata range. + * \param size Size, in bytes, of the subdata range. + * \return true if ranges overlap, false otherwise + * + */ +static bool +bufferobj_range_mapped(const struct gl_buffer_object *obj, + GLintptr offset, GLsizeiptr size) +{ + if (_mesa_bufferobj_mapped(obj)) { + const GLintptr end = offset + size; + const GLintptr mapEnd = obj->Offset + obj->Length; + + if (!(end <= obj->Offset || offset >= mapEnd)) { + return true; + } + } + return false; +} + + +/** * Tests the subdata range parameters and sets the GL error code for - * \c glBufferSubDataARB and \c glGetBufferSubDataARB. + * \c glBufferSubDataARB, \c glGetBufferSubDataARB and + * \c glClearBufferSubData. * * \param ctx GL context. * \param target Buffer object target on which to operate. * \param offset Offset of the first byte of the subdata range. * \param size Size, in bytes, of the subdata range. + * \param mappedRange If true, checks if an overlapping range is mapped. + * If false, checks if buffer is mapped. + * \param errorNoBuffer Error code if no buffer is bound to target. * \param caller Name of calling function for recording errors. * \return A pointer to the buffer object bound to \c target in the * specified context or \c NULL if any of the parameter or state - * conditions for \c glBufferSubDataARB or \c glGetBufferSubDataARB - * are invalid. + * conditions are invalid. * - * \sa glBufferSubDataARB, glGetBufferSubDataARB + * \sa glBufferSubDataARB, glGetBufferSubDataARB, glClearBufferSubData */ static struct gl_buffer_object * -buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target, - GLintptrARB offset, GLsizeiptrARB size, - const char *caller ) +buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target, + GLintptrARB offset, GLsizeiptrARB size, + bool mappedRange, GLenum errorNoBuffer, + const char *caller) { struct gl_buffer_object *bufObj; @@ -218,22 +256,30 @@ buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target, return NULL; } - bufObj = get_buffer(ctx, caller, target); + bufObj = get_buffer(ctx, caller, target, errorNoBuffer); if (!bufObj) return NULL; if (offset + size > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s(offset %lu + size %lu > buffer size %lu)", caller, + "%s(offset %lu + size %lu > buffer size %lu)", caller, (unsigned long) offset, (unsigned long) size, (unsigned long) bufObj->Size); return NULL; } - if (_mesa_bufferobj_mapped(bufObj)) { - /* Buffer is currently mapped */ - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); - return NULL; + + if (mappedRange) { + if (bufferobj_range_mapped(bufObj, offset, size)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + return NULL; + } + } + else { + if (_mesa_bufferobj_mapped(bufObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); + return NULL; + } } return bufObj; @@ -241,6 +287,98 @@ buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target, /** + * Test the format and type parameters and set the GL error code for + * \c glClearBufferData and \c glClearBufferSubData. + * + * \param ctx GL context. + * \param internalformat Format to which the data is to be converted. + * \param format Format of the supplied data. + * \param type Type of the supplied data. + * \param caller Name of calling function for recording errors. + * \return If internalformat, format and type are legal the gl_format + * corresponding to internalformat, otherwise MESA_FORMAT_NONE. + * + * \sa glClearBufferData and glClearBufferSubData + */ +static gl_format +validate_clear_buffer_format(struct gl_context *ctx, + GLenum internalformat, + GLenum format, GLenum type, + const char *caller) +{ + gl_format mesaFormat; + GLenum errorFormatType; + + mesaFormat = _mesa_validate_texbuffer_format(ctx, internalformat); + if (mesaFormat == MESA_FORMAT_NONE) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(invalid internalformat)", caller); + return MESA_FORMAT_NONE; + } + + /* NOTE: not mentioned in ARB_clear_buffer_object but according to + * EXT_texture_integer there is no conversion between integer and + * non-integer formats + */ + if (_mesa_is_enum_format_signed_int(format) != + _mesa_is_format_integer_color(mesaFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer vs non-integer)", caller); + return MESA_FORMAT_NONE; + } + + if (!_mesa_is_color_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(format is not a color format)", caller); + return MESA_FORMAT_NONE; + } + + errorFormatType = _mesa_error_check_format_and_type(ctx, format, type); + if (errorFormatType != GL_NO_ERROR) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(invalid format or type)", caller); + return MESA_FORMAT_NONE; + } + + return mesaFormat; +} + + +/** + * Convert user-specified clear value to the specified internal format. + * + * \param ctx GL context. + * \param internalformat Format to which the data is converted. + * \param clearValue Points to the converted clear value. + * \param format Format of the supplied data. + * \param type Type of the supplied data. + * \param data Data which is to be converted to internalformat. + * \param caller Name of calling function for recording errors. + * \return true if data could be converted, false otherwise. + * + * \sa glClearBufferData, glClearBufferSubData + */ +static bool +convert_clear_buffer_data(struct gl_context *ctx, + gl_format internalformat, + GLubyte *clearValue, GLenum format, GLenum type, + const GLvoid *data, const char *caller) +{ + GLenum internalformatBase = _mesa_get_format_base_format(internalformat); + + if (_mesa_texstore(ctx, 1, internalformatBase, internalformat, + 0, &clearValue, 1, 1, 1, + format, type, data, &ctx->Unpack)) { + return true; + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); + return false; + } +} + + +/** * Allocate and initialize a new buffer object. * * Default callback for the \c dd_function_table::NewBufferObject() hook. @@ -505,6 +643,82 @@ _mesa_buffer_get_subdata( struct gl_context *ctx, GLintptrARB offset, /** + * Clear a subrange of the buffer object with copies of the supplied data. + * If data is NULL the buffer is filled with zeros. + * + * This is the default callback for \c dd_function_table::ClearBufferSubData() + * Note that all GL error checking will have been done already. + * + * \param ctx GL context. + * \param offset Offset of the first byte to be cleared. + * \param size Size, in bytes, of the to be cleared range. + * \param clearValue Source of the data. + * \param clearValueSize Size, in bytes, of the supplied data. + * \param bufObj Object to be cleared. + * + * \sa glClearBufferSubData, glClearBufferData and + * dd_function_table::ClearBufferSubData. + */ +static void +_mesa_buffer_clear_subdata(struct gl_context *ctx, + GLintptr offset, GLsizeiptr size, + const GLvoid *clearValue, + GLsizeiptr clearValueSize, + struct gl_buffer_object *bufObj) +{ + GLsizeiptr i; + GLubyte *dest; + + if (_mesa_bufferobj_mapped(bufObj)) { + GLubyte *data = malloc(size); + GLubyte *dataStart = data; + if (data == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data"); + return; + } + + if (clearValue == NULL) { + /* Clear with zeros, per the spec */ + memset(data, 0, size); + } + else { + for (i = 0; i < size/clearValueSize; ++i) { + memcpy(data, clearValue, clearValueSize); + data += clearValueSize; + } + } + ctx->Driver.BufferSubData(ctx, offset, size, dataStart, bufObj); + return; + } + + ASSERT(ctx->Driver.MapBufferRange); + dest = ctx->Driver.MapBufferRange(ctx, offset, size, + GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT, + bufObj); + + if (!dest) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data"); + return; + } + + if (clearValue == NULL) { + /* Clear with zeros, per the spec */ + memset(dest, 0, size); + ctx->Driver.UnmapBuffer(ctx, bufObj); + return; + } + + for (i = 0; i < size/clearValueSize; ++i) { + memcpy(dest, clearValue, clearValueSize); + dest += clearValueSize; + } + + ctx->Driver.UnmapBuffer(ctx, bufObj); +} + + +/** * Default fallback for \c dd_function_table::MapBufferRange(). * Called via glMapBufferRange(). */ @@ -810,6 +1024,9 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver) driver->GetBufferSubData = _mesa_buffer_get_subdata; driver->UnmapBuffer = _mesa_buffer_unmap; + /* GL_ARB_clear_buffer_object */ + driver->ClearBufferSubData = _mesa_buffer_clear_subdata; + /* GL_ARB_map_buffer_range */ driver->MapBufferRange = _mesa_buffer_map_range; driver->FlushMappedBufferRange = _mesa_buffer_flush_mapped_range; @@ -1064,7 +1281,7 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size, return; } - bufObj = get_buffer(ctx, "glBufferDataARB", target); + bufObj = get_buffer(ctx, "glBufferDataARB", target, GL_INVALID_OPERATION); if (!bufObj) return; @@ -1103,6 +1320,7 @@ _mesa_BufferSubData(GLenum target, GLintptrARB offset, struct gl_buffer_object *bufObj; bufObj = buffer_object_subdata_range_good( ctx, target, offset, size, + false, GL_INVALID_OPERATION, "glBufferSubDataARB" ); if (!bufObj) { /* error already recorded */ @@ -1126,8 +1344,9 @@ _mesa_GetBufferSubData(GLenum target, GLintptrARB offset, GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; - bufObj = buffer_object_subdata_range_good( ctx, target, offset, size, - "glGetBufferSubDataARB" ); + bufObj = buffer_object_subdata_range_good(ctx, target, offset, size, + false, GL_INVALID_OPERATION, + "glGetBufferSubDataARB"); if (!bufObj) { /* error already recorded */ return; @@ -1138,6 +1357,111 @@ _mesa_GetBufferSubData(GLenum target, GLintptrARB offset, } +void GLAPIENTRY +_mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format, + GLenum type, const GLvoid* data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object* bufObj; + gl_format mesaFormat; + GLubyte clearValue[MAX_PIXEL_BYTES]; + GLsizeiptr clearValueSize; + + bufObj = get_buffer(ctx, "glClearBufferData", target, GL_INVALID_VALUE); + if (!bufObj) { + return; + } + + if (_mesa_bufferobj_mapped(bufObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glClearBufferData(buffer currently mapped)"); + return; + } + + mesaFormat = validate_clear_buffer_format(ctx, internalformat, + format, type, + "glClearBufferData"); + if (mesaFormat == MESA_FORMAT_NONE) { + return; + } + + clearValueSize = _mesa_get_format_bytes(mesaFormat); + if (bufObj->Size % clearValueSize != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glClearBufferData(size is not a multiple of " + "internalformat size)"); + return; + } + + if (data == NULL) { + /* clear to zeros, per the spec */ + ctx->Driver.ClearBufferSubData(ctx, 0, bufObj->Size, + NULL, 0, bufObj); + return; + } + + if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue, + format, type, data, "glClearBufferData")) { + return; + } + + ctx->Driver.ClearBufferSubData(ctx, 0, bufObj->Size, + clearValue, clearValueSize, bufObj); +} + + +void GLAPIENTRY +_mesa_ClearBufferSubData(GLenum target, GLenum internalformat, + GLintptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const GLvoid* data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object* bufObj; + gl_format mesaFormat; + GLubyte clearValue[MAX_PIXEL_BYTES]; + GLsizeiptr clearValueSize; + + bufObj = buffer_object_subdata_range_good(ctx, target, offset, size, + true, GL_INVALID_VALUE, + "glClearBufferSubData"); + if (!bufObj) { + return; + } + + mesaFormat = validate_clear_buffer_format(ctx, internalformat, + format, type, + "glClearBufferSubData"); + if (mesaFormat == MESA_FORMAT_NONE) { + return; + } + + clearValueSize = _mesa_get_format_bytes(mesaFormat); + if (offset % clearValueSize != 0 || size % clearValueSize != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glClearBufferSubData(offset or size is not a multiple of " + "internalformat size)"); + return; + } + + if (data == NULL) { + /* clear to zeros, per the spec */ + ctx->Driver.ClearBufferSubData(ctx, offset, size, + NULL, 0, bufObj); + return; + } + + if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue, + format, type, data, + "glClearBufferSubData")) { + return; + } + + ctx->Driver.ClearBufferSubData(ctx, offset, size, + clearValue, clearValueSize, bufObj); +} + + void * GLAPIENTRY _mesa_MapBuffer(GLenum target, GLenum access) { @@ -1172,7 +1496,7 @@ _mesa_MapBuffer(GLenum target, GLenum access) return NULL; } - bufObj = get_buffer(ctx, "glMapBufferARB", target); + bufObj = get_buffer(ctx, "glMapBufferARB", target, GL_INVALID_OPERATION); if (!bufObj) return NULL; @@ -1241,7 +1565,7 @@ _mesa_UnmapBuffer(GLenum target) GLboolean status = GL_TRUE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - bufObj = get_buffer(ctx, "glUnmapBufferARB", target); + bufObj = get_buffer(ctx, "glUnmapBufferARB", target, GL_INVALID_OPERATION); if (!bufObj) return GL_FALSE; @@ -1302,7 +1626,8 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params) GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; - bufObj = get_buffer(ctx, "glGetBufferParameterivARB", target); + bufObj = get_buffer(ctx, "glGetBufferParameterivARB", target, + GL_INVALID_OPERATION); if (!bufObj) return; @@ -1355,7 +1680,8 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; - bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target); + bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target, + GL_INVALID_OPERATION); if (!bufObj) return; @@ -1408,7 +1734,8 @@ _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params) return; } - bufObj = get_buffer(ctx, "glGetBufferPointervARB", target); + bufObj = get_buffer(ctx, "glGetBufferPointervARB", target, + GL_INVALID_OPERATION); if (!bufObj) return; @@ -1424,11 +1751,13 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *src, *dst; - src = get_buffer(ctx, "glCopyBufferSubData", readTarget); + src = get_buffer(ctx, "glCopyBufferSubData", readTarget, + GL_INVALID_OPERATION); if (!src) return; - dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget); + dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget, + GL_INVALID_OPERATION); if (!dst) return; @@ -1572,7 +1901,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, return NULL; } - bufObj = get_buffer(ctx, "glMapBufferRange", target); + bufObj = get_buffer(ctx, "glMapBufferRange", target, GL_INVALID_OPERATION); if (!bufObj) return NULL; @@ -1651,7 +1980,8 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) return; } - bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target); + bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target, + GL_INVALID_OPERATION); if (!bufObj) return; @@ -2331,23 +2661,11 @@ _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset, * mapped by MapBuffer, or if the invalidate range intersects the range * currently mapped by MapBufferRange." */ - if (_mesa_bufferobj_mapped(bufObj)) { - const GLintptr mapEnd = bufObj->Offset + bufObj->Length; - - /* The regions do not overlap if and only if the end of the discard - * region is before the mapped region or the start of the discard region - * is after the mapped region. - * - * Note that 'end' and 'mapEnd' are the first byte *after* the discard - * region and the mapped region, repsectively. It is okay for that byte - * to be mapped (for 'end') or discarded (for 'mapEnd'). - */ - if (!(end <= bufObj->Offset || offset >= mapEnd)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glInvalidateBufferSubData(intersection with mapped " - "range)"); - return; - } + if (bufferobj_range_mapped(bufObj, offset, length)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glInvalidateBufferSubData(intersection with mapped " + "range)"); + return; } /* We don't actually do anything for this yet. Just return after diff --git a/mesalib/src/mesa/main/bufferobj.h b/mesalib/src/mesa/main/bufferobj.h index 0b898a21b..71988b0d9 100644 --- a/mesalib/src/mesa/main/bufferobj.h +++ b/mesalib/src/mesa/main/bufferobj.h @@ -57,10 +57,10 @@ _mesa_is_bufferobj(const struct gl_buffer_object *obj) extern void -_mesa_init_buffer_objects( struct gl_context *ctx ); +_mesa_init_buffer_objects(struct gl_context *ctx); extern void -_mesa_free_buffer_objects( struct gl_context *ctx ); +_mesa_free_buffer_objects(struct gl_context *ctx); extern bool _mesa_handle_bind_buffer_gen(struct gl_context *ctx, @@ -77,9 +77,9 @@ extern struct gl_buffer_object * _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer); extern void -_mesa_initialize_buffer_object( struct gl_context *ctx, - struct gl_buffer_object *obj, - GLuint name, GLenum target ); +_mesa_initialize_buffer_object(struct gl_context *ctx, + struct gl_buffer_object *obj, + GLuint name, GLenum target); extern void _mesa_reference_buffer_object_(struct gl_context *ctx, @@ -105,55 +105,90 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver); /* * API functions */ - void GLAPIENTRY _mesa_BindBuffer(GLenum target, GLuint buffer); + void GLAPIENTRY _mesa_DeleteBuffers(GLsizei n, const GLuint * buffer); + void GLAPIENTRY _mesa_GenBuffers(GLsizei n, GLuint * buffer); + GLboolean GLAPIENTRY _mesa_IsBuffer(GLuint buffer); + void GLAPIENTRY -_mesa_BufferData(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage); +_mesa_BufferData(GLenum target, GLsizeiptrARB size, + const GLvoid * data, GLenum usage); + void GLAPIENTRY -_mesa_BufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data); +_mesa_BufferSubData(GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid * data); + void GLAPIENTRY -_mesa_GetBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data); +_mesa_GetBufferSubData(GLenum target, GLintptrARB offset, + GLsizeiptrARB size, void * data); + +void GLAPIENTRY +_mesa_ClearBufferData(GLenum target, GLenum internalformat, + GLenum format, GLenum type, + const GLvoid * data); + +void GLAPIENTRY +_mesa_ClearBufferSubData(GLenum target, GLenum internalformat, + GLintptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const GLvoid * data); + void * GLAPIENTRY _mesa_MapBuffer(GLenum target, GLenum access); + GLboolean GLAPIENTRY _mesa_UnmapBuffer(GLenum target); + void GLAPIENTRY _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params); + void GLAPIENTRY _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params); + void GLAPIENTRY _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params); + void GLAPIENTRY _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void * GLAPIENTRY _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void GLAPIENTRY -_mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); +_mesa_FlushMappedBufferRange(GLenum target, + GLintptr offset, GLsizeiptr length); + GLenum GLAPIENTRY _mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option); + GLenum GLAPIENTRY _mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option); + void GLAPIENTRY -_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, - GLint* params); +_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, + GLenum pname, GLint* params); + void GLAPIENTRY _mesa_BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void GLAPIENTRY _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer); + void GLAPIENTRY _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length); + void GLAPIENTRY _mesa_InvalidateBufferData(GLuint buffer); diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index 304d135d1..f0b525fa0 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -219,7 +219,25 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; GLbitfield mask = 0x0; - switch (drawbuffer) { + /* From the GL 4.0 specification: + * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is + * specified by passing i as the parameter drawbuffer, and value + * points to a four-element vector specifying the R, G, B, and A + * color to clear that draw buffer to. If the draw buffer is one + * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying + * multiple buffers, each selected buffer is cleared to the same + * value. + * + * Note that "drawbuffer" and "draw buffer" have different meaning. + * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's + * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK, + * etc. + */ + if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { + return INVALID_MASK; + } + + switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) { case GL_FRONT: if (att[BUFFER_FRONT_LEFT].Renderbuffer) mask |= BUFFER_BIT_FRONT_LEFT; @@ -255,11 +273,12 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) mask |= BUFFER_BIT_BACK_RIGHT; break; default: - if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { - mask = INVALID_MASK; - } - else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) { - mask |= (BUFFER_BIT_COLOR0 << drawbuffer); + { + GLuint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer]; + + if (buf >= 0 && att[buf].Renderbuffer) { + mask |= 1 << buf; + } } } diff --git a/mesalib/src/mesa/main/colortab.c b/mesalib/src/mesa/main/colortab.c index 81e92d71c..a8edb03dd 100644 --- a/mesalib/src/mesa/main/colortab.c +++ b/mesalib/src/mesa/main/colortab.c @@ -44,7 +44,7 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, const GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable"); } @@ -55,7 +55,7 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, const GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable"); } @@ -65,7 +65,7 @@ _mesa_CopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorTable(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorTable"); } @@ -75,7 +75,7 @@ _mesa_CopyColorSubTable(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorSubTable(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorSubTable"); } @@ -85,7 +85,7 @@ _mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetnColorTableARB(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetnColorTableARB"); } @@ -94,7 +94,7 @@ _mesa_GetColorTable( GLenum target, GLenum format, GLenum type, GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTable"); } @@ -103,7 +103,7 @@ _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) { /* no extensions use this function */ GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameterfv"); } @@ -113,7 +113,7 @@ _mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) { /* no extensions use this function */ GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameteriv(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameteriv"); } @@ -122,7 +122,7 @@ void GLAPIENTRY _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameterfv"); } @@ -131,5 +131,5 @@ void GLAPIENTRY _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameteriv"); } diff --git a/mesalib/src/mesa/main/condrender.c b/mesalib/src/mesa/main/condrender.c index 3d9b0eca1..2632f7a1a 100644 --- a/mesalib/src/mesa/main/condrender.c +++ b/mesalib/src/mesa/main/condrender.c @@ -72,7 +72,9 @@ _mesa_BeginConditionalRender(GLuint queryId, GLenum mode) } ASSERT(q->Id == queryId); - if (q->Target != GL_SAMPLES_PASSED || q->Active) { + if ((q->Target != GL_SAMPLES_PASSED && + q->Target != GL_ANY_SAMPLES_PASSED && + q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE) || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()"); return; } diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 87a4a3545..658499fa4 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1194,6 +1194,7 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_sync_data(ctx); _mesa_free_varray_data(ctx); _mesa_free_transform_feedback(ctx); + _mesa_free_performance_monitors(ctx); _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); diff --git a/mesalib/src/mesa/main/convolve.c b/mesalib/src/mesa/main/convolve.c index f44031a9b..b13b89535 100644 --- a/mesalib/src/mesa/main/convolve.c +++ b/mesalib/src/mesa/main/convolve.c @@ -45,7 +45,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D"); } void GLAPIENTRY @@ -53,7 +53,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D"); } @@ -62,7 +62,7 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterf"); } @@ -71,7 +71,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterfv"); } @@ -80,7 +80,7 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteri"); } @@ -89,7 +89,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteriv"); } @@ -98,7 +98,7 @@ _mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLi { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter1D"); } @@ -107,7 +107,7 @@ _mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLi { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter2D"); } @@ -134,7 +134,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameterfv"); } @@ -143,7 +143,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameteriv"); } @@ -155,7 +155,7 @@ _mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type, { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSeparableFilter"); } @@ -173,5 +173,5 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs { GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D"); } diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index b5b874f47..6e73691ea 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -375,6 +375,11 @@ struct dd_function_table { GLsizei levels, GLsizei width, GLsizei height, GLsizei depth); + /** Called as part of glTextureView to add views to origTexObj */ + GLboolean (*TextureView)(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_object *origTexObj); + /** * Map a renderbuffer into user space. * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and @@ -569,6 +574,12 @@ struct dd_function_table { GLintptrARB offset, GLsizeiptrARB size, GLvoid *data, struct gl_buffer_object *obj ); + void (*ClearBufferSubData)( struct gl_context *ctx, + GLintptr offset, GLsizeiptr size, + const GLvoid *clearValue, + GLsizeiptr clearValueSize, + struct gl_buffer_object *obj ); + void (*CopyBufferSubData)( struct gl_context *ctx, struct gl_buffer_object *src, struct gl_buffer_object *dst, diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 595641915..cb40ff4db 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -209,18 +209,6 @@ typedef enum OPCODE_COLOR_MASK, OPCODE_COLOR_MASK_INDEXED, OPCODE_COLOR_MATERIAL, - OPCODE_COLOR_TABLE, - OPCODE_COLOR_TABLE_PARAMETER_FV, - OPCODE_COLOR_TABLE_PARAMETER_IV, - OPCODE_COLOR_SUB_TABLE, - OPCODE_CONVOLUTION_FILTER_1D, - OPCODE_CONVOLUTION_FILTER_2D, - OPCODE_CONVOLUTION_PARAMETER_I, - OPCODE_CONVOLUTION_PARAMETER_IV, - OPCODE_CONVOLUTION_PARAMETER_F, - OPCODE_CONVOLUTION_PARAMETER_FV, - OPCODE_COPY_COLOR_SUB_TABLE, - OPCODE_COPY_COLOR_TABLE, OPCODE_COPY_PIXELS, OPCODE_COPY_TEX_IMAGE1D, OPCODE_COPY_TEX_IMAGE2D, @@ -243,7 +231,6 @@ typedef enum OPCODE_FRONT_FACE, OPCODE_FRUSTUM, OPCODE_HINT, - OPCODE_HISTOGRAM, OPCODE_INDEX_MASK, OPCODE_INIT_NAMES, OPCODE_LIGHT, @@ -260,7 +247,6 @@ typedef enum OPCODE_MAPGRID1, OPCODE_MAPGRID2, OPCODE_MATRIX_MODE, - OPCODE_MIN_MAX, OPCODE_MULT_MATRIX, OPCODE_ORTHO, OPCODE_PASSTHROUGH, @@ -281,8 +267,6 @@ typedef enum OPCODE_PUSH_NAME, OPCODE_RASTER_POS, OPCODE_READ_BUFFER, - OPCODE_RESET_HISTOGRAM, - OPCODE_RESET_MIN_MAX, OPCODE_ROTATE, OPCODE_SCALE, OPCODE_SCISSOR, @@ -486,6 +470,10 @@ typedef enum * Each instruction in the display list is stored as a sequence of * contiguous nodes in memory. * Each node is the union of a variety of data types. + * + * Note, all of these members should be 4 bytes in size or less for the + * sake of compact display lists. We store 8-byte pointers in a pair of + * these nodes using the save/get_pointer() functions below. */ union gl_dlist_node { @@ -500,14 +488,61 @@ union gl_dlist_node GLenum e; GLfloat f; GLsizei si; - GLvoid *data; - void *next; /* If prev node's opcode==OPCODE_CONTINUE */ }; typedef union gl_dlist_node Node; +/** How many 4-byte dwords to store a pointer */ +#define POINTER_DWORDS (sizeof(void *) / 4) + +/* We want to keep sizeof(union gl_dlist_node) == 4 to minimize + * space for display lists. The following types and functions are + * used to help store 4- and 8-byte pointers in 1 or 2 dlist_nodes. + */ +union pointer +{ + void *ptr; + GLuint dwords[POINTER_DWORDS]; +}; + + +/** + * Save a 4 or 8-byte pointer at dest (and dest+1). + */ +static inline void +save_pointer(union gl_dlist_node *dest, void *src) +{ + union pointer p; + unsigned i; + + STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2); + STATIC_ASSERT(sizeof(union gl_dlist_node) == 4); + + p.ptr = src; + + for (i = 0; i < POINTER_DWORDS; i++) + dest[i].ui = p.dwords[i]; +} + + +/** + * Retrieve a 4 or 8-byte pointer from node (node+1). + */ +static inline void * +get_pointer(const union gl_dlist_node *node) +{ + union pointer p; + unsigned i; + + for (i = 0; i < POINTER_DWORDS; i++) + p.dwords[i] = node[i].ui; + + return p.ptr; +} + + /** * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit * environment. In 64-bit env, sizeof(Node)==8 anyway. @@ -520,9 +555,9 @@ union uint64_pair /** - * How many nodes to allocate at a time. - * - * \note Reduced now that we hold vertices etc. elsewhere. + * How many nodes to allocate at a time. Note that bulk vertex data + * from glBegin/glVertex/glEnd primitives will typically wind up in + * a VBO, and not directly in the display list itself. */ #define BLOCK_SIZE 256 @@ -538,14 +573,9 @@ static GLuint InstSize[OPCODE_END_OF_LIST + 1]; void mesa_print_display_list(GLuint list); -/**********************************************************************/ -/***** Private *****/ -/**********************************************************************/ - - /** - * Make an empty display list. This is used by glGenLists() to - * reserve display list IDs. + * Allocate a gl_display_list object with an initial block of storage. + * \param count how many display list nodes/tokes to allocate */ static struct gl_display_list * make_list(GLuint name, GLuint count) @@ -637,91 +667,75 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) switch (opcode) { /* for some commands, we need to free malloc'd memory */ case OPCODE_MAP1: - free(n[6].data); + free(get_pointer(&n[6])); n += InstSize[n[0].opcode]; break; case OPCODE_MAP2: - free(n[10].data); + free(get_pointer(&n[10])); n += InstSize[n[0].opcode]; break; case OPCODE_DRAW_PIXELS: - free(n[5].data); + free(get_pointer(&n[5])); n += InstSize[n[0].opcode]; break; case OPCODE_BITMAP: - free(n[7].data); - n += InstSize[n[0].opcode]; - break; - case OPCODE_COLOR_TABLE: - free(n[6].data); - n += InstSize[n[0].opcode]; - break; - case OPCODE_COLOR_SUB_TABLE: - free(n[6].data); - n += InstSize[n[0].opcode]; - break; - case OPCODE_CONVOLUTION_FILTER_1D: - free(n[6].data); - n += InstSize[n[0].opcode]; - break; - case OPCODE_CONVOLUTION_FILTER_2D: - free(n[7].data); + free(get_pointer(&n[7])); n += InstSize[n[0].opcode]; break; case OPCODE_POLYGON_STIPPLE: - free(n[1].data); + free(get_pointer(&n[1])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE1D: - free(n[8].data); + free(get_pointer(&n[8])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE2D: - free(n[9].data); + free(get_pointer(&n[9])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE3D: - free(n[10].data); + free(get_pointer(&n[10])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE1D: - free(n[7].data); + free(get_pointer(&n[7])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE2D: - free(n[9].data); + free(get_pointer(&n[9])); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE3D: - free(n[11].data); + free(get_pointer(&n[11])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_1D: - free(n[7].data); + free(get_pointer(&n[7])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_2D: - free(n[8].data); + free(get_pointer(&n[8])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_3D: - free(n[9].data); + free(get_pointer(&n[9])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: - free(n[7].data); + free(get_pointer(&n[7])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: - free(n[9].data); + free(get_pointer(&n[9])); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: - free(n[11].data); + free(get_pointer(&n[11])); n += InstSize[n[0].opcode]; break; case OPCODE_PROGRAM_STRING_ARB: - free(n[4].data); /* program string */ + free(get_pointer(&n[4])); /* program string */ n += InstSize[n[0].opcode]; break; case OPCODE_UNIFORM_1FV: @@ -736,7 +750,7 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) case OPCODE_UNIFORM_2UIV: case OPCODE_UNIFORM_3UIV: case OPCODE_UNIFORM_4UIV: - free(n[3].data); + free(get_pointer(&n[3])); n += InstSize[n[0].opcode]; break; case OPCODE_UNIFORM_MATRIX22: @@ -748,12 +762,15 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) case OPCODE_UNIFORM_MATRIX32: case OPCODE_UNIFORM_MATRIX34: case OPCODE_UNIFORM_MATRIX43: - free(n[4].data); + free(get_pointer(&n[4])); n += InstSize[n[0].opcode]; break; + case OPCODE_PIXEL_MAP: + free(get_pointer(&n[3])); + break; case OPCODE_CONTINUE: - n = (Node *) n[1].next; + n = (Node *) get_pointer(&n[1]); free(block); block = n; break; @@ -852,12 +869,6 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list) } - - -/**********************************************************************/ -/***** Public *****/ -/**********************************************************************/ - /** * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects. * If width < 0 or height < 0 or format or type are invalid we'll just @@ -929,6 +940,18 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, return NULL; } + +/** Return copy of memory */ +static void * +memdup(const void *src, GLsizei bytes) +{ + void *b = bytes >= 0 ? malloc(bytes) : NULL; + if (b) + memcpy(b, src, bytes); + return b; +} + + /** * Allocate space for a display list instruction (opcode + payload space). * \param opcode the instruction opcode (OPCODE_* value) @@ -939,6 +962,7 @@ static Node * dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) { const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); + const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ Node *n; if (opcode < (GLuint) OPCODE_EXT_0) { @@ -952,7 +976,7 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) } } - if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) { + if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; @@ -962,7 +986,7 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; } - n[1].next = (Node *) newblock; + save_pointer(&n[1], newblock); ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; } @@ -1043,6 +1067,37 @@ alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) } +/** + * Called by EndList to try to reduce memory used for the list. + */ +static void +trim_list(struct gl_context *ctx) +{ + /* If the list we're ending only has one allocated block of nodes/tokens + * and its size isn't a full block size, realloc the block to use less + * memory. This is important for apps that create many small display + * lists and apps that use glXUseXFont (many lists each containing one + * glBitmap call). + * Note: we currently only trim display lists that allocated one block + * of tokens. That hits the short list case which is what we're mainly + * concerned with. Trimming longer lists would involve traversing the + * linked list of blocks. + */ + struct gl_dlist_state *list = &ctx->ListState; + + if ((list->CurrentList->Head == list->CurrentBlock) && + (list->CurrentPos < BLOCK_SIZE)) { + /* There's only one block and it's not full, so realloc */ + GLuint newSize = list->CurrentPos * sizeof(Node); + list->CurrentList->Head = + list->CurrentBlock = realloc(list->CurrentBlock, newSize); + if (!list->CurrentBlock) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList"); + } + } +} + + /* * Display List compilation functions @@ -1106,7 +1161,7 @@ save_Bitmap(GLsizei width, GLsizei height, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_BITMAP, 7); + n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS); if (n) { n[1].i = (GLint) width; n[2].i = (GLint) height; @@ -1114,8 +1169,9 @@ save_Bitmap(GLsizei width, GLsizei height, n[4].f = yorig; n[5].f = xmove; n[6].f = ymove; - n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX, - GL_BITMAP, pixels, &ctx->Unpack); + save_pointer(&n[7], + unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX, + GL_BITMAP, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_Bitmap(ctx->Exec, (width, height, @@ -1735,313 +1791,6 @@ save_ColorMaterial(GLenum face, GLenum mode) static void GLAPIENTRY -save_ColorTable(GLenum target, GLenum internalFormat, - GLsizei width, GLenum format, GLenum type, - const GLvoid * table) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_is_proxy_texture(target)) { - /* execute immediately */ - CALL_ColorTable(ctx->Exec, (target, internalFormat, width, - format, type, table)); - } - else { - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COLOR_TABLE, 6); - if (n) { - n[1].e = target; - n[2].e = internalFormat; - n[3].i = width; - n[4].e = format; - n[5].e = type; - n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table, - &ctx->Unpack); - } - if (ctx->ExecuteFlag) { - CALL_ColorTable(ctx->Exec, (target, internalFormat, width, - format, type, table)); - } - } -} - - - -static void GLAPIENTRY -save_ColorTableParameterfv(GLenum target, GLenum pname, - const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - - n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].f = params[0]; - if (pname == GL_COLOR_TABLE_SGI || - pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || - pname == GL_TEXTURE_COLOR_TABLE_SGI) { - n[4].f = params[1]; - n[5].f = params[2]; - n[6].f = params[3]; - } - } - - if (ctx->ExecuteFlag) { - CALL_ColorTableParameterfv(ctx->Exec, (target, pname, params)); - } -} - - -static void GLAPIENTRY -save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - - n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].i = params[0]; - if (pname == GL_COLOR_TABLE_SGI || - pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || - pname == GL_TEXTURE_COLOR_TABLE_SGI) { - n[4].i = params[1]; - n[5].i = params[2]; - n[6].i = params[3]; - } - } - - if (ctx->ExecuteFlag) { - CALL_ColorTableParameteriv(ctx->Exec, (target, pname, params)); - } -} - - - -static void GLAPIENTRY -save_ColorSubTable(GLenum target, GLsizei start, GLsizei count, - GLenum format, GLenum type, const GLvoid * table) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COLOR_SUB_TABLE, 6); - if (n) { - n[1].e = target; - n[2].i = start; - n[3].i = count; - n[4].e = format; - n[5].e = type; - n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table, - &ctx->Unpack); - } - if (ctx->ExecuteFlag) { - CALL_ColorSubTable(ctx->Exec, - (target, start, count, format, type, table)); - } -} - - -static void GLAPIENTRY -save_CopyColorSubTable(GLenum target, GLsizei start, - GLint x, GLint y, GLsizei width) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5); - if (n) { - n[1].e = target; - n[2].i = start; - n[3].i = x; - n[4].i = y; - n[5].i = width; - } - if (ctx->ExecuteFlag) { - CALL_CopyColorSubTable(ctx->Exec, (target, start, x, y, width)); - } -} - - -static void GLAPIENTRY -save_CopyColorTable(GLenum target, GLenum internalformat, - GLint x, GLint y, GLsizei width) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COPY_COLOR_TABLE, 5); - if (n) { - n[1].e = target; - n[2].e = internalformat; - n[3].i = x; - n[4].i = y; - n[5].i = width; - } - if (ctx->ExecuteFlag) { - CALL_CopyColorTable(ctx->Exec, (target, internalformat, x, y, width)); - } -} - - -static void GLAPIENTRY -save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, - GLenum format, GLenum type, const GLvoid * filter) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6); - if (n) { - n[1].e = target; - n[2].e = internalFormat; - n[3].i = width; - n[4].e = format; - n[5].e = type; - n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter, - &ctx->Unpack); - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width, - format, type, filter)); - } -} - - -static void GLAPIENTRY -save_ConvolutionFilter2D(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height, GLenum format, - GLenum type, const GLvoid * filter) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7); - if (n) { - n[1].e = target; - n[2].e = internalFormat; - n[3].i = width; - n[4].i = height; - n[5].e = format; - n[6].e = type; - n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter, - &ctx->Unpack); - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionFilter2D(ctx->Exec, - (target, internalFormat, width, height, format, - type, filter)); - } -} - - -static void GLAPIENTRY -save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].i = param; - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionParameteri(ctx->Exec, (target, pname, param)); - } -} - - -static void GLAPIENTRY -save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].i = params[0]; - if (pname == GL_CONVOLUTION_BORDER_COLOR || - pname == GL_CONVOLUTION_FILTER_SCALE || - pname == GL_CONVOLUTION_FILTER_BIAS) { - n[4].i = params[1]; - n[5].i = params[2]; - n[6].i = params[3]; - } - else { - n[4].i = n[5].i = n[6].i = 0; - } - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionParameteriv(ctx->Exec, (target, pname, params)); - } -} - - -static void GLAPIENTRY -save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].f = param; - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionParameterf(ctx->Exec, (target, pname, param)); - } -} - - -static void GLAPIENTRY -save_ConvolutionParameterfv(GLenum target, GLenum pname, - const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6); - if (n) { - n[1].e = target; - n[2].e = pname; - n[3].f = params[0]; - if (pname == GL_CONVOLUTION_BORDER_COLOR || - pname == GL_CONVOLUTION_FILTER_SCALE || - pname == GL_CONVOLUTION_FILTER_BIAS) { - n[4].f = params[1]; - n[5].f = params[2]; - n[6].f = params[3]; - } - else { - n[4].f = n[5].f = n[6].f = 0.0F; - } - } - if (ctx->ExecuteFlag) { - CALL_ConvolutionParameterfv(ctx->Exec, (target, pname, params)); - } -} - - -static void GLAPIENTRY save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { GET_CURRENT_CONTEXT(ctx); @@ -2314,14 +2063,15 @@ save_DrawPixels(GLsizei width, GLsizei height, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 5); + n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 4 + POINTER_DWORDS); if (n) { n[1].i = width; n[2].i = height; n[3].e = format; n[4].e = type; - n[5].data = unpack_image(ctx, 2, width, height, 1, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[5], + unpack_image(ctx, 2, width, height, 1, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels)); @@ -2530,27 +2280,6 @@ save_Hint(GLenum target, GLenum mode) static void GLAPIENTRY -save_Histogram(GLenum target, GLsizei width, GLenum internalFormat, - GLboolean sink) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_HISTOGRAM, 4); - if (n) { - n[1].e = target; - n[2].i = width; - n[3].e = internalFormat; - n[4].b = sink; - } - if (ctx->ExecuteFlag) { - CALL_Histogram(ctx->Exec, (target, width, internalFormat, sink)); - } -} - - -static void GLAPIENTRY save_IndexMask(GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -2890,7 +2619,7 @@ save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_MAP1, 6); + n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS); if (n) { GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points); n[1].e = target; @@ -2898,7 +2627,7 @@ save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, n[3].f = (GLfloat) u2; n[4].i = _mesa_evaluator_components(target); /* stride */ n[5].i = order; - n[6].data = (void *) pnts; + save_pointer(&n[6], pnts); } if (ctx->ExecuteFlag) { CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points)); @@ -2912,7 +2641,7 @@ save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_MAP1, 6); + n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS); if (n) { GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points); n[1].e = target; @@ -2920,7 +2649,7 @@ save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, n[3].f = u2; n[4].i = _mesa_evaluator_components(target); /* stride */ n[5].i = order; - n[6].data = (void *) pnts; + save_pointer(&n[6], pnts); } if (ctx->ExecuteFlag) { CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points)); @@ -2937,7 +2666,7 @@ save_Map2d(GLenum target, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_MAP2, 10); + n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS); if (n) { GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder, vstride, vorder, points); @@ -2951,7 +2680,7 @@ save_Map2d(GLenum target, n[7].i = _mesa_evaluator_components(target); /*vstride */ n[8].i = uorder; n[9].i = vorder; - n[10].data = (void *) pnts; + save_pointer(&n[10], pnts); } if (ctx->ExecuteFlag) { CALL_Map2d(ctx->Exec, (target, @@ -2970,7 +2699,7 @@ save_Map2f(GLenum target, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_MAP2, 10); + n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS); if (n) { GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder, vstride, vorder, points); @@ -2984,7 +2713,7 @@ save_Map2f(GLenum target, n[7].i = _mesa_evaluator_components(target); /*vstride */ n[8].i = uorder; n[9].i = vorder; - n[10].data = (void *) pnts; + save_pointer(&n[10], pnts); } if (ctx->ExecuteFlag) { CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder, @@ -3067,25 +2796,6 @@ save_MatrixMode(GLenum mode) static void GLAPIENTRY -save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_MIN_MAX, 3); - if (n) { - n[1].e = target; - n[2].e = internalFormat; - n[3].b = sink; - } - if (ctx->ExecuteFlag) { - CALL_Minmax(ctx->Exec, (target, internalFormat, sink)); - } -} - - -static void GLAPIENTRY save_MultMatrixf(const GLfloat * m) { GET_CURRENT_CONTEXT(ctx); @@ -3156,12 +2866,11 @@ save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 3); + n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 2 + POINTER_DWORDS); if (n) { n[1].e = map; n[2].i = mapsize; - n[3].data = malloc(mapsize * sizeof(GLfloat)); - memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat)); + save_pointer(&n[3], memdup(values, mapsize * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_PixelMapfv(ctx->Exec, (map, mapsize, values)); @@ -3336,10 +3045,11 @@ save_PolygonStipple(const GLubyte * pattern) ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, 1); + n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, POINTER_DWORDS); if (n) { - n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, - pattern, &ctx->Unpack); + save_pointer(&n[1], + unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, + pattern, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern)); @@ -3667,38 +3377,6 @@ save_ReadBuffer(GLenum mode) static void GLAPIENTRY -save_ResetHistogram(GLenum target) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_RESET_HISTOGRAM, 1); - if (n) { - n[1].e = target; - } - if (ctx->ExecuteFlag) { - CALL_ResetHistogram(ctx->Exec, (target)); - } -} - - -static void GLAPIENTRY -save_ResetMinmax(GLenum target) -{ - GET_CURRENT_CONTEXT(ctx); - Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_RESET_MIN_MAX, 1); - if (n) { - n[1].e = target; - } - if (ctx->ExecuteFlag) { - CALL_ResetMinmax(ctx->Exec, (target)); - } -} - - -static void GLAPIENTRY save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -4140,7 +3818,7 @@ save_TexImage1D(GLenum target, else { Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 8); + n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 7 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4149,8 +3827,9 @@ save_TexImage1D(GLenum target, n[5].i = border; n[6].e = format; n[7].e = type; - n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[8], + unpack_image(ctx, 1, width, 1, 1, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexImage1D(ctx->Exec, (target, level, components, width, @@ -4175,7 +3854,7 @@ save_TexImage2D(GLenum target, else { Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 9); + n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 8 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4185,8 +3864,9 @@ save_TexImage2D(GLenum target, n[6].i = border; n[7].e = format; n[8].e = type; - n[9].data = unpack_image(ctx, 2, width, height, 1, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[9], + unpack_image(ctx, 2, width, height, 1, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexImage2D(ctx->Exec, (target, level, components, width, @@ -4213,7 +3893,7 @@ save_TexImage3D(GLenum target, else { Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 10); + n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 9 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4224,8 +3904,9 @@ save_TexImage3D(GLenum target, n[7].i = border; n[8].e = format; n[9].e = type; - n[10].data = unpack_image(ctx, 3, width, height, depth, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[10], + unpack_image(ctx, 3, width, height, depth, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width, @@ -4246,7 +3927,7 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 7); + n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 6 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4254,8 +3935,9 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset, n[4].i = (GLint) width; n[5].e = format; n[6].e = type; - n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[7], + unpack_image(ctx, 1, width, 1, 1, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width, @@ -4275,7 +3957,7 @@ save_TexSubImage2D(GLenum target, GLint level, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 9); + n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 8 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4285,8 +3967,9 @@ save_TexSubImage2D(GLenum target, GLint level, n[6].i = (GLint) height; n[7].e = format; n[8].e = type; - n[9].data = unpack_image(ctx, 2, width, height, 1, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[9], + unpack_image(ctx, 2, width, height, 1, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset, @@ -4306,7 +3989,7 @@ save_TexSubImage3D(GLenum target, GLint level, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 11); + n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 10 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4318,8 +4001,9 @@ save_TexSubImage3D(GLenum target, GLint level, n[8].i = (GLint) depth; n[9].e = format; n[10].e = type; - n[11].data = unpack_image(ctx, 3, width, height, depth, format, type, - pixels, &ctx->Unpack); + save_pointer(&n[11], + unpack_image(ctx, 3, width, height, depth, format, type, + pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { CALL_TexSubImage3D(ctx->Exec, (target, level, @@ -4626,7 +4310,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, + 6 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4634,7 +4319,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, n[4].i = (GLint) width; n[5].i = border; n[6].i = imageSize; - n[7].data = copy_data(data, imageSize, "glCompressedTexImage1DARB"); + save_pointer(&n[7], + copy_data(data, imageSize, "glCompressedTexImage1DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexImage1D(ctx->Exec, @@ -4662,7 +4348,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, + 7 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4671,7 +4358,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, n[5].i = (GLint) height; n[6].i = border; n[7].i = imageSize; - n[8].data = copy_data(data, imageSize, "glCompressedTexImage2DARB"); + save_pointer(&n[8], + copy_data(data, imageSize, "glCompressedTexImage2DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexImage2D(ctx->Exec, @@ -4699,7 +4387,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, + 8 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4709,7 +4398,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, n[6].i = (GLint) depth; n[7].i = border; n[8].i = imageSize; - n[9].data = copy_data(data, imageSize, "glCompressedTexImage3DARB"); + save_pointer(&n[9], + copy_data(data, imageSize, "glCompressedTexImage3DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexImage3D(ctx->Exec, @@ -4730,7 +4420,8 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, + 6 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4738,7 +4429,8 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, n[4].i = (GLint) width; n[5].e = format; n[6].i = imageSize; - n[7].data = copy_data(data, imageSize, "glCompressedTexSubImage1DARB"); + save_pointer(&n[7], + copy_data(data, imageSize, "glCompressedTexSubImage1DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexSubImage1D(ctx->Exec, (target, level, xoffset, @@ -4758,7 +4450,8 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, + 8 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4768,7 +4461,8 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, n[6].i = (GLint) height; n[7].e = format; n[8].i = imageSize; - n[9].data = copy_data(data, imageSize, "glCompressedTexSubImage2DARB"); + save_pointer(&n[9], + copy_data(data, imageSize, "glCompressedTexSubImage2DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexSubImage2D(ctx->Exec, @@ -4788,7 +4482,8 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11); + n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, + 10 + POINTER_DWORDS); if (n) { n[1].e = target; n[2].i = level; @@ -4800,7 +4495,8 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, n[8].i = (GLint) depth; n[9].e = format; n[10].i = imageSize; - n[11].data = copy_data(data, imageSize, "glCompressedTexSubImage3DARB"); + save_pointer(&n[11], + copy_data(data, imageSize, "glCompressedTexSubImage3DARB")); } if (ctx->ExecuteFlag) { CALL_CompressedTexSubImage3D(ctx->Exec, @@ -5098,7 +4794,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 4); + n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 3 + POINTER_DWORDS); if (n) { GLubyte *programCopy = malloc(len); if (!programCopy) { @@ -5109,7 +4805,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, n[1].e = target; n[2].e = format; n[3].i = len; - n[4].data = programCopy; + save_pointer(&n[4], programCopy); } if (ctx->ExecuteFlag) { CALL_ProgramStringARB(ctx->Exec, (target, format, len, string)); @@ -6284,28 +5980,17 @@ save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) } -/** Return copy of memory */ -static void * -memdup(const void *src, GLsizei bytes) -{ - void *b = bytes >= 0 ? malloc(bytes) : NULL; - if (b) - memcpy(b, src, bytes); - return b; -} - - static void GLAPIENTRY save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_1FV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_1FV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 1 * sizeof(GLfloat)); + save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_Uniform1fv(ctx->Exec, (location, count, v)); @@ -6318,11 +6003,11 @@ save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_2FV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_2FV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 2 * sizeof(GLfloat)); + save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_Uniform2fv(ctx->Exec, (location, count, v)); @@ -6335,11 +6020,11 @@ save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_3FV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_3FV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 3 * sizeof(GLfloat)); + save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_Uniform3fv(ctx->Exec, (location, count, v)); @@ -6352,11 +6037,11 @@ save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_4FV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_4FV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 4 * sizeof(GLfloat)); + save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_Uniform4fv(ctx->Exec, (location, count, v)); @@ -6442,11 +6127,11 @@ save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 1 * sizeof(GLint)); + save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint))); } if (ctx->ExecuteFlag) { CALL_Uniform1iv(ctx->Exec, (location, count, v)); @@ -6459,11 +6144,11 @@ save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 2 * sizeof(GLint)); + save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint))); } if (ctx->ExecuteFlag) { CALL_Uniform2iv(ctx->Exec, (location, count, v)); @@ -6476,11 +6161,11 @@ save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 3 * sizeof(GLint)); + save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint))); } if (ctx->ExecuteFlag) { CALL_Uniform3iv(ctx->Exec, (location, count, v)); @@ -6493,11 +6178,11 @@ save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_4IV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_4IV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 4 * sizeof(GLfloat)); + save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_Uniform4iv(ctx->Exec, (location, count, v)); @@ -6584,11 +6269,11 @@ save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_1UIV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_1UIV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 1 * sizeof(*v)); + save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v))); } if (ctx->ExecuteFlag) { /*CALL_Uniform1uiv(ctx->Exec, (location, count, v));*/ @@ -6601,11 +6286,11 @@ save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_2UIV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_2UIV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 2 * sizeof(*v)); + save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v))); } if (ctx->ExecuteFlag) { /*CALL_Uniform2uiv(ctx->Exec, (location, count, v));*/ @@ -6618,11 +6303,11 @@ save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_3UIV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_3UIV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 3 * sizeof(*v)); + save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v))); } if (ctx->ExecuteFlag) { /*CALL_Uniform3uiv(ctx->Exec, (location, count, v));*/ @@ -6635,11 +6320,11 @@ save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_4UIV, 3); + n = alloc_instruction(ctx, OPCODE_UNIFORM_4UIV, 2 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; - n[3].data = memdup(v, count * 4 * sizeof(*v)); + save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v))); } if (ctx->ExecuteFlag) { /*CALL_Uniform4uiv(ctx->Exec, (location, count, v));*/ @@ -6655,12 +6340,12 @@ save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 2 * 2 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix2fv(ctx->Exec, (location, count, transpose, m)); @@ -6674,12 +6359,12 @@ save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 3 * 3 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix3fv(ctx->Exec, (location, count, transpose, m)); @@ -6693,12 +6378,12 @@ save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 4 * 4 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix4fv(ctx->Exec, (location, count, transpose, m)); @@ -6713,12 +6398,12 @@ save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 2 * 3 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m)); @@ -6732,12 +6417,12 @@ save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 3 * 2 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m)); @@ -6752,12 +6437,12 @@ save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 2 * 4 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m)); @@ -6771,12 +6456,12 @@ save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 4 * 2 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m)); @@ -6791,12 +6476,12 @@ save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 3 * 4 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m)); @@ -6810,12 +6495,12 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43, 4); + n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43, 3 + POINTER_DWORDS); if (n) { n[1].i = location; n[2].i = count; n[3].b = transpose; - n[4].data = memdup(m, count * 4 * 3 * sizeof(GLfloat)); + save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m)); @@ -7185,10 +6870,10 @@ save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) if (n) { union uint64_pair p; p.uint64 = timeout; - n[1].data = sync; - n[2].e = flags; - n[3].ui = p.uint32[0]; - n[4].ui = p.uint32[1]; + n[1].bf = flags; + n[2].ui = p.uint32[0]; + n[3].ui = p.uint32[1]; + save_pointer(&n[4], sync); } if (ctx->ExecuteFlag) { CALL_WaitSync(ctx->Exec, (sync, flags, timeout)); @@ -7252,10 +6937,14 @@ static void save_error(struct gl_context *ctx, GLenum error, const char *s) { Node *n; - n = alloc_instruction(ctx, OPCODE_ERROR, 2); + n = alloc_instruction(ctx, OPCODE_ERROR, 1 + POINTER_DWORDS); if (n) { n[1].e = error; - n[2].data = (void *) s; + save_pointer(&n[2], (void *) s); + /* note: the data/string here doesn't have to be freed in + * _mesa_delete_list() since the string is never dynamically + * allocated. + */ } } @@ -7336,7 +7025,7 @@ execute_list(struct gl_context *ctx, GLuint list) else { switch (opcode) { case OPCODE_ERROR: - _mesa_error(ctx, n[1].e, "%s", (const char *) n[2].data); + _mesa_error(ctx, n[1].e, "%s", (const char *) get_pointer(&n[2])); break; case OPCODE_ACCUM: CALL_Accum(ctx->Exec, (n[1].e, n[2].f)); @@ -7353,7 +7042,7 @@ execute_list(struct gl_context *ctx, GLuint list) ctx->Unpack = ctx->DefaultPacking; CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i, n[3].f, n[4].f, n[5].f, n[6].f, - (const GLubyte *) n[7].data)); + get_pointer(&n[7]))); ctx->Unpack = save; /* restore */ } break; @@ -7478,102 +7167,6 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_COLOR_MATERIAL: CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e)); break; - case OPCODE_COLOR_TABLE: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_ColorTable(ctx->Exec, (n[1].e, n[2].e, n[3].i, n[4].e, - n[5].e, n[6].data)); - ctx->Unpack = save; /* restore */ - } - break; - case OPCODE_COLOR_TABLE_PARAMETER_FV: - { - GLfloat params[4]; - params[0] = n[3].f; - params[1] = n[4].f; - params[2] = n[5].f; - params[3] = n[6].f; - CALL_ColorTableParameterfv(ctx->Exec, - (n[1].e, n[2].e, params)); - } - break; - case OPCODE_COLOR_TABLE_PARAMETER_IV: - { - GLint params[4]; - params[0] = n[3].i; - params[1] = n[4].i; - params[2] = n[5].i; - params[3] = n[6].i; - CALL_ColorTableParameteriv(ctx->Exec, - (n[1].e, n[2].e, params)); - } - break; - case OPCODE_COLOR_SUB_TABLE: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_ColorSubTable(ctx->Exec, (n[1].e, n[2].i, n[3].i, - n[4].e, n[5].e, n[6].data)); - ctx->Unpack = save; /* restore */ - } - break; - case OPCODE_CONVOLUTION_FILTER_1D: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_ConvolutionFilter1D(ctx->Exec, (n[1].e, n[2].i, n[3].i, - n[4].e, n[5].e, - n[6].data)); - ctx->Unpack = save; /* restore */ - } - break; - case OPCODE_CONVOLUTION_FILTER_2D: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_ConvolutionFilter2D(ctx->Exec, (n[1].e, n[2].i, n[3].i, - n[4].i, n[5].e, n[6].e, - n[7].data)); - ctx->Unpack = save; /* restore */ - } - break; - case OPCODE_CONVOLUTION_PARAMETER_I: - CALL_ConvolutionParameteri(ctx->Exec, (n[1].e, n[2].e, n[3].i)); - break; - case OPCODE_CONVOLUTION_PARAMETER_IV: - { - GLint params[4]; - params[0] = n[3].i; - params[1] = n[4].i; - params[2] = n[5].i; - params[3] = n[6].i; - CALL_ConvolutionParameteriv(ctx->Exec, - (n[1].e, n[2].e, params)); - } - break; - case OPCODE_CONVOLUTION_PARAMETER_F: - CALL_ConvolutionParameterf(ctx->Exec, (n[1].e, n[2].e, n[3].f)); - break; - case OPCODE_CONVOLUTION_PARAMETER_FV: - { - GLfloat params[4]; - params[0] = n[3].f; - params[1] = n[4].f; - params[2] = n[5].f; - params[3] = n[6].f; - CALL_ConvolutionParameterfv(ctx->Exec, - (n[1].e, n[2].e, params)); - } - break; - case OPCODE_COPY_COLOR_SUB_TABLE: - CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i, - n[3].i, n[4].i, n[5].i)); - break; - case OPCODE_COPY_COLOR_TABLE: - CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i, - n[3].i, n[4].i, n[5].i)); - break; case OPCODE_COPY_PIXELS: CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i, (GLsizei) n[3].i, (GLsizei) n[4].i, @@ -7628,7 +7221,7 @@ execute_list(struct gl_context *ctx, GLuint list) const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e, - n[5].data)); + get_pointer(&n[5]))); ctx->Unpack = save; /* restore */ } break; @@ -7665,9 +7258,6 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_HINT: CALL_Hint(ctx->Exec, (n[1].e, n[2].e)); break; - case OPCODE_HISTOGRAM: - CALL_Histogram(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].b)); - break; case OPCODE_INDEX_MASK: CALL_IndexMask(ctx->Exec, (n[1].ui)); break; @@ -7733,7 +7323,7 @@ execute_list(struct gl_context *ctx, GLuint list) GLfloat u1 = n[2].f; GLfloat u2 = n[3].f; CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder, - (GLfloat *) n[6].data)); + (GLfloat *) get_pointer(&n[6]))); } break; case OPCODE_MAP2: @@ -7749,7 +7339,7 @@ execute_list(struct gl_context *ctx, GLuint list) GLint vorder = n[9].i; CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, - (GLfloat *) n[10].data)); + (GLfloat *) get_pointer(&n[10]))); } break; case OPCODE_MAPGRID1: @@ -7762,9 +7352,6 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_MATRIX_MODE: CALL_MatrixMode(ctx->Exec, (n[1].e)); break; - case OPCODE_MIN_MAX: - CALL_Minmax(ctx->Exec, (n[1].e, n[2].e, n[3].b)); - break; case OPCODE_MULT_MATRIX: if (sizeof(Node) == sizeof(GLfloat)) { CALL_MultMatrixf(ctx->Exec, (&n[1].f)); @@ -7787,7 +7374,7 @@ execute_list(struct gl_context *ctx, GLuint list) break; case OPCODE_PIXEL_MAP: CALL_PixelMapfv(ctx->Exec, - (n[1].e, n[2].i, (GLfloat *) n[3].data)); + (n[1].e, n[2].i, get_pointer(&n[3]))); break; case OPCODE_PIXEL_TRANSFER: CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f)); @@ -7814,7 +7401,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data)); + CALL_PolygonStipple(ctx->Exec, (get_pointer(&n[1]))); ctx->Unpack = save; /* restore */ } break; @@ -7848,12 +7435,6 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_READ_BUFFER: CALL_ReadBuffer(ctx->Exec, (n[1].e)); break; - case OPCODE_RESET_HISTOGRAM: - CALL_ResetHistogram(ctx->Exec, (n[1].e)); - break; - case OPCODE_RESET_MIN_MAX: - CALL_ResetMinmax(ctx->Exec, (n[1].e)); - break; case OPCODE_ROTATE: CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; @@ -7930,7 +7511,7 @@ execute_list(struct gl_context *ctx, GLuint list) n[5].e, /* border */ n[6].e, /* format */ n[7].e, /* type */ - n[8].data)); + get_pointer(&n[8]))); ctx->Unpack = save; /* restore */ } break; @@ -7946,7 +7527,7 @@ execute_list(struct gl_context *ctx, GLuint list) n[6].e, /* border */ n[7].e, /* format */ n[8].e, /* type */ - n[9].data)); + get_pointer(&n[9]))); ctx->Unpack = save; /* restore */ } break; @@ -7963,7 +7544,7 @@ execute_list(struct gl_context *ctx, GLuint list) n[7].e, /* border */ n[8].e, /* format */ n[9].e, /* type */ - n[10].data)); + get_pointer(&n[10]))); ctx->Unpack = save; /* restore */ } break; @@ -7973,7 +7554,7 @@ execute_list(struct gl_context *ctx, GLuint list) ctx->Unpack = ctx->DefaultPacking; CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].e, - n[6].e, n[7].data)); + n[6].e, get_pointer(&n[7]))); ctx->Unpack = save; /* restore */ } break; @@ -7984,7 +7565,7 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].e, n[6].i, n[7].e, n[8].e, - n[9].data)); + get_pointer(&n[9]))); ctx->Unpack = save; /* restore */ } break; @@ -7995,7 +7576,7 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_TexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].e, n[10].e, - n[11].data)); + get_pointer(&n[11]))); ctx->Unpack = save; /* restore */ } break; @@ -8014,36 +7595,38 @@ execute_list(struct gl_context *ctx, GLuint list) break; case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */ CALL_CompressedTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, - n[4].i, n[5].i, n[6].i, - n[7].data)); + n[4].i, n[5].i, n[6].i, + get_pointer(&n[7]))); break; case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */ CALL_CompressedTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, - n[4].i, n[5].i, n[6].i, - n[7].i, n[8].data)); + n[4].i, n[5].i, n[6].i, + n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */ CALL_CompressedTexImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].e, - n[4].i, n[5].i, n[6].i, - n[7].i, n[8].i, - n[9].data)); + n[4].i, n[5].i, n[6].i, + n[7].i, n[8].i, + get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */ CALL_CompressedTexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, - n[5].e, n[6].i, n[7].data)); + n[5].e, n[6].i, + get_pointer(&n[7]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */ CALL_CompressedTexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].e, n[8].i, - n[9].data)); + get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */ CALL_CompressedTexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, - n[9].e, n[10].i, n[11].data)); + n[9].e, n[10].i, + get_pointer(&n[11]))); break; case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */ CALL_SampleCoverage(ctx->Exec, (n[1].f, n[2].b)); @@ -8067,7 +7650,8 @@ execute_list(struct gl_context *ctx, GLuint list) break; case OPCODE_PROGRAM_STRING_ARB: CALL_ProgramStringARB(ctx->Exec, - (n[1].e, n[2].e, n[3].i, n[4].data)); + (n[1].e, n[2].e, n[3].i, + get_pointer(&n[4]))); break; case OPCODE_PROGRAM_ENV_PARAMETER_ARB: CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f, @@ -8126,16 +7710,16 @@ execute_list(struct gl_context *ctx, GLuint list) (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f)); break; case OPCODE_UNIFORM_1FV: - CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2FV: - CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3FV: - CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4FV: - CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1I: CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i)); @@ -8151,16 +7735,16 @@ execute_list(struct gl_context *ctx, GLuint list) (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i)); break; case OPCODE_UNIFORM_1IV: - CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2IV: - CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3IV: - CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4IV: - CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, n[3].data)); + CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1UI: /*CALL_Uniform1uiARB(ctx->Exec, (n[1].i, n[2].i));*/ @@ -8177,52 +7761,56 @@ execute_list(struct gl_context *ctx, GLuint list) */ break; case OPCODE_UNIFORM_1UIV: - /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/ + /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i, + get_pointer(&n[3])));*/ break; case OPCODE_UNIFORM_2UIV: - /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/ + /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i, + get_pointer(&n[3])));*/ break; case OPCODE_UNIFORM_3UIV: - /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/ + /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i, + get_pointer(&n[3])));*/ break; case OPCODE_UNIFORM_4UIV: - /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/ + /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i, + get_pointer(&n[3])));*/ break; case OPCODE_UNIFORM_MATRIX22: CALL_UniformMatrix2fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX33: CALL_UniformMatrix3fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX44: CALL_UniformMatrix4fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX23: CALL_UniformMatrix2x3fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX32: CALL_UniformMatrix3x2fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX24: CALL_UniformMatrix2x4fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX42: CALL_UniformMatrix4x2fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX34: CALL_UniformMatrix3x4fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX43: CALL_UniformMatrix4x3fv(ctx->Exec, - (n[1].i, n[2].i, n[3].b, n[4].data)); + (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_CLAMP_COLOR: @@ -8476,9 +8064,10 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_WAIT_SYNC: { union uint64_pair p; - p.uint32[0] = n[3].ui; - p.uint32[1] = n[4].ui; - CALL_WaitSync(ctx->Exec, (n[1].data, n[2].bf, p.uint64)); + p.uint32[0] = n[2].ui; + p.uint32[1] = n[3].ui; + CALL_WaitSync(ctx->Exec, + (get_pointer(&n[4]), n[1].bf, p.uint64)); } break; @@ -8495,7 +8084,7 @@ execute_list(struct gl_context *ctx, GLuint list) break; case OPCODE_CONTINUE: - n = (Node *) n[1].next; + n = (Node *) get_pointer(&n[1]); break; case OPCODE_END_OF_LIST: done = GL_TRUE; @@ -8684,6 +8273,8 @@ _mesa_EndList(void) (void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0); + trim_list(ctx); + /* Destroy old list, if any */ destroy_list(ctx, ctx->ListState.CurrentList->Name); @@ -8697,6 +8288,8 @@ _mesa_EndList(void) mesa_print_display_list(ctx->ListState.CurrentList->Name); ctx->ListState.CurrentList = NULL; + ctx->ListState.CurrentBlock = NULL; + ctx->ListState.CurrentPos = 0; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; @@ -8998,22 +8591,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx) /* Not all are supported */ SET_BlendColor(table, save_BlendColor); SET_BlendEquation(table, save_BlendEquation); - SET_ColorSubTable(table, save_ColorSubTable); - SET_ColorTable(table, save_ColorTable); - SET_ColorTableParameterfv(table, save_ColorTableParameterfv); - SET_ColorTableParameteriv(table, save_ColorTableParameteriv); - SET_ConvolutionFilter1D(table, save_ConvolutionFilter1D); - SET_ConvolutionFilter2D(table, save_ConvolutionFilter2D); - SET_ConvolutionParameterf(table, save_ConvolutionParameterf); - SET_ConvolutionParameterfv(table, save_ConvolutionParameterfv); - SET_ConvolutionParameteri(table, save_ConvolutionParameteri); - SET_ConvolutionParameteriv(table, save_ConvolutionParameteriv); - SET_CopyColorSubTable(table, save_CopyColorSubTable); - SET_CopyColorTable(table, save_CopyColorTable); - SET_Histogram(table, save_Histogram); - SET_Minmax(table, save_Minmax); - SET_ResetHistogram(table, save_ResetHistogram); - SET_ResetMinmax(table, save_ResetMinmax); /* 2. GL_EXT_blend_color */ #if 0 @@ -9030,12 +8607,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_TexSubImage3DEXT(table, save_TexSubImage3D); #endif - /* 14. GL_SGI_color_table */ -#if 0 - SET_ColorTableSGI(table, save_ColorTable); - SET_ColorSubTableSGI(table, save_ColorSubTable); -#endif - /* 37. GL_EXT_blend_minmax */ #if 0 SET_BlendEquationEXT(table, save_BlendEquationEXT); @@ -9332,7 +8903,8 @@ print_list(struct gl_context *ctx, GLuint list) break; case OPCODE_BITMAP: printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, - n[3].f, n[4].f, n[5].f, n[6].f, (void *) n[7].data); + n[3].f, n[4].f, n[5].f, n[6].f, + get_pointer(&n[7])); break; case OPCODE_CALL_LIST: printf("CallList %d\n", (int) n[1].ui); @@ -9341,16 +8913,6 @@ print_list(struct gl_context *ctx, GLuint list) printf("CallList %d + offset %u = %u\n", (int) n[1].ui, ctx->List.ListBase, ctx->List.ListBase + n[1].ui); break; - case OPCODE_COLOR_TABLE_PARAMETER_FV: - printf("ColorTableParameterfv %s %s %f %f %f %f\n", - enum_string(n[1].e), enum_string(n[2].e), - n[3].f, n[4].f, n[5].f, n[6].f); - break; - case OPCODE_COLOR_TABLE_PARAMETER_IV: - printf("ColorTableParameteriv %s %s %d %d %d %d\n", - enum_string(n[1].e), enum_string(n[2].e), - n[3].i, n[4].i, n[5].i, n[6].i); - break; case OPCODE_DISABLE: printf("Disable %s\n", enum_string(n[1].e)); break; @@ -9525,12 +9087,12 @@ print_list(struct gl_context *ctx, GLuint list) * meta opcodes/commands */ case OPCODE_ERROR: - printf("Error: %s %s\n", - enum_string(n[1].e), (const char *) n[2].data); + printf("Error: %s %s\n", enum_string(n[1].e), + (const char *) get_pointer(&n[2])); break; case OPCODE_CONTINUE: printf("DISPLAY-LIST-CONTINUE\n"); - n = (Node *) n[1].next; + n = (Node *) get_pointer(&n[1]); break; case OPCODE_END_OF_LIST: printf("END-LIST %u\n", list); diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c index c047f5df2..bb4a23c91 100644 --- a/mesalib/src/mesa/main/enable.c +++ b/mesalib/src/mesa/main/enable.c @@ -934,25 +934,6 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) ctx->ATIFragmentShader.Enabled = state; break; - /* GL_MESA_texture_array */ - case GL_TEXTURE_1D_ARRAY_EXT: - if (ctx->API != API_OPENGL_COMPAT) - goto invalid_enum_error; - CHECK_EXTENSION(MESA_texture_array, cap); - if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) { - return; - } - break; - - case GL_TEXTURE_2D_ARRAY_EXT: - if (ctx->API != API_OPENGL_COMPAT) - goto invalid_enum_error; - CHECK_EXTENSION(MESA_texture_array, cap); - if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) { - return; - } - break; - case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 42da9057c..f0e1858e4 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -82,6 +82,7 @@ static const struct extension extension_table[] = { { "GL_ARB_ES3_compatibility", o(ARB_ES3_compatibility), GL, 2012 }, { "GL_ARB_base_instance", o(ARB_base_instance), GL, 2011 }, { "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 }, + { "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 }, { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 }, { "GL_ARB_copy_buffer", o(dummy_true), GL, 2008 }, { "GL_ARB_conservative_depth", o(ARB_conservative_depth), GL, 2011 }, @@ -158,6 +159,7 @@ static const struct extension extension_table[] = { { "GL_ARB_texture_rg", o(ARB_texture_rg), GL, 2008 }, { "GL_ARB_texture_storage", o(dummy_true), GL, 2011 }, { "GL_ARB_texture_storage_multisample", o(ARB_texture_multisample), GL, 2012 }, + { "GL_ARB_texture_view", o(ARB_texture_view), GL, 2012 }, { "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 }, { "GL_ARB_timer_query", o(ARB_timer_query), GL, 2010 }, { "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 }, @@ -199,7 +201,7 @@ static const struct extension extension_table[] = { { "GL_EXT_gpu_shader4", o(EXT_gpu_shader4), GL, 2006 }, { "GL_EXT_map_buffer_range", o(ARB_map_buffer_range), ES1 | ES2, 2012 }, { "GL_EXT_multi_draw_arrays", o(dummy_true), GLL | ES1 | ES2, 1999 }, - { "GL_EXT_packed_depth_stencil", o(EXT_packed_depth_stencil), GL, 2005 }, + { "GL_EXT_packed_depth_stencil", o(dummy_true), GL, 2005 }, { "GL_EXT_packed_float", o(EXT_packed_float), GL, 2004 }, { "GL_EXT_packed_pixels", o(dummy_true), GLL, 1997 }, { "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, @@ -272,7 +274,7 @@ static const struct extension extension_table[] = { { "GL_OES_framebuffer_object", o(dummy_true), ES1, 2005 }, { "GL_OES_get_program_binary", o(dummy_true), ES2, 2008 }, { "GL_OES_mapbuffer", o(dummy_true), ES1 | ES2, 2005 }, - { "GL_OES_packed_depth_stencil", o(EXT_packed_depth_stencil), ES1 | ES2, 2007 }, + { "GL_OES_packed_depth_stencil", o(dummy_true), ES1 | ES2, 2007 }, { "GL_OES_point_size_array", o(dummy_true), ES1, 2004 }, { "GL_OES_point_sprite", o(ARB_point_sprite), ES1, 2004 }, { "GL_OES_query_matrix", o(dummy_true), ES1, 2003 }, @@ -302,7 +304,7 @@ static const struct extension extension_table[] = { { "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 }, { "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 }, { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, - { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GL, 2012 }, + { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GLC, 2012 }, { "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL, 2006 }, { "GL_APPLE_packed_pixels", o(dummy_true), GLL, 2002 }, { "GL_APPLE_texture_max_level", o(dummy_true), ES1 | ES2, 2009 }, @@ -321,7 +323,6 @@ static const struct extension extension_table[] = { { "GL_IBM_texture_mirrored_repeat", o(dummy_true), GLL, 1998 }, { "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GLL, 1999 }, { "GL_MESA_pack_invert", o(MESA_pack_invert), GL, 2002 }, - { "GL_MESA_texture_array", o(MESA_texture_array), GLL, 2007 }, { "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), GL, 2009 }, { "GL_MESA_window_pos", o(dummy_true), GLL, 2000 }, { "GL_MESA_ycbcr_texture", o(MESA_ycbcr_texture), GL, 2002 }, @@ -333,7 +334,7 @@ static const struct extension extension_table[] = { { "GL_NV_fog_distance", o(NV_fog_distance), GLL, 2001 }, { "GL_NV_fragment_program_option", o(NV_fragment_program_option), GLL, 2005 }, { "GL_NV_light_max_exponent", o(dummy_true), GLL, 1999 }, - { "GL_NV_packed_depth_stencil", o(EXT_packed_depth_stencil), GL, 2000 }, + { "GL_NV_packed_depth_stencil", o(dummy_true), GL, 2000 }, { "GL_NV_point_sprite", o(NV_point_sprite), GL, 2001 }, { "GL_NV_primitive_restart", o(NV_primitive_restart), GLL, 2002 }, { "GL_NV_read_buffer", o(dummy_true), ES2, 2011 }, @@ -436,7 +437,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.EXT_depth_bounds_test = GL_TRUE; ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; ctx->Extensions.EXT_framebuffer_blit = GL_TRUE; - ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE; ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; ctx->Extensions.EXT_point_parameters = GL_TRUE; ctx->Extensions.EXT_provoking_vertex = GL_TRUE; @@ -453,7 +453,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/ ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; ctx->Extensions.MESA_pack_invert = GL_TRUE; - ctx->Extensions.MESA_texture_array = GL_TRUE; ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; ctx->Extensions.NV_conditional_render = GL_TRUE; ctx->Extensions.NV_point_sprite = GL_TRUE; @@ -480,7 +479,8 @@ set_extension( struct gl_context *ctx, const char *name, GLboolean state ) if (ctx->Extensions.String) { /* The string was already queried - can't change it now! */ - _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name); + _mesa_problem(ctx, "Trying to enable/disable extension after " + "glGetString(GL_EXTENSIONS): %s", name); return GL_FALSE; } @@ -679,10 +679,10 @@ _mesa_make_extension_string(struct gl_context *ctx) return NULL; } - /* Sort extensions in chronological order because certain old applications (e.g., - * Quake3 demo) store the extension list in a static size buffer so chronologically - * order ensure that the extensions that such applications expect will fit into - * that buffer. + /* Sort extensions in chronological order because certain old applications + * (e.g., Quake3 demo) store the extension list in a static size buffer so + * chronologically order ensure that the extensions that such applications + * expect will fit into that buffer. */ j = 0; for (i = extension_table; i->name != 0; ++i) { @@ -693,7 +693,8 @@ _mesa_make_extension_string(struct gl_context *ctx) } } assert(j == count); - qsort(extension_indices, count, sizeof *extension_indices, extension_compare); + qsort(extension_indices, count, + sizeof *extension_indices, extension_compare); /* Build the extension string.*/ for (j = 0; j < count; ++j) { diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 861885dd3..2892784f8 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -781,9 +781,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, if (baseFormat == GL_DEPTH_COMPONENT) { /* OK */ } - else if (ctx->Extensions.EXT_packed_depth_stencil && - ctx->Extensions.ARB_depth_texture && - baseFormat == GL_DEPTH_STENCIL_EXT) { + else if (ctx->Extensions.ARB_depth_texture && + baseFormat == GL_DEPTH_STENCIL) { /* OK */ } else { @@ -794,9 +793,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } else { ASSERT(format == GL_STENCIL); - if (ctx->Extensions.EXT_packed_depth_stencil && - ctx->Extensions.ARB_depth_texture && - baseFormat == GL_DEPTH_STENCIL_EXT) { + if (ctx->Extensions.ARB_depth_texture && + baseFormat == GL_DEPTH_STENCIL) { /* OK */ } else { @@ -830,8 +828,7 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, if (baseFormat == GL_DEPTH_COMPONENT) { /* OK */ } - else if (ctx->Extensions.EXT_packed_depth_stencil && - baseFormat == GL_DEPTH_STENCIL_EXT) { + else if (baseFormat == GL_DEPTH_STENCIL) { /* OK */ } else { @@ -842,11 +839,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } else { assert(format == GL_STENCIL); - if (baseFormat == GL_STENCIL_INDEX) { - /* OK */ - } - else if (ctx->Extensions.EXT_packed_depth_stencil && - baseFormat == GL_DEPTH_STENCIL_EXT) { + if (baseFormat == GL_STENCIL_INDEX || + baseFormat == GL_DEPTH_STENCIL) { /* OK */ } else { @@ -1457,13 +1451,10 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT; - case GL_DEPTH_STENCIL_EXT: - return _mesa_is_desktop_gl(ctx) - && ctx->Extensions.EXT_packed_depth_stencil - ? GL_DEPTH_STENCIL_EXT : 0; - case GL_DEPTH24_STENCIL8_EXT: - return ctx->Extensions.EXT_packed_depth_stencil - ? GL_DEPTH_STENCIL_EXT : 0; + case GL_DEPTH_STENCIL: + return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_STENCIL : 0; + case GL_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL; case GL_DEPTH_COMPONENT32F: return ctx->Version >= 30 || (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_buffer_float) diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 01edd3ff8..ba6258d89 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -543,7 +543,8 @@ get_current_attrib(texenv_fragment_program *p, GLuint attrib) ir_rvalue *val; current = p->shader->symbols->get_variable("gl_CurrentAttribFragMESA"); - current->max_array_access = MAX2(current->max_array_access, attrib); + assert(current); + current->data.max_array_access = MAX2(current->data.max_array_access, attrib); val = new(p->mem_ctx) ir_dereference_variable(current); ir_rvalue *index = new(p->mem_ctx) ir_constant(attrib); return new(p->mem_ctx) ir_dereference_array(val, index); @@ -587,7 +588,7 @@ get_source(texenv_fragment_program *p, var = p->shader->symbols->get_variable("gl_TextureEnvColor"); assert(var); deref = new(p->mem_ctx) ir_dereference_variable(var); - var->max_array_access = MAX2(var->max_array_access, unit); + var->data.max_array_access = MAX2(var->data.max_array_access, unit); return new(p->mem_ctx) ir_dereference_array(deref, new(p->mem_ctx) ir_constant(unit)); @@ -927,7 +928,7 @@ static void load_texture( texenv_fragment_program *p, GLuint unit ) texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array); ir_rvalue *index = new(p->mem_ctx) ir_constant(unit); texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index); - tc_array->max_array_access = MAX2(tc_array->max_array_access, unit); + tc_array->data.max_array_access = MAX2(tc_array->data.max_array_access, unit); } if (!p->state->unit[unit].enabled) { @@ -1096,14 +1097,16 @@ load_texunit_bumpmap( texenv_fragment_program *p, GLuint unit ) ir_variable *rot_mat_0, *rot_mat_1; rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA"); + assert(rot_mat_0); rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA"); + assert(rot_mat_1); ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord"); assert(tc_array); texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array); ir_rvalue *index = new(p->mem_ctx) ir_constant(bumpedUnitNr); texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index); - tc_array->max_array_access = MAX2(tc_array->max_array_access, unit); + tc_array->data.max_array_access = MAX2(tc_array->data.max_array_access, unit); load_texenv_source( p, unit + SRC_TEXTURE0, unit ); @@ -1157,8 +1160,11 @@ emit_fog_instructions(texenv_fragment_program *p, fragcolor = swizzle_xyz(fog_result); oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA"); + assert(oparams); fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord"); + assert(fogcoord); params = p->shader->symbols->get_variable("gl_Fog"); + assert(params); f = new(p->mem_ctx) ir_dereference_variable(fogcoord); ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor"); @@ -1344,7 +1350,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key) p.shader->CompileStatus = true; p.shader->Version = state->language_version; - p.shader->num_builtins_to_link = state->num_builtins_to_link; + p.shader->uses_builtin_functions = state->uses_builtin_functions; p.shader_program->Shaders = (gl_shader **)malloc(sizeof(*p.shader_program->Shaders)); p.shader_program->Shaders[0] = p.shader; diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 7f233409e..691380898 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -327,8 +327,8 @@ static const int extra_EXT_framebuffer_sRGB_and_new_buffers[] = { EXTRA_END }; -static const int extra_MESA_texture_array_es3[] = { - EXT(MESA_texture_array), +static const int extra_EXT_texture_array_es3[] = { + EXT(EXT_texture_array), EXTRA_API_ES3, EXTRA_END }; @@ -339,7 +339,7 @@ static const int extra_ARB_shader_atomic_counters_and_geometry_shader[] = { }; EXTRA_EXT(ARB_texture_cube_map); -EXTRA_EXT(MESA_texture_array); +EXTRA_EXT(EXT_texture_array); EXTRA_EXT(NV_fog_distance); EXTRA_EXT(EXT_texture_filter_anisotropic); EXTRA_EXT(NV_point_sprite); @@ -565,8 +565,6 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - case GL_TEXTURE_1D_ARRAY_EXT: - case GL_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_CUBE_MAP_ARB: case GL_TEXTURE_RECTANGLE_NV: case GL_TEXTURE_EXTERNAL_OES: diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 781b796ee..653bf6256 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -376,8 +376,8 @@ descriptor=[ [ "PIXEL_UNPACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_pixel_buffer_object" ], # GL_EXT_texture_array - [ "TEXTURE_BINDING_2D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_ARRAY_INDEX, extra_MESA_texture_array_es3" ], - [ "MAX_ARRAY_TEXTURE_LAYERS_EXT", "CONTEXT_INT(Const.MaxArrayTextureLayers), extra_MESA_texture_array_es3" ], + [ "TEXTURE_BINDING_2D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_ARRAY_INDEX, extra_EXT_texture_array_es3" ], + [ "MAX_ARRAY_TEXTURE_LAYERS_EXT", "CONTEXT_INT(Const.MaxArrayTextureLayers), extra_EXT_texture_array_es3" ], # GL_EXT_transform_feedback [ "TRANSFORM_FEEDBACK_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_transform_feedback" ], @@ -504,10 +504,8 @@ descriptor=[ [ "STEREO", "BUFFER_INT(Visual.stereoMode), NO_EXTRA" ], [ "TEXTURE_1D", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ], [ "TEXTURE_3D", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ], - [ "TEXTURE_1D_ARRAY_EXT", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ], - [ "TEXTURE_2D_ARRAY_EXT", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ], [ "TEXTURE_BINDING_1D", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_INDEX, NO_EXTRA" ], - [ "TEXTURE_BINDING_1D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array" ], + [ "TEXTURE_BINDING_1D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_ARRAY_INDEX, extra_EXT_texture_array" ], [ "TEXTURE_GEN_S", "LOC_TEXUNIT, TYPE_BIT_0, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ], [ "TEXTURE_GEN_T", "LOC_TEXUNIT, TYPE_BIT_1, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ], [ "TEXTURE_GEN_R", "LOC_TEXUNIT, TYPE_BIT_2, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ], diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c index d8189115a..b66e24788 100644 --- a/mesalib/src/mesa/main/getstring.c +++ b/mesalib/src/mesa/main/getstring.c @@ -42,8 +42,6 @@ shading_language_version(struct gl_context *ctx) case API_OPENGL_COMPAT: case API_OPENGL_CORE: switch (ctx->Const.GLSLVersion) { - case 110: - return (const GLubyte *) "1.10"; case 120: return (const GLubyte *) "1.20"; case 130: diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 740faa890..bec7a9bbb 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -1301,9 +1301,6 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_OPERATION; case GL_UNSIGNED_INT_24_8: - if (!ctx->Extensions.EXT_packed_depth_stencil) { - return GL_INVALID_ENUM; - } if (format != GL_DEPTH_STENCIL) { return GL_INVALID_OPERATION; } @@ -1484,9 +1481,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, else return GL_INVALID_OPERATION; - case GL_DEPTH_STENCIL_EXT: - if (ctx->Extensions.EXT_packed_depth_stencil && - type == GL_UNSIGNED_INT_24_8) + case GL_DEPTH_STENCIL: + if (type == GL_UNSIGNED_INT_24_8) return GL_NO_ERROR; else if (ctx->Extensions.ARB_depth_buffer_float && type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) @@ -1694,8 +1690,6 @@ GLenum _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, GLenum internalFormat) { - GLboolean type_valid = GL_TRUE; - switch (format) { case GL_RGBA: switch (type) { @@ -2116,5 +2110,5 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, break; } - return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION; + return GL_NO_ERROR; } diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index 277e9476a..4afe156b0 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -168,6 +168,8 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment) * \param ptr pointer to the memory to be freed. * The actual address to free is stored in the word immediately before the * address the client sees. + * Note that it is legal to pass NULL pointer to this function and will be + * handled accordingly. */ void _mesa_align_free(void *ptr) @@ -177,9 +179,11 @@ _mesa_align_free(void *ptr) #elif defined(_WIN32) && defined(_MSC_VER) _aligned_free(ptr); #else - void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); - void *realAddr = *cubbyHole; - free(realAddr); + if (ptr) { + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + free(realAddr); + } #endif /* defined(HAVE_POSIX_MEMALIGN) */ } @@ -199,8 +203,8 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize, if (newBuf && oldBuffer && copySize > 0) { memcpy(newBuf, oldBuffer, copySize); } - if (oldBuffer) - _mesa_align_free(oldBuffer); + + _mesa_align_free(oldBuffer); return newBuf; #endif } diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 180f89116..033015780 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1767,8 +1767,8 @@ _mesa_generate_mipmap_level(GLenum target, * compute next (level+1) image size * \return GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size) */ -static GLboolean -next_mipmap_level_size(GLenum target, GLint border, +GLboolean +_mesa_next_mipmap_level_size(GLenum target, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLint *dstWidth, GLint *dstHeight, GLint *dstDepth) { @@ -1911,7 +1911,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, srcDepth = srcImage->Depth; border = srcImage->Border; - nextLevel = next_mipmap_level_size(target, border, + nextLevel = _mesa_next_mipmap_level_size(target, border, srcWidth, srcHeight, srcDepth, &dstWidth, &dstHeight, &dstDepth); if (!nextLevel) @@ -2102,7 +2102,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, srcDepth = srcImage->Depth; border = srcImage->Border; - nextLevel = next_mipmap_level_size(target, border, + nextLevel = _mesa_next_mipmap_level_size(target, border, srcWidth, srcHeight, srcDepth, &dstWidth, &dstHeight, &dstDepth); if (!nextLevel) diff --git a/mesalib/src/mesa/main/mipmap.h b/mesalib/src/mesa/main/mipmap.h index d5bd1d83d..ee91df006 100644 --- a/mesalib/src/mesa/main/mipmap.h +++ b/mesalib/src/mesa/main/mipmap.h @@ -51,5 +51,9 @@ extern void _mesa_generate_mipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj); +extern GLboolean +_mesa_next_mipmap_level_size(GLenum target, GLint border, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint *dstWidth, GLint *dstHeight, GLint *dstDepth); #endif /* MIPMAP_H */ diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index b4b432f40..f93bb5641 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -280,6 +280,7 @@ typedef enum */ #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. @@ -1193,6 +1194,11 @@ struct gl_texture_object pressure? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ + GLuint MinLevel; /**< GL_ARB_texture_view */ + GLuint MinLayer; /**< GL_ARB_texture_view */ + GLuint NumLevels; /**< GL_ARB_texture_view */ + GLuint NumLayers; /**< GL_ARB_texture_view */ + /** Actual texture images, indexed by [cube face] and [mipmap level] */ struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS]; @@ -1968,12 +1974,13 @@ typedef enum */ typedef enum { - SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ - SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */ - SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ - SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */ - SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */ - SYSTEM_VALUE_MAX /**< Number of values */ + SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ + SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */ + SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ + SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */ + SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */ + SYSTEM_VALUE_SAMPLE_MASK_IN, /**< Fragment shader only */ + SYSTEM_VALUE_MAX /**< Number of values */ } gl_system_value; @@ -2132,6 +2139,12 @@ struct gl_fragment_program * uses centroid interpolation, 0 otherwise. Unused inputs are 0. */ GLbitfield64 IsCentroid; + + /** + * Bitfield indicating, for each fragment shader input, 1 if that input + * uses sample interpolation, 0 otherwise. Unused inputs are 0. + */ + GLbitfield64 IsSample; }; @@ -2352,9 +2365,7 @@ struct gl_shader struct exec_list *ir; struct glsl_symbol_table *symbols; - /** Shaders containing built-in functions that are used for linking. */ - struct gl_shader *builtins_to_link[16]; - unsigned num_builtins_to_link; + bool uses_builtin_functions; /** * Geometry shader state from GLSL 1.50 layout qualifiers. @@ -2388,9 +2399,10 @@ typedef enum MESA_SHADER_VERTEX = 0, MESA_SHADER_GEOMETRY = 1, MESA_SHADER_FRAGMENT = 2, - MESA_SHADER_TYPES = 3 } gl_shader_type; +#define MESA_SHADER_TYPES (MESA_SHADER_FRAGMENT + 1) + struct gl_uniform_buffer_variable { @@ -3374,6 +3386,7 @@ struct gl_extensions GLboolean ARB_texture_query_lod; GLboolean ARB_texture_rg; GLboolean ARB_texture_rgb10_a2ui; + GLboolean ARB_texture_view; GLboolean ARB_timer_query; GLboolean ARB_transform_feedback2; GLboolean ARB_transform_feedback3; @@ -3395,7 +3408,6 @@ struct gl_extensions GLboolean EXT_framebuffer_sRGB; GLboolean EXT_gpu_program_parameters; GLboolean EXT_gpu_shader4; - GLboolean EXT_packed_depth_stencil; GLboolean EXT_packed_float; GLboolean EXT_pixel_buffer_object; GLboolean EXT_point_parameters; @@ -3432,7 +3444,6 @@ struct gl_extensions GLboolean ATI_fragment_shader; GLboolean ATI_separate_stencil; GLboolean MESA_pack_invert; - GLboolean MESA_texture_array; GLboolean MESA_ycbcr_texture; GLboolean NV_conditional_render; GLboolean NV_fog_distance; diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index 4981e6fb2..e62f77012 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -93,6 +93,25 @@ fail: return NULL; } +static void +free_performance_monitor(GLuint key, void *data, void *user) +{ + struct gl_perf_monitor_object *m = data; + struct gl_context *ctx = user; + + ralloc_free(m->ActiveGroups); + ralloc_free(m->ActiveCounters); + ctx->Driver.DeletePerfMonitor(ctx, m); +} + +void +_mesa_free_performance_monitors(struct gl_context *ctx) +{ + _mesa_HashDeleteAll(ctx->PerfMonitor.Monitors, + free_performance_monitor, ctx); + _mesa_DeleteHashTable(ctx->PerfMonitor.Monitors); +} + static inline struct gl_perf_monitor_object * lookup_monitor(struct gl_context *ctx, GLuint id) { diff --git a/mesalib/src/mesa/main/performance_monitor.h b/mesalib/src/mesa/main/performance_monitor.h index a852a4184..76234e5c1 100644 --- a/mesalib/src/mesa/main/performance_monitor.h +++ b/mesalib/src/mesa/main/performance_monitor.h @@ -35,6 +35,9 @@ extern void _mesa_init_performance_monitors(struct gl_context *ctx); +extern void +_mesa_free_performance_monitors(struct gl_context *ctx); + extern void GLAPIENTRY _mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups); diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index 3014a9778..f14e1a562 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -106,8 +106,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, const ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var == NULL - || var->mode != ir_var_shader_in - || var->location == -1) + || var->data.mode != ir_var_shader_in + || var->data.location == -1) continue; if (current_index == desired_index) { @@ -169,13 +169,13 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name) * attribute, or if an error occurs, -1 will be returned." */ if (var == NULL - || var->mode != ir_var_shader_in - || var->location == -1 - || var->location < VERT_ATTRIB_GENERIC0) + || var->data.mode != ir_var_shader_in + || var->data.location == -1 + || var->data.location < VERT_ATTRIB_GENERIC0) continue; if (strcmp(var->name, name) == 0) - return var->location - VERT_ATTRIB_GENERIC0; + return var->data.location - VERT_ATTRIB_GENERIC0; } return -1; @@ -197,8 +197,8 @@ _mesa_count_active_attribs(struct gl_shader_program *shProg) const ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var == NULL - || var->mode != ir_var_shader_in - || var->location == -1) + || var->data.mode != ir_var_shader_in + || var->data.location == -1) continue; i++; @@ -223,8 +223,8 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg) const ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var == NULL - || var->mode != ir_var_shader_in - || var->location == -1) + || var->data.mode != ir_var_shader_in + || var->data.location == -1) continue; const size_t len = strlen(var->name); @@ -333,13 +333,13 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name) * attribute, or if an error occurs, -1 will be returned." */ if (var == NULL - || var->mode != ir_var_shader_out - || var->location == -1 - || var->location < FRAG_RESULT_DATA0) + || var->data.mode != ir_var_shader_out + || var->data.location == -1 + || var->data.location < FRAG_RESULT_DATA0) continue; if (strcmp(var->name, name) == 0) - return var->index; + return var->data.index; } return -1; @@ -389,13 +389,13 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name) * attribute, or if an error occurs, -1 will be returned." */ if (var == NULL - || var->mode != ir_var_shader_out - || var->location == -1 - || var->location < FRAG_RESULT_DATA0) + || var->data.mode != ir_var_shader_out + || var->data.location == -1 + || var->data.location < FRAG_RESULT_DATA0) continue; if (strcmp(var->name, name) == 0) - return var->location - FRAG_RESULT_DATA0; + return var->data.location - FRAG_RESULT_DATA0; } return -1; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 1d9aac39d..4f3be68a4 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -414,7 +414,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) err = GL_INVALID_OPERATION; else err = GL_INVALID_VALUE; - _mesa_error(ctx, err, "glDetachProgram(shader)"); + _mesa_error(ctx, err, "glDetachShader(shader)"); return; } } diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h index de1c9fcaf..aff178f26 100644 --- a/mesalib/src/mesa/main/shaderobj.h +++ b/mesalib/src/mesa/main/shaderobj.h @@ -113,7 +113,7 @@ _mesa_shader_type_to_index(GLenum v) return MESA_SHADER_GEOMETRY; default: ASSERT(0 && "bad value in _mesa_shader_type_to_index()"); - return MESA_SHADER_TYPES; + return MESA_SHADER_VERTEX; } } diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index d66ca1abc..200d29c2f 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -759,8 +759,7 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target) return ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; default: diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 793c5d382..9c3f1e86e 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -48,6 +48,7 @@ #include "texobj.h" #include "texstate.h" #include "texstorage.h" +#include "textureview.h" #include "mtypes.h" #include "glformats.h" @@ -300,14 +301,12 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) } } - if (ctx->Extensions.EXT_packed_depth_stencil) { - switch (internalFormat) { - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - return GL_DEPTH_STENCIL_EXT; - default: - ; /* fallthrough */ - } + switch (internalFormat) { + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL; + default: + ; /* fallthrough */ } if (ctx->Extensions.EXT_texture_sRGB) { @@ -752,8 +751,7 @@ _mesa_select_tex_object(struct gl_context *ctx, const struct gl_texture_unit *texUnit, GLenum target) { - const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; switch (target) { case GL_TEXTURE_1D: @@ -1018,8 +1016,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) case GL_PROXY_TEXTURE_1D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array) + return ctx->Extensions.EXT_texture_array ? ctx->Const.MaxTextureLevels : 0; case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: @@ -1726,8 +1723,7 @@ target_can_be_compressed(const struct gl_context *ctx, GLenum target, return ctx->Extensions.ARB_texture_cube_map; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return ctx->Extensions.EXT_texture_array; case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; @@ -1775,9 +1771,7 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) && ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY_EXT: case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - return _mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; default: return GL_FALSE; } @@ -1788,14 +1782,10 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_PROXY_TEXTURE_3D: return _mesa_is_desktop_gl(ctx); case GL_TEXTURE_2D_ARRAY_EXT: - return (_mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array)) + return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) || _mesa_is_gles3(ctx); case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - return _mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; @@ -1836,9 +1826,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY_EXT: - return _mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; default: return GL_FALSE; } @@ -1847,9 +1835,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_TEXTURE_3D: return GL_TRUE; case GL_TEXTURE_2D_ARRAY_EXT: - return (_mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array)) + return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) || _mesa_is_gles3(ctx); case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: @@ -2870,7 +2856,7 @@ _mesa_choose_texture_format(struct gl_context *ctx, } /* If the application requested compression to an S3TC format but we don't - * have the DTXn library, force a generic compressed format instead. + * have the DXTn library, force a generic compressed format instead. */ if (internalFormat != format && format != GL_NONE) { const GLenum before = internalFormat; @@ -3892,87 +3878,108 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, static gl_format get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) { + if (ctx->API != API_OPENGL_CORE) { + switch (internalFormat) { + case GL_ALPHA8: + return MESA_FORMAT_A8; + case GL_ALPHA16: + return MESA_FORMAT_A16; + case GL_ALPHA16F_ARB: + return MESA_FORMAT_ALPHA_FLOAT16; + case GL_ALPHA32F_ARB: + return MESA_FORMAT_ALPHA_FLOAT32; + case GL_ALPHA8I_EXT: + return MESA_FORMAT_ALPHA_INT8; + case GL_ALPHA16I_EXT: + return MESA_FORMAT_ALPHA_INT16; + case GL_ALPHA32I_EXT: + return MESA_FORMAT_ALPHA_INT32; + case GL_ALPHA8UI_EXT: + return MESA_FORMAT_ALPHA_UINT8; + case GL_ALPHA16UI_EXT: + return MESA_FORMAT_ALPHA_UINT16; + case GL_ALPHA32UI_EXT: + return MESA_FORMAT_ALPHA_UINT32; + case GL_LUMINANCE8: + return MESA_FORMAT_L8; + case GL_LUMINANCE16: + return MESA_FORMAT_L16; + case GL_LUMINANCE16F_ARB: + return MESA_FORMAT_LUMINANCE_FLOAT16; + case GL_LUMINANCE32F_ARB: + return MESA_FORMAT_LUMINANCE_FLOAT32; + case GL_LUMINANCE8I_EXT: + return MESA_FORMAT_LUMINANCE_INT8; + case GL_LUMINANCE16I_EXT: + return MESA_FORMAT_LUMINANCE_INT16; + case GL_LUMINANCE32I_EXT: + return MESA_FORMAT_LUMINANCE_INT32; + case GL_LUMINANCE8UI_EXT: + return MESA_FORMAT_LUMINANCE_UINT8; + case GL_LUMINANCE16UI_EXT: + return MESA_FORMAT_LUMINANCE_UINT16; + case GL_LUMINANCE32UI_EXT: + return MESA_FORMAT_LUMINANCE_UINT32; + case GL_LUMINANCE8_ALPHA8: + return MESA_FORMAT_AL88; + case GL_LUMINANCE16_ALPHA16: + return MESA_FORMAT_AL1616; + case GL_LUMINANCE_ALPHA16F_ARB: + return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; + case GL_LUMINANCE_ALPHA32F_ARB: + return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; + case GL_LUMINANCE_ALPHA8I_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_INT8; + case GL_LUMINANCE_ALPHA16I_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_INT8; + case GL_LUMINANCE_ALPHA32I_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_INT16; + case GL_LUMINANCE_ALPHA8UI_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_UINT8; + case GL_LUMINANCE_ALPHA16UI_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_UINT16; + case GL_LUMINANCE_ALPHA32UI_EXT: + return MESA_FORMAT_LUMINANCE_ALPHA_UINT32; + case GL_INTENSITY8: + return MESA_FORMAT_I8; + case GL_INTENSITY16: + return MESA_FORMAT_I16; + case GL_INTENSITY16F_ARB: + return MESA_FORMAT_INTENSITY_FLOAT16; + case GL_INTENSITY32F_ARB: + return MESA_FORMAT_INTENSITY_FLOAT32; + case GL_INTENSITY8I_EXT: + return MESA_FORMAT_INTENSITY_INT8; + case GL_INTENSITY16I_EXT: + return MESA_FORMAT_INTENSITY_INT16; + case GL_INTENSITY32I_EXT: + return MESA_FORMAT_INTENSITY_INT32; + case GL_INTENSITY8UI_EXT: + return MESA_FORMAT_INTENSITY_UINT8; + case GL_INTENSITY16UI_EXT: + return MESA_FORMAT_INTENSITY_UINT16; + case GL_INTENSITY32UI_EXT: + return MESA_FORMAT_INTENSITY_UINT32; + default: + break; + } + } + + if (ctx->API == API_OPENGL_CORE && + ctx->Extensions.ARB_texture_buffer_object_rgb32) { + switch (internalFormat) { + case GL_RGB32F: + return MESA_FORMAT_RGB_FLOAT32; + case GL_RGB32UI: + return MESA_FORMAT_RGB_UINT32; + case GL_RGB32I: + return MESA_FORMAT_RGB_INT32; + default: + break; + } + } + switch (internalFormat) { - case GL_ALPHA8: - return MESA_FORMAT_A8; - case GL_ALPHA16: - return MESA_FORMAT_A16; - case GL_ALPHA16F_ARB: - return MESA_FORMAT_ALPHA_FLOAT16; - case GL_ALPHA32F_ARB: - return MESA_FORMAT_ALPHA_FLOAT32; - case GL_ALPHA8I_EXT: - return MESA_FORMAT_ALPHA_INT8; - case GL_ALPHA16I_EXT: - return MESA_FORMAT_ALPHA_INT16; - case GL_ALPHA32I_EXT: - return MESA_FORMAT_ALPHA_INT32; - case GL_ALPHA8UI_EXT: - return MESA_FORMAT_ALPHA_UINT8; - case GL_ALPHA16UI_EXT: - return MESA_FORMAT_ALPHA_UINT16; - case GL_ALPHA32UI_EXT: - return MESA_FORMAT_ALPHA_UINT32; - case GL_LUMINANCE8: - return MESA_FORMAT_L8; - case GL_LUMINANCE16: - return MESA_FORMAT_L16; - case GL_LUMINANCE16F_ARB: - return MESA_FORMAT_LUMINANCE_FLOAT16; - case GL_LUMINANCE32F_ARB: - return MESA_FORMAT_LUMINANCE_FLOAT32; - case GL_LUMINANCE8I_EXT: - return MESA_FORMAT_LUMINANCE_INT8; - case GL_LUMINANCE16I_EXT: - return MESA_FORMAT_LUMINANCE_INT16; - case GL_LUMINANCE32I_EXT: - return MESA_FORMAT_LUMINANCE_INT32; - case GL_LUMINANCE8UI_EXT: - return MESA_FORMAT_LUMINANCE_UINT8; - case GL_LUMINANCE16UI_EXT: - return MESA_FORMAT_LUMINANCE_UINT16; - case GL_LUMINANCE32UI_EXT: - return MESA_FORMAT_LUMINANCE_UINT32; - case GL_LUMINANCE8_ALPHA8: - return MESA_FORMAT_AL88; - case GL_LUMINANCE16_ALPHA16: - return MESA_FORMAT_AL1616; - case GL_LUMINANCE_ALPHA16F_ARB: - return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; - case GL_LUMINANCE_ALPHA32F_ARB: - return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; - case GL_LUMINANCE_ALPHA8I_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_INT8; - case GL_LUMINANCE_ALPHA16I_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_INT8; - case GL_LUMINANCE_ALPHA32I_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_INT16; - case GL_LUMINANCE_ALPHA8UI_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_UINT8; - case GL_LUMINANCE_ALPHA16UI_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_UINT16; - case GL_LUMINANCE_ALPHA32UI_EXT: - return MESA_FORMAT_LUMINANCE_ALPHA_UINT32; - case GL_INTENSITY8: - return MESA_FORMAT_I8; - case GL_INTENSITY16: - return MESA_FORMAT_I16; - case GL_INTENSITY16F_ARB: - return MESA_FORMAT_INTENSITY_FLOAT16; - case GL_INTENSITY32F_ARB: - return MESA_FORMAT_INTENSITY_FLOAT32; - case GL_INTENSITY8I_EXT: - return MESA_FORMAT_INTENSITY_INT8; - case GL_INTENSITY16I_EXT: - return MESA_FORMAT_INTENSITY_INT16; - case GL_INTENSITY32I_EXT: - return MESA_FORMAT_INTENSITY_INT32; - case GL_INTENSITY8UI_EXT: - return MESA_FORMAT_INTENSITY_UINT8; - case GL_INTENSITY16UI_EXT: - return MESA_FORMAT_INTENSITY_UINT16; - case GL_INTENSITY32UI_EXT: - return MESA_FORMAT_INTENSITY_UINT32; case GL_RGBA8: return MESA_FORMAT_RGBA8888_REV; case GL_RGBA16: @@ -4036,21 +4043,15 @@ get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) case GL_R32UI: return MESA_FORMAT_R_UINT32; - case GL_RGB32F: - return MESA_FORMAT_RGB_FLOAT32; - case GL_RGB32UI: - return MESA_FORMAT_RGB_UINT32; - case GL_RGB32I: - return MESA_FORMAT_RGB_INT32; - default: return MESA_FORMAT_NONE; } } -static gl_format -validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) +gl_format +_mesa_validate_texbuffer_format(const struct gl_context *ctx, + GLenum internalFormat) { gl_format format = get_texbuffer_format(ctx, internalFormat); GLenum datatype; @@ -4065,15 +4066,10 @@ validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel) return MESA_FORMAT_NONE; - /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make - * any mention of R/RG formats, but they appear in the GL 3.1 core - * specification. - */ - if (ctx->Version <= 30) { + if (!ctx->Extensions.ARB_texture_rg) { GLenum base_format = _mesa_get_format_base_format(format); - if (base_format == GL_R || base_format == GL_RG) - return MESA_FORMAT_NONE; + return MESA_FORMAT_NONE; } if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) { @@ -4100,7 +4096,7 @@ texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat, return; } - format = validate_texbuffer_format(ctx, internalFormat); + format = _mesa_validate_texbuffer_format(ctx, internalFormat); if (format == MESA_FORMAT_NONE) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", internalFormat); @@ -4348,6 +4344,11 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, } texObj->Immutable = immutable; + + if (immutable) { + _mesa_set_texture_view_state(ctx, texObj, target, 1); + } + _mesa_update_fbo_texture(ctx, texObj, 0, 0); } } diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 792383d2f..0b5786340 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -147,6 +147,10 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, GLint level, GLint width, GLint height, GLint depth, GLint border); +extern gl_format +_mesa_validate_texbuffer_format(const struct gl_context *ctx, + GLenum internalFormat); + /** * Lock a texture for updating. See also _mesa_lock_context_textures(). */ diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index abd30c563..d6510fefd 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -552,7 +552,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->_MaxLevel = MIN3(t->MaxLevel, /* 'p' in the GL spec */ - baseLevel + baseImage->MaxNumLevels - 1, + (int) (baseLevel + baseImage->MaxNumLevels - 1), /* 'q' in the GL spec */ maxLevels - 1); @@ -889,6 +889,8 @@ count_tex_size(GLuint key, void *data, void *userData) (const struct gl_texture_object *) data; GLuint *total = (GLuint *) userData; + (void) key; + *total = *total + texture_size(texObj); } @@ -1171,7 +1173,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) * \return TEXTURE_x_INDEX or -1 if target is invalid */ static GLint -target_enum_to_index(struct gl_context *ctx, GLenum target) +target_enum_to_index(const struct gl_context *ctx, GLenum target) { switch (target) { case GL_TEXTURE_1D: @@ -1179,25 +1181,21 @@ target_enum_to_index(struct gl_context *ctx, GLenum target) case GL_TEXTURE_2D: return TEXTURE_2D_INDEX; case GL_TEXTURE_3D: - return TEXTURE_3D_INDEX; - case GL_TEXTURE_CUBE_MAP_ARB: + return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1; + case GL_TEXTURE_CUBE_MAP: return ctx->Extensions.ARB_texture_cube_map ? TEXTURE_CUBE_INDEX : -1; - case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_RECTANGLE: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle ? TEXTURE_RECT_INDEX : -1; - case GL_TEXTURE_1D_ARRAY_EXT: - return _mesa_is_desktop_gl(ctx) - && (ctx->Extensions.EXT_texture_array - || ctx->Extensions.MESA_texture_array) + case GL_TEXTURE_1D_ARRAY: + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array ? TEXTURE_1D_ARRAY_INDEX : -1; - case GL_TEXTURE_2D_ARRAY_EXT: - return (_mesa_is_desktop_gl(ctx) - && (ctx->Extensions.EXT_texture_array - || ctx->Extensions.MESA_texture_array)) + case GL_TEXTURE_2D_ARRAY: + return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) || _mesa_is_gles3(ctx) ? TEXTURE_2D_ARRAY_INDEX : -1; - case GL_TEXTURE_BUFFER_ARB: + case GL_TEXTURE_BUFFER: return ctx->API == API_OPENGL_CORE && ctx->Extensions.ARB_texture_buffer_object ? TEXTURE_BUFFER_INDEX : -1; @@ -1205,7 +1203,8 @@ target_enum_to_index(struct gl_context *ctx, GLenum target) return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external ? TEXTURE_EXTERNAL_INDEX : -1; case GL_TEXTURE_CUBE_MAP_ARRAY: - return TEXTURE_CUBE_ARRAY_INDEX; + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_cube_map_array + ? TEXTURE_CUBE_ARRAY_INDEX : -1; case GL_TEXTURE_2D_MULTISAMPLE: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample ? TEXTURE_2D_MULTISAMPLE_INDEX: -1; diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 7092c630b..94e498d20 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -158,16 +158,13 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) } break; case GL_TEXTURE_1D_ARRAY_EXT: - if (_mesa_is_desktop_gl(ctx) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array)) { + if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) { return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX]; } break; case GL_TEXTURE_2D_ARRAY_EXT: if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) - && (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array)) { + && ctx->Extensions.EXT_texture_array) { return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX]; } break; @@ -1046,8 +1043,7 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) case GL_PROXY_TEXTURE_1D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_BUFFER: /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts, * but not in earlier versions that expose ARB_texture_buffer_object. @@ -1166,10 +1162,7 @@ get_tex_level_parameter_image(struct gl_context *ctx, goto invalid_pname; *params = _mesa_get_format_bits(texFormat, pname); break; - case GL_TEXTURE_STENCIL_SIZE_EXT: - if (!ctx->Extensions.EXT_packed_depth_stencil && - !ctx->Extensions.ARB_framebuffer_object) - goto invalid_pname; + case GL_TEXTURE_STENCIL_SIZE: *params = _mesa_get_format_bits(texFormat, pname); break; case GL_TEXTURE_SHARED_SIZE: @@ -1562,9 +1555,35 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) break; case GL_TEXTURE_IMMUTABLE_LEVELS: - if (!_mesa_is_gles3(ctx)) + if (_mesa_is_gles3(ctx) || + (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) + *params = (GLfloat) obj->ImmutableLevels; + else goto invalid_pname; - *params = (GLfloat) obj->ImmutableLevels; + break; + + case GL_TEXTURE_VIEW_MIN_LEVEL: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLfloat) obj->MinLevel; + break; + + case GL_TEXTURE_VIEW_NUM_LEVELS: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLfloat) obj->NumLevels; + break; + + case GL_TEXTURE_VIEW_MIN_LAYER: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLfloat) obj->MinLayer; + break; + + case GL_TEXTURE_VIEW_NUM_LAYERS: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLfloat) obj->NumLayers; break; case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: @@ -1746,9 +1765,35 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) break; case GL_TEXTURE_IMMUTABLE_LEVELS: - if (!_mesa_is_gles3(ctx)) + if (_mesa_is_gles3(ctx) || + (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) + *params = obj->ImmutableLevels; + else + goto invalid_pname; + break; + + case GL_TEXTURE_VIEW_MIN_LEVEL: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLint) obj->MinLevel; + break; + + case GL_TEXTURE_VIEW_NUM_LEVELS: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLint) obj->NumLevels; + break; + + case GL_TEXTURE_VIEW_MIN_LAYER: + if (!ctx->Extensions.ARB_texture_view) + goto invalid_pname; + *params = (GLint) obj->MinLayer; + break; + + case GL_TEXTURE_VIEW_NUM_LAYERS: + if (!ctx->Extensions.ARB_texture_view) goto invalid_pname; - *params = obj->ImmutableLevels; + *params = (GLint) obj->NumLayers; break; case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 84b8f8224..5062fdb4f 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -37,7 +37,9 @@ #include "macros.h" #include "teximage.h" #include "texobj.h" +#include "mipmap.h" #include "texstorage.h" +#include "textureview.h" #include "mtypes.h" @@ -73,8 +75,7 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) return ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY: case GL_PROXY_TEXTURE_1D_ARRAY: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return ctx->Extensions.EXT_texture_array; default: return GL_FALSE; } @@ -85,8 +86,7 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) return GL_TRUE; case GL_TEXTURE_2D_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY: - return (ctx->Extensions.MESA_texture_array || - ctx->Extensions.EXT_texture_array); + return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; @@ -100,27 +100,6 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) } -/** - * Compute the size of the next mipmap level. - */ -static void -next_mipmap_level_size(GLenum target, - GLint *width, GLint *height, GLint *depth) -{ - if (*width > 1) { - *width /= 2; - } - - if ((*height > 1) && (target != GL_TEXTURE_1D_ARRAY)) { - *height /= 2; - } - - if ((*depth > 1) && (target != GL_TEXTURE_2D_ARRAY)) { - *depth /= 2; - } -} - - /** Helper to get a particular texture image in a texture object */ static struct gl_texture_image * get_tex_image(struct gl_context *ctx, @@ -164,7 +143,8 @@ initialize_texture_fields(struct gl_context *ctx, 0, internalFormat, texFormat); } - next_mipmap_level_size(target, &levelWidth, &levelHeight, &levelDepth); + _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth, + &levelWidth, &levelHeight, &levelDepth); } return GL_TRUE; } @@ -436,8 +416,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, return; } - texObj->Immutable = GL_TRUE; - texObj->ImmutableLevels = levels; + _mesa_set_texture_view_state(ctx, texObj, target, levels); + } } diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 76d8d9ba3..5adbd5dc9 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -3864,6 +3864,7 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS) /** * Store user data into texture memory. * Called via glTex[Sub]Image1/2/3D() + * \return GL_TRUE for success, GL_FALSE for failure (out of memory). */ GLboolean _mesa_texstore(TEXSTORE_PARAMS) diff --git a/mesalib/src/mesa/main/textureview.c b/mesalib/src/mesa/main/textureview.c new file mode 100644 index 000000000..5f88a4171 --- /dev/null +++ b/mesalib/src/mesa/main/textureview.c @@ -0,0 +1,668 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2013 LunarG, Inc. + * + * 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. + * + * Authors: + * Courtney Goeltzenleuchter <courtney@lunarg.com> + */ + + +/** + * \file textureview.c + * GL_ARB_texture_view functions + */ + +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "imports.h" +#include "macros.h" +#include "teximage.h" +#include "texobj.h" +#include "mipmap.h" +#include "texstorage.h" +#include "textureview.h" +#include "stdbool.h" +#include "mtypes.h" + +/* Table 3.X.2 (Compatible internal formats for TextureView) + --------------------------------------------------------------------------- + | Class | Internal formats | + --------------------------------------------------------------------------- + | VIEW_CLASS_128_BITS | RGBA32F, RGBA32UI, RGBA32I | + --------------------------------------------------------------------------- + | VIEW_CLASS_96_BITS | RGB32F, RGB32UI, RGB32I | + --------------------------------------------------------------------------- + | VIEW_CLASS_64_BITS | RGBA16F, RG32F, RGBA16UI, RG32UI, RGBA16I, | + | | RG32I, RGBA16, RGBA16_SNORM | + --------------------------------------------------------------------------- + | VIEW_CLASS_48_BITS | RGB16, RGB16_SNORM, RGB16F, RGB16UI, RGB16I | + --------------------------------------------------------------------------- + | VIEW_CLASS_32_BITS | RG16F, R11F_G11F_B10F, R32F, | + | | RGB10_A2UI, RGBA8UI, RG16UI, R32UI, | + | | RGBA8I, RG16I, R32I, RGB10_A2, RGBA8, RG16, | + | | RGBA8_SNORM, RG16_SNORM, SRGB8_ALPHA8, RGB9_E5 | + --------------------------------------------------------------------------- + | VIEW_CLASS_24_BITS | RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I | + --------------------------------------------------------------------------- + | VIEW_CLASS_16_BITS | R16F, RG8UI, R16UI, RG8I, R16I, RG8, R16, | + | | RG8_SNORM, R16_SNORM | + --------------------------------------------------------------------------- + | VIEW_CLASS_8_BITS | R8UI, R8I, R8, R8_SNORM | + --------------------------------------------------------------------------- + | VIEW_CLASS_RGTC1_RED | COMPRESSED_RED_RGTC1, | + | | COMPRESSED_SIGNED_RED_RGTC1 | + --------------------------------------------------------------------------- + | VIEW_CLASS_RGTC2_RG | COMPRESSED_RG_RGTC2, | + | | COMPRESSED_SIGNED_RG_RGTC2 | + --------------------------------------------------------------------------- + | VIEW_CLASS_BPTC_UNORM | COMPRESSED_RGBA_BPTC_UNORM, | + | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM | + --------------------------------------------------------------------------- + | VIEW_CLASS_BPTC_FLOAT | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, | + | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT | + --------------------------------------------------------------------------- + */ +struct internal_format_class_info { + GLenum view_class; + GLenum internal_format; +}; +static const struct internal_format_class_info compatible_internal_formats[] = { + {GL_VIEW_CLASS_128_BITS, GL_RGBA32F}, + {GL_VIEW_CLASS_128_BITS, GL_RGBA32UI}, + {GL_VIEW_CLASS_128_BITS, GL_RGBA32I}, + {GL_VIEW_CLASS_96_BITS, GL_RGB32F}, + {GL_VIEW_CLASS_96_BITS, GL_RGB32UI}, + {GL_VIEW_CLASS_96_BITS, GL_RGB32I}, + {GL_VIEW_CLASS_64_BITS, GL_RGBA16F}, + {GL_VIEW_CLASS_64_BITS, GL_RG32F}, + {GL_VIEW_CLASS_64_BITS, GL_RGBA16UI}, + {GL_VIEW_CLASS_64_BITS, GL_RG32UI}, + {GL_VIEW_CLASS_64_BITS, GL_RGBA16I}, + {GL_VIEW_CLASS_64_BITS, GL_RG32I}, + {GL_VIEW_CLASS_64_BITS, GL_RGBA16}, + {GL_VIEW_CLASS_64_BITS, GL_RGBA16_SNORM}, + {GL_VIEW_CLASS_48_BITS, GL_RGB16}, + {GL_VIEW_CLASS_48_BITS, GL_RGB16_SNORM}, + {GL_VIEW_CLASS_48_BITS, GL_RGB16F}, + {GL_VIEW_CLASS_48_BITS, GL_RGB16UI}, + {GL_VIEW_CLASS_48_BITS, GL_RGB16I}, + {GL_VIEW_CLASS_32_BITS, GL_RG16F}, + {GL_VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F}, + {GL_VIEW_CLASS_32_BITS, GL_R32F}, + {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2UI}, + {GL_VIEW_CLASS_32_BITS, GL_RGBA8UI}, + {GL_VIEW_CLASS_32_BITS, GL_RG16UI}, + {GL_VIEW_CLASS_32_BITS, GL_R32UI}, + {GL_VIEW_CLASS_32_BITS, GL_RGBA8I}, + {GL_VIEW_CLASS_32_BITS, GL_RG16I}, + {GL_VIEW_CLASS_32_BITS, GL_R32I}, + {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2}, + {GL_VIEW_CLASS_32_BITS, GL_RGBA8}, + {GL_VIEW_CLASS_32_BITS, GL_RG16}, + {GL_VIEW_CLASS_32_BITS, GL_RGBA8_SNORM}, + {GL_VIEW_CLASS_32_BITS, GL_RG16_SNORM}, + {GL_VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8}, + {GL_VIEW_CLASS_32_BITS, GL_RGB9_E5}, + {GL_VIEW_CLASS_24_BITS, GL_RGB8}, + {GL_VIEW_CLASS_24_BITS, GL_RGB8_SNORM}, + {GL_VIEW_CLASS_24_BITS, GL_SRGB8}, + {GL_VIEW_CLASS_24_BITS, GL_RGB8UI}, + {GL_VIEW_CLASS_24_BITS, GL_RGB8I}, + {GL_VIEW_CLASS_16_BITS, GL_R16F}, + {GL_VIEW_CLASS_16_BITS, GL_RG8UI}, + {GL_VIEW_CLASS_16_BITS, GL_R16UI}, + {GL_VIEW_CLASS_16_BITS, GL_RG8I}, + {GL_VIEW_CLASS_16_BITS, GL_R16I}, + {GL_VIEW_CLASS_16_BITS, GL_RG8}, + {GL_VIEW_CLASS_16_BITS, GL_R16}, + {GL_VIEW_CLASS_16_BITS, GL_RG8_SNORM}, + {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM}, + {GL_VIEW_CLASS_8_BITS, GL_R8UI}, + {GL_VIEW_CLASS_8_BITS, GL_R8I}, + {GL_VIEW_CLASS_8_BITS, GL_R8}, + {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM}, + {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1}, + {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1}, + {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2}, + {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2}, + {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB}, + {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB}, + {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB}, + {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB}, +}; + +static const struct internal_format_class_info s3tc_compatible_internal_formats[] = { + {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT}, + {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}, + {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, + {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, + {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, + {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, + {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, + {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, +}; + +/** + * Lookup format view class based on internalformat + * \return VIEW_CLASS if internalformat found in table, false otherwise. + */ +static GLenum +lookup_view_class(struct gl_context *ctx, GLenum internalformat) +{ + GLuint i; + + for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) { + if (compatible_internal_formats[i].internal_format == internalformat) + return compatible_internal_formats[i].view_class; + } + + if (ctx->Extensions.EXT_texture_compression_s3tc && ctx->Extensions.EXT_texture_sRGB) { + for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) { + if (s3tc_compatible_internal_formats[i].internal_format == internalformat) + return s3tc_compatible_internal_formats[i].view_class; + } + } + return GL_FALSE; +} + +/** + * Initialize new texture's gl_texture_image structures. Will not call driver + * to allocate new space, simply record relevant layer, face, format, etc. + * \return GL_FALSE if any error, GL_TRUE otherwise. + */ +static GLboolean +initialize_texture_fields(struct gl_context *ctx, + GLenum target, + struct gl_texture_object *texObj, + GLint levels, + GLsizei width, GLsizei height, GLsizei depth, + GLenum internalFormat, gl_format texFormat) +{ + const GLuint numFaces = _mesa_num_tex_faces(target); + GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; + GLuint face; + + /* Pretend we are bound to initialize the gl_texture_image structs */ + texObj->Target = target; + + /* Set up all the texture object's gl_texture_images */ + for (level = 0; level < levels; level++) { + for (face = 0; face < numFaces; face++) { + struct gl_texture_image *texImage; + GLenum faceTarget = target; + + if (target == GL_TEXTURE_CUBE_MAP) + faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + + texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level); + + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); + return GL_FALSE; + } + + _mesa_init_teximage_fields(ctx, texImage, + levelWidth, levelHeight, levelDepth, + 0, internalFormat, texFormat); + } + + _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth, + &levelWidth, &levelHeight, &levelDepth); + } + + /* "unbind" */ + texObj->Target = 0; + + return GL_TRUE; +} + +#define RETURN_IF_SUPPORTED(t) do { \ + if (newTarget == GL_ ## t) \ + return true; \ +} while (0) + +/** + * Check for compatible target + * If an error is found, record it with _mesa_error() + * \return false if any error, true otherwise. + */ +static bool +target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget) +{ + /* + * From ARB_texture_view spec: + --------------------------------------------------------------------------------------------------------- + | Original target | Valid new targets | + --------------------------------------------------------------------------------------------------------- + | TEXTURE_1D | TEXTURE_1D, TEXTURE_1D_ARRAY | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_2D | TEXTURE_2D, TEXTURE_2D_ARRAY | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_3D | TEXTURE_3D | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_CUBE_MAP | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_RECTANGLE | TEXTURE_RECTANGLE | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_BUFFER | <none> | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_1D_ARRAY | TEXTURE_1D_ARRAY, TEXTURE_1D | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_2D_ARRAY | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_CUBE_MAP_ARRAY | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_2D_MULTISAMPLE | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | + | ------------------------------------------------------------------------------------------------------- | + | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | + --------------------------------------------------------------------------------------------------------- + */ + + switch (origTarget) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + RETURN_IF_SUPPORTED(TEXTURE_1D); + RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY); + break; + case GL_TEXTURE_2D: + RETURN_IF_SUPPORTED(TEXTURE_2D); + RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); + break; + case GL_TEXTURE_3D: + RETURN_IF_SUPPORTED(TEXTURE_3D); + break; + case GL_TEXTURE_RECTANGLE: + RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE); + break; + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + RETURN_IF_SUPPORTED(TEXTURE_2D); + RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); + RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP); + RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY); + break; + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE); + RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY); + break; + } + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureView(illegal target=%s)", + _mesa_lookup_enum_by_nr(newTarget)); + return false; +} +#undef RETURN_IF_SUPPORTED + +/** + * Check for compatible format + * If an error is found, record it with _mesa_error() + * \return false if any error, true otherwise. + */ +static bool +compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTexObj, + GLenum internalformat) +{ + /* Level 0 of a texture created by glTextureStorage or glTextureView + * is always defined. + */ + struct gl_texture_image *texImage = origTexObj->Image[0][0]; + GLint origInternalFormat = texImage->InternalFormat; + unsigned int origViewClass, newViewClass; + + /* The two textures' internal formats must be compatible according to + * Table 3.X.2 (Compatible internal formats for TextureView) + * if the internal format exists in that table the view class must match. + * The internal formats must be identical if not in that table, + * or an INVALID_OPERATION error is generated. + */ + if (origInternalFormat == internalformat) + return true; + + origViewClass = lookup_view_class(ctx, origInternalFormat); + newViewClass = lookup_view_class(ctx, internalformat); + if ((origViewClass == newViewClass) && origViewClass != false) + return true; + + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureView(internalformat %s not compatible with origtexture %s)", + _mesa_lookup_enum_by_nr(internalformat), + _mesa_lookup_enum_by_nr(origInternalFormat)); + return false; +} +/** + * Helper function for TexStorage and teximagemultisample to set immutable + * texture state needed by ARB_texture_view. + */ +void +_mesa_set_texture_view_state(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target, GLuint levels) +{ + struct gl_texture_image *texImage; + + /* Get a reference to what will become this View's base level */ + texImage = _mesa_select_tex_image(ctx, texObj, target, 0); + + /* When an immutable texture is created via glTexStorage or glTexImageMultisample, + * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. + * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels. + * If the texture target is TEXTURE_1D_ARRAY then + * TEXTURE_VIEW_NUM_LAYERS becomes height. + * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, + * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes depth. + * If the texture target is TEXTURE_CUBE_MAP, then + * TEXTURE_VIEW_NUM_LAYERS becomes 6. + * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1. + * + * ARB_texture_multisample: Multisample textures do + * not have multiple image levels. + */ + + texObj->Immutable = GL_TRUE; + texObj->ImmutableLevels = levels; + texObj->MinLevel = 0; + texObj->NumLevels = levels; + texObj->MinLayer = 0; + texObj->NumLayers = 1; + switch (target) { + case GL_TEXTURE_1D_ARRAY: + texObj->NumLayers = texImage->Height; + break; + + case GL_TEXTURE_2D_MULTISAMPLE: + texObj->NumLevels = 1; + texObj->ImmutableLevels = 1; + break; + + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + texObj->NumLevels = 1; + texObj->ImmutableLevels = 1; + /* fall through to set NumLayers */ + + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + texObj->NumLayers = texImage->Depth; + break; + + case GL_TEXTURE_CUBE_MAP: + texObj->NumLayers = 6; + break; + + } +} + +/** + * glTextureView (ARB_texture_view) + * If an error is found, record it with _mesa_error() + * \return none. + */ +void GLAPIENTRY +_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, + GLuint minlevel, GLuint numlevels, + GLuint minlayer, GLuint numlayers) +{ + struct gl_texture_object *texObj; + struct gl_texture_object *origTexObj; + struct gl_texture_image *origTexImage; + GLuint newViewMinLevel, newViewMinLayer; + GLuint newViewNumLevels, newViewNumLayers; + GLsizei width, height, depth; + gl_format texFormat; + GLboolean sizeOK, dimensionsOK; + GLenum faceTarget; + + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n", + texture, _mesa_lookup_enum_by_nr(target), origtexture, + _mesa_lookup_enum_by_nr(internalformat), + minlevel, numlevels, minlayer, numlayers); + + if (origtexture == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture); + return; + } + + /* Need original texture information to validate arguments */ + origTexObj = _mesa_lookup_texture(ctx, origtexture); + + /* If <origtexture> is not the name of a texture, INVALID_VALUE is generated. */ + if (!origTexObj) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture); + return; + } + + /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE, + * INVALID_OPERATION is generated. + */ + if (!origTexObj->Immutable) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture not immutable)"); + return; + } + + /* If <texture> is 0, INVALID_VALUE is generated. */ + if (texture == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)"); + return; + } + + /* If <texture> is not a valid name returned by GenTextures, + * the error INVALID_OPERATION is generated. + */ + texObj = _mesa_lookup_texture(ctx, texture); + if (texObj == NULL) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u non-gen name)", texture); + return; + } + + /* If <texture> has already been bound and given a target, then + * the error INVALID_OPERATION is generated. + */ + if (texObj->Target) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u already bound)", texture); + return; + } + + /* Check for compatible target */ + if (!target_valid(ctx, origTexObj->Target, target)) { + return; /* error was recorded */ + } + + /* minlevel and minlayer are relative to the view of origtexture + * If minlevel or minlayer is greater than level or layer, respectively, + * of origtexture return INVALID_VALUE. + */ + newViewMinLevel = origTexObj->MinLevel + minlevel; + newViewMinLayer = origTexObj->MinLayer + minlayer; + if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTextureView(new minlevel (%d) > orig minlevel (%d) + orig numlevels (%d))", + newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels); + return; + } + + if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTextureView(new minlayer (%d) > orig minlayer (%d) + orig numlayers (%d))", + newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers); + return; + } + + if (!compatible_format(ctx, origTexObj, internalformat)) { + return; /* Error logged */ + } + + texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, + internalformat, GL_NONE, GL_NONE); + assert(texFormat != MESA_FORMAT_NONE); + if (texFormat == MESA_FORMAT_NONE) return; + + newViewNumLevels = MIN2(numlevels, origTexObj->NumLevels - minlevel); + newViewNumLayers = MIN2(numlayers, origTexObj->NumLayers - minlayer); + + faceTarget = origTexObj->Target; + if (faceTarget == GL_TEXTURE_CUBE_MAP) + faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + minlayer; + + /* Get a reference to what will become this View's base level */ + origTexImage = _mesa_select_tex_image(ctx, origTexObj, + faceTarget, minlevel); + width = origTexImage->Width; + height = origTexImage->Height; + depth = origTexImage->Depth; + + /* Adjust width, height, depth to be appropriate for new target */ + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_3D: + break; + + case GL_TEXTURE_1D_ARRAY: + height = (GLsizei) newViewNumLayers; + break; + + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_CUBE_MAP: + depth = 1; + break; + + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + depth = newViewNumLayers; + break; + } + + /* If the dimensions of the original texture are larger than the maximum + * supported dimensions of the new target, the error INVALID_OPERATION is + * generated. For example, if the original texture has a TEXTURE_2D_ARRAY + * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an error + * will be generated if TextureView is called to create a TEXTURE_CUBE_MAP + * view. + */ + dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, + width, height, depth, 0); + if (!dimensionsOK) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid width or height or depth)"); + return; + } + + sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, + width, height, depth, 0); + if (!sizeOK) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)"); + return; + } + + /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE, + * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error + * INVALID_VALUE is generated. + */ + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_2D_MULTISAMPLE: + if (numlayers != 1) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", numlayers); + return; + } + break; + + case GL_TEXTURE_CUBE_MAP: + /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped <numlayers> + * must be equal to 6. + */ + if (newViewNumLayers != 6) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(clamped numlayers %d != 6)", + newViewNumLayers); + return; + } + break; + + case GL_TEXTURE_CUBE_MAP_ARRAY: + /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY, + * then <numlayers> counts layer-faces rather than layers, + * and the clamped <numlayers> must be a multiple of 6. + * Otherwise, the error INVALID_VALUE is generated. + */ + if ((newViewNumLayers % 6) != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTextureView(clamped numlayers %d is not a multiple of 6)", + newViewNumLayers); + return; + } + break; + } + + /* If the new texture's target is TEXTURE_CUBE_MAP or + * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's + * levels must be equal otherwise the error INVALID_OPERATION is generated. + */ + if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) && + (origTexImage->Width != origTexImage->Height)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture width (%d) != height (%d))", + origTexImage->Width, origTexImage->Height); + return; + } + + /* When the original texture's target is TEXTURE_CUBE_MAP, the layer + * parameters are interpreted in the same order as if it were a + * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces. + */ + + /* If the internal format does not exactly match the internal format of the + * original texture, the contents of the memory are reinterpreted in the + * same manner as for image bindings described in + * section 3.9.20 (Texture Image Loads and Stores). + */ + + /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted + * relative to the view and not relative to the original data store. + */ + + if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels, + width, height, depth, + internalformat, texFormat)) { + return; /* Already recorded error */ + } + + texObj->MinLevel = newViewMinLevel; + texObj->MinLayer = newViewMinLayer; + texObj->NumLevels = newViewNumLevels; + texObj->NumLayers = newViewNumLayers; + texObj->Immutable = GL_TRUE; + texObj->ImmutableLevels = origTexObj->ImmutableLevels; + texObj->Target = target; + + if (ctx->Driver.TextureView != NULL && !ctx->Driver.TextureView(ctx, texObj, origTexObj)) { + return; /* driver recorded error */ + } +} diff --git a/mesalib/src/mesa/main/textureview.h b/mesalib/src/mesa/main/textureview.h new file mode 100644 index 000000000..3088ac193 --- /dev/null +++ b/mesalib/src/mesa/main/textureview.h @@ -0,0 +1,43 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2012-2013 LunarG, Inc. + * + * 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. + * + * Authors: + * Courtney Goeltzenleuchter <courtney@lunarg.com> + */ + + +#ifndef TEXTUREVIEW_H +#define TEXTUREVIEW_H + + +extern void GLAPIENTRY +_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, + GLuint minlevel, GLuint numlevels, + GLuint minlayer, GLuint numlayers); + +extern void +_mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_object *texObj, + GLenum target, GLuint levels); + +#endif /* TEXTUREVIEW_H */ diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 55411faf8..00eeca764 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -224,7 +224,6 @@ compute_version(struct gl_context *ctx) (ctx->Extensions.EXT_stencil_two_side || ctx->Extensions.ATI_separate_stencil)); const GLboolean ver_2_1 = (ver_2_0 && - ctx->Const.GLSLVersion >= 120 && ctx->Extensions.EXT_pixel_buffer_object && ctx->Extensions.EXT_texture_sRGB); const GLboolean ver_3_0 = (ver_2_1 && diff --git a/mesalib/src/mesa/math/m_matrix.c b/mesalib/src/mesa/math/m_matrix.c index 290231527..274f969d2 100644 --- a/mesalib/src/mesa/math/m_matrix.c +++ b/mesalib/src/mesa/math/m_matrix.c @@ -1488,14 +1488,11 @@ _math_matrix_ctr( GLmatrix *m ) void _math_matrix_dtr( GLmatrix *m ) { - if (m->m) { - _mesa_align_free( m->m ); - m->m = NULL; - } - if (m->inv) { - _mesa_align_free( m->inv ); - m->inv = NULL; - } + _mesa_align_free( m->m ); + m->m = NULL; + + _mesa_align_free( m->inv ); + m->inv = NULL; } /*@}*/ diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index c833a12f2..23d479c32 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -681,11 +681,11 @@ ir_to_mesa_visitor::visit(ir_variable *ir) if (strcmp(ir->name, "gl_FragCoord") == 0) { struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - fp->OriginUpperLeft = ir->origin_upper_left; - fp->PixelCenterInteger = ir->pixel_center_integer; + fp->OriginUpperLeft = ir->data.origin_upper_left; + fp->PixelCenterInteger = ir->data.pixel_center_integer; } - if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { + if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { unsigned int i; const ir_state_slot *const slots = ir->state_slots; assert(ir->state_slots != NULL); @@ -759,49 +759,10 @@ ir_to_mesa_visitor::visit(ir_variable *ir) void ir_to_mesa_visitor::visit(ir_loop *ir) { - ir_dereference_variable *counter = NULL; - - if (ir->counter != NULL) - counter = new(mem_ctx) ir_dereference_variable(ir->counter); - - if (ir->from != NULL) { - assert(ir->counter != NULL); - - ir_assignment *a = - new(mem_ctx) ir_assignment(counter, ir->from, NULL); - - a->accept(this); - } - emit(NULL, OPCODE_BGNLOOP); - if (ir->to) { - ir_expression *e = - new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type, - counter, ir->to); - ir_if *if_stmt = new(mem_ctx) ir_if(e); - - ir_loop_jump *brk = - new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break); - - if_stmt->then_instructions.push_tail(brk); - - if_stmt->accept(this); - } - visit_exec_list(&ir->body_instructions, this); - if (ir->increment) { - ir_expression *e = - new(mem_ctx) ir_expression(ir_binop_add, counter->type, - counter, ir->increment); - - ir_assignment *a = - new(mem_ctx) ir_assignment(counter, e, NULL); - - a->accept(this); - } - emit(NULL, OPCODE_ENDLOOP); } @@ -1567,10 +1528,10 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir) ir_variable *var = ir->var; if (!entry) { - switch (var->mode) { + switch (var->data.mode) { case ir_var_uniform: entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, - var->location); + var->data.location); this->variables.push_tail(entry); break; case ir_var_shader_in: @@ -1579,21 +1540,21 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir) * user-assigned generic attributes (glBindVertexLocation), * and user-defined varyings. */ - assert(var->location != -1); + assert(var->data.location != -1); entry = new(mem_ctx) variable_storage(var, PROGRAM_INPUT, - var->location); + var->data.location); break; case ir_var_shader_out: - assert(var->location != -1); + assert(var->data.location != -1); entry = new(mem_ctx) variable_storage(var, PROGRAM_OUTPUT, - var->location); + var->data.location); break; case ir_var_system_value: entry = new(mem_ctx) variable_storage(var, PROGRAM_SYSTEM_VALUE, - var->location); + var->data.location); break; case ir_var_auto: case ir_var_temporary: @@ -2443,7 +2404,7 @@ public: this->idx = -1; this->program_resource_visitor::process(var); - var->location = this->idx; + var->data.location = this->idx; } private: @@ -2538,7 +2499,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program foreach_list(node, sh->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); - if ((var == NULL) || (var->mode != ir_var_uniform) + if ((var == NULL) || (var->data.mode != ir_var_uniform) || var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0)) continue; diff --git a/mesalib/src/mesa/program/prog_parameter.c b/mesalib/src/mesa/program/prog_parameter.c index 4d9cf08d2..54531d255 100644 --- a/mesalib/src/mesa/program/prog_parameter.c +++ b/mesalib/src/mesa/program/prog_parameter.c @@ -83,8 +83,7 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList) free((void *)paramList->Parameters[i].Name); } free(paramList->Parameters); - if (paramList->ParameterValues) - _mesa_align_free(paramList->ParameterValues); + _mesa_align_free(paramList->ParameterValues); free(paramList); } diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c index 01f8c6f11..cdf1c03fa 100644 --- a/mesalib/src/mesa/program/program.c +++ b/mesalib/src/mesa/program/program.c @@ -1049,6 +1049,14 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx, * has no effect." */ if (ctx->Multisample.Enabled) { + /* The ARB_gpu_shader5 specification says: + * + * "Use of the "sample" qualifier on a fragment shader input + * forces per-sample shading" + */ + if (prog->IsSample) + return MAX2(ctx->DrawBuffer->Visual.samples, 1); + if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID | SYSTEM_BIT_SAMPLE_POS)) return MAX2(ctx->DrawBuffer->Visual.samples, 1); diff --git a/mesalib/src/mesa/program/program_parse_extra.c b/mesalib/src/mesa/program/program_parse_extra.c index e8e1912eb..a9e364045 100644 --- a/mesalib/src/mesa/program/program_parse_extra.c +++ b/mesalib/src/mesa/program/program_parse_extra.c @@ -256,15 +256,6 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) return 1; } } - } else if (strncmp(option, "MESA_", 5) == 0) { - option += 5; - - if (strcmp(option, "texture_array") == 0) { - if (state->ctx->Extensions.MESA_texture_array) { - state->option.TexArray = 1; - return 1; - } - } } return 0; diff --git a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c index c752640f4..51f079cda 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c @@ -44,56 +44,6 @@ /** - * When doing GL render to texture, we have to be sure that finalize_texture() - * didn't yank out the pipe_resource that we earlier created a surface for. - * Check for that here and create a new surface if needed. - */ -static void -update_renderbuffer_surface(struct st_context *st, - struct st_renderbuffer *strb) -{ - struct pipe_context *pipe = st->pipe; - struct pipe_resource *resource = strb->rtt ? strb->rtt->pt : strb->texture; - int rtt_width = strb->Base.Width; - int rtt_height = strb->Base.Height; - enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format); - - if (!strb->surface || - strb->surface->texture->nr_samples != strb->Base.NumSamples || - strb->surface->format != format || - strb->surface->texture != resource || - strb->surface->width != rtt_width || - strb->surface->height != rtt_height) { - GLuint level; - /* find matching mipmap level size */ - for (level = 0; level <= resource->last_level; level++) { - if (u_minify(resource->width0, level) == rtt_width && - u_minify(resource->height0, level) == rtt_height) { - struct pipe_surface surf_tmpl; - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - surf_tmpl.format = format; - surf_tmpl.u.tex.level = level; - surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice; - surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice; - - pipe_surface_reference(&strb->surface, NULL); - - strb->surface = pipe->create_surface(pipe, - resource, - &surf_tmpl); -#if 0 - printf("-- alloc new surface %d x %d into tex %p\n", - strb->surface->width, strb->surface->height, - texture); -#endif - break; - } - } - } -} - - -/** * Update framebuffer state (color, depth, stencil, etc. buffers) */ static void @@ -121,10 +71,10 @@ update_framebuffer_state( struct st_context *st ) if (strb) { /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/ - if (strb->rtt || + if (strb->is_rtt || (strb->texture && util_format_is_srgb(strb->texture->format))) { /* rendering to a GL texture, may have to update surface */ - update_renderbuffer_surface(st, strb); + st_update_renderbuffer_surface(st, strb); } if (strb->surface) { @@ -144,9 +94,9 @@ update_framebuffer_state( struct st_context *st ) */ strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer); if (strb) { - if (strb->rtt) { + if (strb->is_rtt) { /* rendering to a GL texture, may have to update surface */ - update_renderbuffer_surface(st, strb); + st_update_renderbuffer_surface(st, strb); } pipe_surface_reference(&framebuffer->zsbuf, strb->surface); } diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c index 302e12981..57670ce25 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c +++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c @@ -130,15 +130,20 @@ convert_sampler(struct st_context *st, struct pipe_sampler_state *sampler, GLuint texUnit) { - struct gl_texture_object *texobj; + const struct gl_texture_object *texobj; struct gl_context *ctx = st->ctx; struct gl_sampler_object *msamp; + const struct gl_texture_image *teximg; + GLenum texBaseFormat; texobj = ctx->Texture.Unit[texUnit]._Current; if (!texobj) { texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX); } + teximg = texobj->Image[0][texobj->BaseLevel]; + texBaseFormat = teximg ? teximg->_BaseFormat : GL_RGBA; + msamp = _mesa_get_samplerobj(ctx, texUnit); memset(sampler, 0, sizeof(*sampler)); @@ -170,21 +175,15 @@ convert_sampler(struct st_context *st, assert(sampler->min_lod <= sampler->max_lod); } + /* For non-black borders... */ if (msamp->BorderColor.ui[0] || msamp->BorderColor.ui[1] || msamp->BorderColor.ui[2] || msamp->BorderColor.ui[3]) { - struct st_texture_object *stobj = st_texture_object(texobj); - struct gl_texture_image *teximg; - GLboolean is_integer = GL_FALSE; + const struct st_texture_object *stobj = st_texture_object_const(texobj); + const GLboolean is_integer = texobj->_IsIntegerFormat; union pipe_color_union border_color; - teximg = texobj->Image[0][texobj->BaseLevel]; - - if (teximg) { - is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat); - } - if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view) { const unsigned char swz[4] = { @@ -196,25 +195,26 @@ convert_sampler(struct st_context *st, st_translate_color(&msamp->BorderColor, &border_color, - teximg ? teximg->_BaseFormat : GL_RGBA, is_integer); + texBaseFormat, is_integer); util_format_apply_color_swizzle(&sampler->border_color, &border_color, swz, is_integer); } else { st_translate_color(&msamp->BorderColor, &sampler->border_color, - teximg ? teximg->_BaseFormat : GL_RGBA, is_integer); + texBaseFormat, is_integer); } } sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ? 0 : (GLuint) msamp->MaxAnisotropy); - /* only care about ARB_shadow, not SGI shadow */ - if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { + /* If sampling a depth texture and using shadow comparison */ + if ((texBaseFormat == GL_DEPTH_COMPONENT || + texBaseFormat == GL_DEPTH_STENCIL) && + msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) { sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; - sampler->compare_func - = st_compare_func_to_pipe(msamp->CompareFunc); + sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc); } sampler->seamless_cube_map = diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 7fa4cbdc4..230ab5449 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -422,6 +422,9 @@ st_bufferobj_validate_usage(struct st_context *st, void st_init_bufferobject_functions(struct dd_function_table *functions) { + /* plug in default driver fallbacks (such as for ClearBufferSubData) */ + _mesa_init_buffer_object_functions(functions); + functions->NewBufferObject = st_bufferobj_alloc; functions->DeleteBuffer = st_bufferobj_free; functions->BufferData = st_bufferobj_data; diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 8da664afb..887e58bd9 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -51,6 +51,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" +#include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" @@ -129,6 +130,26 @@ set_vertex_shader(struct st_context *st) } +static void +set_vertex_shader_layered(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + + if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) || + !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + assert(!"Got layered clear, but the VS layer output is unsupported"); + set_vertex_shader(st); + return; + } + + if (!st->clear.vs_layered) { + st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe); + } + + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered); +} + + /** * Draw a screen-aligned quadrilateral. * Coords are clip coords with y=0=bottom. @@ -136,15 +157,19 @@ set_vertex_shader(struct st_context *st) static void draw_quad(struct st_context *st, float x0, float y0, float x1, float y1, GLfloat z, + unsigned num_instances, const union pipe_color_union *color) { - struct pipe_context *pipe = st->pipe; - struct pipe_resource *vbuf = NULL; - GLuint i, offset; + struct cso_context *cso = st->cso_context; + struct pipe_vertex_buffer vb = {0}; + GLuint i; float (*vertices)[2][4]; /**< vertex pos + color */ + vb.stride = 8 * sizeof(float); + if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), - &offset, &vbuf, (void **) &vertices) != PIPE_OK) { + &vb.buffer_offset, &vb.buffer, + (void **) &vertices) != PIPE_OK) { return; } @@ -174,16 +199,10 @@ draw_quad(struct st_context *st, u_upload_unmap(st->uploader); /* draw */ - util_draw_vertex_buffer(pipe, - st->cso_context, - vbuf, - cso_get_aux_vertex_buffer_slot(st->cso_context), - offset, - PIPE_PRIM_TRIANGLE_FAN, - 4, /* verts */ - 2); /* attribs/vert */ - - pipe_resource_reference(&vbuf, NULL); + cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb); + cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4, + 0, num_instances); + pipe_resource_reference(&vb.buffer, NULL); } @@ -194,8 +213,7 @@ draw_quad(struct st_context *st, * ctx->DrawBuffer->_X/Ymin/max fields. */ static void -clear_with_quad(struct gl_context *ctx, - GLboolean color, GLboolean depth, GLboolean stencil) +clear_with_quad(struct gl_context *ctx, unsigned clear_buffers) { struct st_context *st = st_context(ctx); const struct gl_framebuffer *fb = ctx->DrawBuffer; @@ -205,7 +223,8 @@ clear_with_quad(struct gl_context *ctx, const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f; const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f; const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f; - union pipe_color_union clearColor; + unsigned num_layers = + util_framebuffer_get_num_layers(&st->state.framebuffer); /* printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__, @@ -233,7 +252,7 @@ clear_with_quad(struct gl_context *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - if (color) { + if (clear_buffers & PIPE_CLEAR_COLOR) { int num_buffers = ctx->Extensions.EXT_draw_buffers2 ? ctx->DrawBuffer->_NumColorDrawBuffers : 1; int i; @@ -241,6 +260,9 @@ clear_with_quad(struct gl_context *ctx, blend.independent_blend_enable = num_buffers > 1; for (i = 0; i < num_buffers; i++) { + if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i))) + continue; + if (ctx->Color.ColorMask[i][0]) blend.rt[i].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[i][1]) @@ -261,13 +283,13 @@ clear_with_quad(struct gl_context *ctx, { struct pipe_depth_stencil_alpha_state depth_stencil; memset(&depth_stencil, 0, sizeof(depth_stencil)); - if (depth) { + if (clear_buffers & PIPE_CLEAR_DEPTH) { depth_stencil.depth.enabled = 1; depth_stencil.depth.writemask = 1; depth_stencil.depth.func = PIPE_FUNC_ALWAYS; } - if (stencil) { + if (clear_buffers & PIPE_CLEAR_STENCIL) { struct pipe_stencil_ref stencil_ref; memset(&stencil_ref, 0, sizeof(stencil_ref)); depth_stencil.stencil[0].enabled = 1; @@ -305,21 +327,20 @@ clear_with_quad(struct gl_context *ctx, } set_fragment_shader(st); - set_vertex_shader(st); cso_set_geometry_shader_handle(st->cso_context, NULL); - if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; - GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); + if (num_layers > 1) + set_vertex_shader_layered(st); + else + set_vertex_shader(st); - st_translate_color(&ctx->Color.ClearColor, - &clearColor, - ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - is_integer); - } + /* We can't translate the clear color to the colorbuffer format, + * because different colorbuffers may have different formats. + */ /* draw quad matching scissor rect */ - draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor); + draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers, + (union pipe_color_union*)&ctx->Color.ClearColor); /* Restore pipe state */ cso_restore_blend(st->cso_context); @@ -352,6 +373,19 @@ is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb) /** + * Return if all of the color channels are masked. + */ +static INLINE GLboolean +is_color_disabled(struct gl_context *ctx, int i) +{ + return !ctx->Color.ColorMask[i][0] && + !ctx->Color.ColorMask[i][1] && + !ctx->Color.ColorMask[i][2] && + !ctx->Color.ColorMask[i][3]; +} + + +/** * Return if any of the color channels are masked. */ static INLINE GLboolean @@ -408,11 +442,14 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) if (!strb || !strb->surface) continue; + if (is_color_disabled(ctx, colormask_index)) + continue; + if (is_scissor_enabled(ctx, rb) || is_color_masked(ctx, colormask_index)) - quad_buffers |= PIPE_CLEAR_COLOR; + quad_buffers |= PIPE_CLEAR_COLOR0 << i; else - clear_buffers |= PIPE_CLEAR_COLOR; + clear_buffers |= PIPE_CLEAR_COLOR0 << i; } } } @@ -445,24 +482,13 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) */ if (quad_buffers) { quad_buffers |= clear_buffers; - clear_with_quad(ctx, - quad_buffers & PIPE_CLEAR_COLOR, - quad_buffers & PIPE_CLEAR_DEPTH, - quad_buffers & PIPE_CLEAR_STENCIL); + clear_with_quad(ctx, quad_buffers); } else if (clear_buffers) { - union pipe_color_union clearColor; - - if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; - GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); - - st_translate_color(&ctx->Color.ClearColor, - &clearColor, - ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat, - is_integer); - } - - st->pipe->clear(st->pipe, clear_buffers, &clearColor, + /* We can't translate the clear color to the colorbuffer format, + * because different colorbuffers may have different formats. + */ + st->pipe->clear(st->pipe, clear_buffers, + (union pipe_color_union*)&ctx->Color.ClearColor, ctx->Depth.Clear, ctx->Stencil.Clear); } if (mask & BUFFER_BIT_ACCUM) diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 2ce4728ad..3058dfb5b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -878,7 +878,8 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, } stmap = pipe_transfer_map(pipe, strb->texture, - strb->rtt_level, strb->rtt_face + strb->rtt_slice, + strb->surface->u.tex.level, + strb->surface->u.tex.first_layer, usage, x, y, width, height, &pt); @@ -1263,8 +1264,8 @@ copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, /* map the stencil buffer */ drawMap = pipe_transfer_map(pipe, rbDraw->texture, - rbDraw->rtt_level, - rbDraw->rtt_face + rbDraw->rtt_slice, + rbDraw->surface->u.tex.level, + rbDraw->surface->u.tex.first_layer, usage, dstx, dsty, width, height, &ptDraw); @@ -1422,20 +1423,20 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, memset(&blit, 0, sizeof(blit)); blit.src.resource = rbRead->texture; - blit.src.level = rbRead->rtt_level; + blit.src.level = rbRead->surface->u.tex.level; blit.src.format = rbRead->texture->format; blit.src.box.x = readX; blit.src.box.y = readY; - blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice; + blit.src.box.z = rbRead->surface->u.tex.first_layer; blit.src.box.width = readW; blit.src.box.height = readH; blit.src.box.depth = 1; blit.dst.resource = rbDraw->texture; - blit.dst.level = rbDraw->rtt_level; + blit.dst.level = rbDraw->surface->u.tex.level; blit.dst.format = rbDraw->texture->format; blit.dst.box.x = drawX; blit.dst.box.y = drawY; - blit.dst.box.z = rbDraw->rtt_face + rbDraw->rtt_slice; + blit.dst.box.z = rbDraw->surface->u.tex.first_layer; blit.dst.box.width = drawW; blit.dst.box.height = drawH; blit.dst.box.depth = 1; @@ -1633,11 +1634,11 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, memset(&blit, 0, sizeof(blit)); blit.src.resource = rbRead->texture; - blit.src.level = rbRead->rtt_level; + blit.src.level = rbRead->surface->u.tex.level; blit.src.format = rbRead->texture->format; blit.src.box.x = readX; blit.src.box.y = readY; - blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice; + blit.src.box.z = rbRead->surface->u.tex.first_layer; blit.src.box.width = readW; blit.src.box.height = readH; blit.src.box.depth = 1; diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 20894825f..70baa9965 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -389,6 +389,72 @@ st_bind_framebuffer(struct gl_context *ctx, GLenum target, /** + * Create or update the pipe_surface of a FBO renderbuffer. + * This is usually called after st_finalize_texture. + */ +void +st_update_renderbuffer_surface(struct st_context *st, + struct st_renderbuffer *strb) +{ + struct pipe_context *pipe = st->pipe; + struct pipe_resource *resource = strb->texture; + int rtt_width = strb->Base.Width; + int rtt_height = strb->Base.Height; + int rtt_depth = strb->Base.Depth; + enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : + util_format_linear(resource->format); + unsigned first_layer, last_layer, level; + + if (resource->target == PIPE_TEXTURE_1D_ARRAY) { + rtt_depth = rtt_height; + rtt_height = 1; + } + + /* find matching mipmap level size */ + for (level = 0; level <= resource->last_level; level++) { + if (u_minify(resource->width0, level) == rtt_width && + u_minify(resource->height0, level) == rtt_height && + (resource->target != PIPE_TEXTURE_3D || + u_minify(resource->depth0, level) == rtt_depth)) { + break; + } + } + assert(level <= resource->last_level); + + /* determine the layer bounds */ + if (strb->rtt_layered) { + first_layer = 0; + last_layer = util_max_layer(strb->texture, level); + } + else { + first_layer = + last_layer = strb->rtt_face + strb->rtt_slice; + } + + if (!strb->surface || + strb->surface->texture->nr_samples != strb->Base.NumSamples || + strb->surface->format != format || + strb->surface->texture != resource || + strb->surface->width != rtt_width || + strb->surface->height != rtt_height || + strb->surface->u.tex.level != level || + strb->surface->u.tex.first_layer != first_layer || + strb->surface->u.tex.last_layer != last_layer) { + /* create a new pipe_surface */ + struct pipe_surface surf_tmpl; + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = format; + surf_tmpl.u.tex.level = level; + surf_tmpl.u.tex.first_layer = first_layer; + surf_tmpl.u.tex.last_layer = last_layer; + + pipe_surface_reference(&strb->surface, NULL); + + strb->surface = pipe->create_surface(pipe, resource, &surf_tmpl); + } +} + +/** * Called by ctx->Driver.RenderTexture */ static void @@ -401,8 +467,6 @@ st_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb = att->Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); struct pipe_resource *pt; - struct st_texture_object *stObj; - struct pipe_surface surf_tmpl; if (!st_finalize_texture(ctx, pipe, att->Texture)) return; @@ -410,31 +474,16 @@ st_render_texture(struct gl_context *ctx, pt = st_get_texobj_resource(att->Texture); assert(pt); - /* get the texture for the texture object */ - stObj = st_texture_object(att->Texture); - /* point renderbuffer at texobject */ - strb->rtt = stObj; - strb->rtt_level = att->TextureLevel; + strb->is_rtt = TRUE; strb->rtt_face = att->CubeMapFace; strb->rtt_slice = att->Zoffset; - - pipe_resource_reference( &strb->texture, pt ); + strb->rtt_layered = att->Layered; + pipe_resource_reference(&strb->texture, pt); pipe_surface_release(pipe, &strb->surface); - assert(strb->rtt_level <= strb->texture->last_level); - - /* new surface for rendering into the texture */ - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); - surf_tmpl.format = ctx->Color.sRGBEnabled - ? strb->texture->format : util_format_linear(strb->texture->format); - surf_tmpl.u.tex.level = strb->rtt_level; - surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice; - surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice; - strb->surface = pipe->create_surface(pipe, - strb->texture, - &surf_tmpl); + st_update_renderbuffer_surface(st, strb); strb->Base.Format = st_pipe_format_to_mesa_format(pt->format); @@ -464,7 +513,7 @@ st_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb) if (!strb) return; - strb->rtt = NULL; + strb->is_rtt = FALSE; /* restore previous framebuffer state */ st_invalidate_state(ctx, _NEW_BUFFERS); @@ -706,8 +755,8 @@ st_MapRenderbuffer(struct gl_context *ctx, map = pipe_transfer_map(pipe, strb->texture, - strb->rtt_level, - strb->rtt_face + strb->rtt_slice, + strb->surface->u.tex.level, + strb->surface->u.tex.first_layer, usage, x, y2, w, h, &strb->transfer); if (map) { if (invert) { diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.h b/mesalib/src/mesa/state_tracker/st_cb_fbo.h index f335c371b..88fccc298 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.h +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.h @@ -58,8 +58,10 @@ struct st_renderbuffer boolean software; void *data; - struct st_texture_object *rtt; /**< GL render to texture's texture */ - unsigned rtt_level, rtt_face, rtt_slice; + /* Inputs from Driver.RenderTexture, don't use directly. */ + boolean is_rtt; /**< whether Driver.RenderTexture was called */ + unsigned rtt_face, rtt_slice; + boolean rtt_layered; /**< whether glFramebufferTexture was called */ }; @@ -74,6 +76,10 @@ extern struct gl_renderbuffer * st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw); extern void +st_update_renderbuffer_surface(struct st_context *st, + struct st_renderbuffer *strb); + +extern void st_init_fbo_functions(struct dd_function_table *functions); #endif /* ST_CB_FBO_H */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c index b5df58c03..7547dfd8b 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c @@ -166,7 +166,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, } blit.src.resource = src; - blit.src.level = strb->rtt_level; + blit.src.level = strb->surface->u.tex.level; blit.src.format = src_format; blit.dst.resource = dst; blit.dst.level = 0; @@ -175,7 +175,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, blit.dst.box.x = 0; blit.src.box.y = y; blit.dst.box.y = 0; - blit.src.box.z = strb->rtt_face + strb->rtt_slice; + blit.src.box.z = strb->surface->u.tex.first_layer; blit.dst.box.z = 0; blit.src.box.width = blit.dst.box.width = width; blit.src.box.height = blit.dst.box.height = height; diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index faa9ee3f6..c09f34e37 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -175,10 +175,8 @@ st_FreeTextureImageBuffer(struct gl_context *ctx, pipe_resource_reference(&stImage->pt, NULL); } - if (stImage->TexData) { - _mesa_align_free(stImage->TexData); - stImage->TexData = NULL; - } + _mesa_align_free(stImage->TexData); + stImage->TexData = NULL; } @@ -1156,8 +1154,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, map = pipe_transfer_map(pipe, strb->texture, - strb->rtt_level, - strb->rtt_face + strb->rtt_slice, + strb->surface->u.tex.level, + strb->surface->u.tex.first_layer, PIPE_TRANSFER_READ, srcX, srcY, width, height, &src_trans); diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index ab89b4947..cd0a5ae98 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -178,6 +178,7 @@ struct st_context struct pipe_viewport_state viewport; void *vs; void *fs; + void *vs_layered; } clear; /** used for anything using util_draw_vertex_buffer */ diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index cd10a0c9d..5e4a3b398 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -406,7 +406,6 @@ void st_init_extensions(struct st_context *st) { o(NV_texture_barrier), PIPE_CAP_TEXTURE_BARRIER }, /* GL_NV_point_sprite is not supported by gallium because we don't * support the GL_POINT_SPRITE_R_MODE_NV option. */ - { o(MESA_texture_array), PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS }, { o(OES_standard_derivatives), PIPE_CAP_SM3 }, { o(ARB_texture_cube_map_array), PIPE_CAP_CUBE_MAP_ARRAY }, @@ -444,11 +443,6 @@ void st_init_extensions(struct st_context *st) { { o(ARB_depth_buffer_float) }, { PIPE_FORMAT_Z32_FLOAT, PIPE_FORMAT_Z32_FLOAT_S8X24_UINT } }, - - { { o(EXT_packed_depth_stencil) }, - { PIPE_FORMAT_S8_UINT_Z24_UNORM, - PIPE_FORMAT_Z24_UNORM_S8_UINT }, - GL_TRUE }, /* at least one format must be supported */ }; /* Required: sampler support */ @@ -605,6 +599,13 @@ void st_init_extensions(struct st_context *st) ctx->Const.ForceGLSLVersion = st->options.force_glsl_version; } + /* This extension needs full OpenGL 3.2, but we don't know if that's + * supported at this point. Only check the GLSL version. */ + if (ctx->Const.GLSLVersion >= 150 && + screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER)) { + ctx->Extensions.AMD_vertex_shader_layer = GL_TRUE; + } + if (ctx->Const.GLSLVersion >= 130) { ctx->Const.NativeIntegers = GL_TRUE; ctx->Const.MaxClipPlanes = 8; @@ -758,8 +759,7 @@ void st_init_extensions(struct st_context *st) PIPE_BUFFER, PIPE_BIND_SAMPLER_VIEW); } - if (screen->get_param(screen, PIPE_CAP_MIXED_FRAMEBUFFER_SIZES) && - ctx->Extensions.EXT_packed_depth_stencil) { + if (screen->get_param(screen, PIPE_CAP_MIXED_FRAMEBUFFER_SIZES)) { ctx->Extensions.ARB_framebuffer_object = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index ec2552384..6acf98390 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1854,12 +1854,12 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, * Similarly for texture border colors. */ void -st_translate_color(union gl_color_union *colorIn, +st_translate_color(const union gl_color_union *colorIn, union pipe_color_union *colorOut, GLenum baseFormat, GLboolean is_integer) { if (is_integer) { - int *in = colorIn->i; + const int *in = colorIn->i; int *out = colorOut->i; switch (baseFormat) { @@ -1901,7 +1901,7 @@ st_translate_color(union gl_color_union *colorIn, } } else { - float *in = colorIn->f; + const float *in = colorIn->f; float *out = colorOut->f; switch (baseFormat) { diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index 6e97dcb96..3278748d0 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -73,7 +73,7 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, extern void -st_translate_color(union gl_color_union *colorIn, +st_translate_color(const union gl_color_union *colorIn, union pipe_color_union *colorOut, GLenum baseFormat, GLboolean is_integer); diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index ac95968d6..1331c73dc 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1056,11 +1056,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) if (strcmp(ir->name, "gl_FragCoord") == 0) { struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - fp->OriginUpperLeft = ir->origin_upper_left; - fp->PixelCenterInteger = ir->pixel_center_integer; + fp->OriginUpperLeft = ir->data.origin_upper_left; + fp->PixelCenterInteger = ir->data.pixel_center_integer; } - if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { + if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { unsigned int i; const ir_state_slot *const slots = ir->state_slots; assert(ir->state_slots != NULL); @@ -1137,53 +1137,10 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir) void glsl_to_tgsi_visitor::visit(ir_loop *ir) { - ir_dereference_variable *counter = NULL; - - if (ir->counter != NULL) - counter = new(ir) ir_dereference_variable(ir->counter); - - if (ir->from != NULL) { - assert(ir->counter != NULL); - - ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); - - a->accept(this); - delete a; - } - emit(NULL, TGSI_OPCODE_BGNLOOP); - if (ir->to) { - ir_expression *e = - new(ir) ir_expression(ir->cmp, glsl_type::bool_type, - counter, ir->to); - ir_if *if_stmt = new(ir) ir_if(e); - - ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); - - if_stmt->then_instructions.push_tail(brk); - - if_stmt->accept(this); - - delete if_stmt; - delete e; - delete brk; - } - visit_exec_list(&ir->body_instructions, this); - if (ir->increment) { - ir_expression *e = - new(ir) ir_expression(ir_binop_add, counter->type, - counter, ir->increment); - - ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); - - a->accept(this); - delete a; - delete e; - } - emit(NULL, TGSI_OPCODE_ENDLOOP); } @@ -2063,10 +2020,10 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) ir_variable *var = ir->var; if (!entry) { - switch (var->mode) { + switch (var->data.mode) { case ir_var_uniform: entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, - var->location); + var->data.location); this->variables.push_tail(entry); break; case ir_var_shader_in: @@ -2075,21 +2032,22 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) * generic attributes (glBindVertexLocation), and * user-defined varyings. */ - assert(var->location != -1); + assert(var->data.location != -1); entry = new(mem_ctx) variable_storage(var, PROGRAM_INPUT, - var->location); + var->data.location); break; case ir_var_shader_out: - assert(var->location != -1); + assert(var->data.location != -1); entry = new(mem_ctx) variable_storage(var, PROGRAM_OUTPUT, - var->location + var->index); + var->data.location + + var->data.index); break; case ir_var_system_value: entry = new(mem_ctx) variable_storage(var, PROGRAM_SYSTEM_VALUE, - var->location); + var->data.location); break; case ir_var_auto: case ir_var_temporary: @@ -2388,7 +2346,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir) assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); l.writemask = WRITEMASK_XYZW; } else if (ir->lhs->type->is_scalar() && - ir->lhs->variable_referenced()->mode == ir_var_shader_out) { + ir->lhs->variable_referenced()->data.mode == ir_var_shader_out) { /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the * FINISHME: W component of fragment shader output zero, work correctly. */ @@ -2664,8 +2622,8 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) ir_rvalue *param_rval = (ir_rvalue *)iter.get(); ir_variable *param = (ir_variable *)sig_iter.get(); - if (param->mode == ir_var_function_in || - param->mode == ir_var_function_inout) { + if (param->data.mode == ir_var_function_in || + param->data.mode == ir_var_function_inout) { variable_storage *storage = find_variable_storage(param); assert(storage); @@ -2700,8 +2658,8 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) ir_rvalue *param_rval = (ir_rvalue *)iter.get(); ir_variable *param = (ir_variable *)sig_iter.get(); - if (param->mode == ir_var_function_out || - param->mode == ir_var_function_inout) { + if (param->data.mode == ir_var_function_out || + param->data.mode == ir_var_function_inout) { variable_storage *storage = find_variable_storage(param); assert(storage); diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index f010e1889..f72122b4f 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -258,6 +258,10 @@ st_prepare_vertex_program(struct gl_context *ctx, stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX; stvp->output_semantic_index[slot] = 0; break; + case VARYING_SLOT_LAYER: + stvp->output_semantic_name[slot] = TGSI_SEMANTIC_LAYER; + stvp->output_semantic_index[slot] = 0; + break; case VARYING_SLOT_TEX0: case VARYING_SLOT_TEX1: @@ -563,6 +567,11 @@ st_translate_fragment_program(struct st_context *st, input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; + case VARYING_SLOT_PRIMITIVE_ID: + input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID; + input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; + break; case VARYING_SLOT_CLIP_DIST0: input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST; input_semantic_index[slot] = 0; diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h index c15aeaea6..ac93d9655 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.h +++ b/mesalib/src/mesa/state_tracker/st_texture.h @@ -112,6 +112,12 @@ st_texture_object(struct gl_texture_object *obj) return (struct st_texture_object *) obj; } +static INLINE const struct st_texture_object * +st_texture_object_const(const struct gl_texture_object *obj) +{ + return (const struct st_texture_object *) obj; +} + static INLINE struct pipe_resource * st_get_texobj_resource(struct gl_texture_object *texObj) diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c index 27803c553..c08a4e9d1 100644 --- a/mesalib/src/mesa/swrast/s_texture.c +++ b/mesalib/src/mesa/swrast/s_texture.c @@ -164,10 +164,9 @@ _swrast_free_texture_image_buffer(struct gl_context *ctx, struct gl_texture_image *texImage) { struct swrast_texture_image *swImage = swrast_texture_image(texImage); - if (swImage->Buffer) { - _mesa_align_free(swImage->Buffer); - swImage->Buffer = NULL; - } + + _mesa_align_free(swImage->Buffer); + swImage->Buffer = NULL; free(swImage->ImageSlices); swImage->ImageSlices = NULL; diff --git a/mesalib/src/mesa/tnl/t_vertex.c b/mesalib/src/mesa/tnl/t_vertex.c index c7a745ed7..8c4195eed 100644 --- a/mesalib/src/mesa/tnl/t_vertex.c +++ b/mesalib/src/mesa/tnl/t_vertex.c @@ -546,10 +546,8 @@ void _tnl_free_vertices( struct gl_context *ctx ) struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); struct tnl_clipspace_fastpath *fp, *tmp; - if (vtx->vertex_buf) { - _mesa_align_free(vtx->vertex_buf); - vtx->vertex_buf = NULL; - } + _mesa_align_free(vtx->vertex_buf); + vtx->vertex_buf = NULL; for (fp = vtx->fastpath ; fp ; fp = tmp) { tmp = fp->next; diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index c84d97f56..6feda1657 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -990,11 +990,10 @@ void vbo_use_buffer_objects(struct gl_context *ctx) /* Make sure this func is only used once */ assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj); - if (exec->vtx.buffer_map) { - _mesa_align_free(exec->vtx.buffer_map); - exec->vtx.buffer_map = NULL; - exec->vtx.buffer_ptr = NULL; - } + + _mesa_align_free(exec->vtx.buffer_map); + exec->vtx.buffer_map = NULL; + exec->vtx.buffer_ptr = NULL; /* Allocate a real buffer object now */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL); diff --git a/mesalib/src/mesa/x86/rtasm/x86sse.c b/mesalib/src/mesa/x86/rtasm/x86sse.c deleted file mode 100644 index c93faba79..000000000 --- a/mesalib/src/mesa/x86/rtasm/x86sse.c +++ /dev/null @@ -1,1203 +0,0 @@ -#ifdef USE_X86_ASM -#if defined(__i386__) || defined(__386__) - -#include "main/imports.h" -#include "x86sse.h" - -#define DISASSEM 0 -#define X86_TWOB 0x0f - -#if 0 -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *)(unsigned long)label; -} -#endif - - -static void do_realloc( struct x86_function *p ) -{ - if (p->size == 0) { - p->size = 1024; - p->store = _mesa_exec_malloc(p->size); - p->csr = p->store; - } - else { - unsigned used = p->csr - p->store; - unsigned char *tmp = p->store; - p->size *= 2; - p->store = _mesa_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; - _mesa_exec_free(tmp); - } -} - -/* Emit bytes to the instruction stream: - */ -static unsigned char *reserve( struct x86_function *p, int bytes ) -{ - if (p->csr + bytes - p->store > p->size) - do_realloc(p); - - { - unsigned char *csr = p->csr; - p->csr += bytes; - return csr; - } -} - - - -static void emit_1b( struct x86_function *p, char b0 ) -{ - char *csr = (char *)reserve(p, 1); - *csr = b0; -} - -static void emit_1i( struct x86_function *p, int i0 ) -{ - int *icsr = (int *)reserve(p, sizeof(i0)); - *icsr = i0; -} - -static void emit_1ub( struct x86_function *p, unsigned char b0 ) -{ - unsigned char *csr = reserve(p, 1); - *csr++ = b0; -} - -static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) -{ - unsigned char *csr = reserve(p, 2); - *csr++ = b0; - *csr++ = b1; -} - -static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) -{ - unsigned char *csr = reserve(p, 3); - *csr++ = b0; - *csr++ = b1; - *csr++ = b2; -} - - -/* Build a modRM byte + possible displacement. No treatment of SIB - * indexing. BZZT - no way to encode an absolute address. - */ -static void emit_modrm( struct x86_function *p, - struct x86_reg reg, - struct x86_reg regmem ) -{ - unsigned char val = 0; - - assert(reg.mod == mod_REG); - - val |= regmem.mod << 6; /* mod field */ - val |= reg.idx << 3; /* reg field */ - val |= regmem.idx; /* r/m field */ - - emit_1ub(p, val); - - /* Oh-oh we've stumbled into the SIB thing. - */ - if (regmem.file == file_REG32 && - regmem.idx == reg_SP) { - emit_1ub(p, 0x24); /* simplistic! */ - } - - switch (regmem.mod) { - case mod_REG: - case mod_INDIRECT: - break; - case mod_DISP8: - emit_1b(p, regmem.disp); - break; - case mod_DISP32: - emit_1i(p, regmem.disp); - break; - default: - assert(0); - break; - } -} - - -static void emit_modrm_noreg( struct x86_function *p, - unsigned op, - struct x86_reg regmem ) -{ - struct x86_reg dummy = x86_make_reg(file_REG32, op); - emit_modrm(p, dummy, regmem); -} - -/* Many x86 instructions have two opcodes to cope with the situations - * where the destination is a register or memory reference - * respectively. This function selects the correct opcode based on - * the arguments presented. - */ -static void emit_op_modrm( struct x86_function *p, - unsigned char op_dst_is_reg, - unsigned char op_dst_is_mem, - struct x86_reg dst, - struct x86_reg src ) -{ - switch (dst.mod) { - case mod_REG: - emit_1ub(p, op_dst_is_reg); - emit_modrm(p, dst, src); - break; - case mod_INDIRECT: - case mod_DISP32: - case mod_DISP8: - assert(src.mod == mod_REG); - emit_1ub(p, op_dst_is_mem); - emit_modrm(p, src, dst); - break; - default: - assert(0); - break; - } -} - - - - - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ) -{ - struct x86_reg reg; - - reg.file = file; - reg.idx = idx; - reg.mod = mod_REG; - reg.disp = 0; - - return reg; -} - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ) -{ - assert(reg.file == file_REG32); - - if (reg.mod == mod_REG) - reg.disp = disp; - else - reg.disp += disp; - - if (reg.disp == 0) - reg.mod = mod_INDIRECT; - else if (reg.disp <= 127 && reg.disp >= -128) - reg.mod = mod_DISP8; - else - reg.mod = mod_DISP32; - - return reg; -} - -struct x86_reg x86_deref( struct x86_reg reg ) -{ - return x86_make_disp(reg, 0); -} - -struct x86_reg x86_get_base_reg( struct x86_reg reg ) -{ - return x86_make_reg( reg.file, reg.idx ); -} - -unsigned char *x86_get_label( struct x86_function *p ) -{ - return p->csr; -} - - - -/*********************************************************************** - * x86 instructions - */ - - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ) -{ - int offset = label - (x86_get_label(p) + 2); - - if (offset <= 127 && offset >= -128) { - emit_1ub(p, 0x70 + cc); - emit_1b(p, (char) offset); - } - else { - offset = label - (x86_get_label(p) + 6); - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, offset); - } -} - -/* Always use a 32bit offset for forward jumps: - */ -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ) -{ - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_jmp_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe9); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_call_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe8); - emit_1i(p, 0); - return x86_get_label(p); -} - -/* Fixup offset from forward jump: - */ -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ) -{ - *(int *)(fixup - 4) = x86_get_label(p) - fixup; -} - -void x86_jmp( struct x86_function *p, unsigned char *label) -{ - emit_1ub(p, 0xe9); - emit_1i(p, label - x86_get_label(p) - 4); -} - -#if 0 -/* This doesn't work once we start reallocating & copying the - * generated code on buffer fills, because the call is relative to the - * current pc. - */ -void x86_call( struct x86_function *p, void (*label)()) -{ - emit_1ub(p, 0xe8); - emit_1i(p, cptr(label) - x86_get_label(p) - 4); -} -#else -void x86_call( struct x86_function *p, struct x86_reg reg) -{ - emit_1ub(p, 0xff); - emit_modrm_noreg(p, 2, reg); -} -#endif - - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) -{ - assert(dst.mod == mod_REG); - emit_1ub(p, 0xb8 + dst.idx); - emit_1i(p, imm); -} - -void x86_push( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x50 + reg.idx); - p->stack_offset += 4; -} - -void x86_pop( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x58 + reg.idx); - p->stack_offset -= 4; -} - -void x86_inc( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x40 + reg.idx); -} - -void x86_dec( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x48 + reg.idx); -} - -void x86_ret( struct x86_function *p ) -{ - emit_1ub(p, 0xc3); -} - -void x86_sahf( struct x86_function *p ) -{ - emit_1ub(p, 0x9e); -} - -void x86_mov( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x8b, 0x89, dst, src ); -} - -void x86_xor( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x33, 0x31, dst, src ); -} - -void x86_cmp( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x3b, 0x39, dst, src ); -} - -void x86_lea( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x8d); - emit_modrm( p, dst, src ); -} - -void x86_test( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x85); - emit_modrm( p, dst, src ); -} - -void x86_add( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x03, 0x01, dst, src ); -} - -void x86_mul( struct x86_function *p, - struct x86_reg src ) -{ - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); -} - -void x86_sub( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x2b, 0x29, dst, src ); -} - -void x86_or( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x0b, 0x09, dst, src ); -} - -void x86_and( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x23, 0x21, dst, src ); -} - - - -/*********************************************************************** - * SSE instructions - */ - - -void sse_movss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0xF3, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movaps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x28, 0x29, dst, src ); -} - -void sse_movups( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ -} - -void sse_movlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ -} - -void sse_maxps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_maxss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_divss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5E); - emit_modrm( p, dst, src ); -} - -void sse_minps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5D); - emit_modrm( p, dst, src ); -} - -void sse_subps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5C); - emit_modrm( p, dst, src ); -} - -void sse_mulps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_mulss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_addps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_addss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_andnps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x55); - emit_modrm( p, dst, src ); -} - -void sse_andps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x54); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); - -} - -void sse_movhlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x12); - emit_modrm( p, dst, src ); -} - -void sse_movlhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x16); - emit_modrm( p, dst, src ); -} - -void sse_orps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x56); - emit_modrm( p, dst, src ); -} - -void sse_xorps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x57); - emit_modrm( p, dst, src ); -} - -void sse_cvtps2pi( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_XMM || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x2d); - emit_modrm( p, dst, src ); -} - - -/* Shufps can also be used to implement a reduced swizzle when dest == - * arg0. - */ -void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char cc) -{ - emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); - emit_1ub(p, cc); -} - -void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, - struct x86_reg src) -{ - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); -} - -/*********************************************************************** - * SSE2 instructions - */ - -/** - * Perform a reduced swizzle: - */ -void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse2_cvttps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); - emit_modrm( p, dst, src ); -} - -void sse2_cvtps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x5B); - emit_modrm( p, dst, src ); -} - -void sse2_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x6B); - emit_modrm( p, dst, src ); -} - -void sse2_packsswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x63); - emit_modrm( p, dst, src ); -} - -void sse2_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void sse2_rcpps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_rcpss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0x66, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - - - - -/*********************************************************************** - * x87 instructions - */ -void x87_fist( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 2, dst); -} - -void x87_fistp( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 3, dst); -} - -void x87_fild( struct x86_function *p, struct x86_reg arg ) -{ - emit_1ub(p, 0xdf); - emit_modrm_noreg(p, 0, arg); -} - -void x87_fldz( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xee); -} - - -void x87_fldcw( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_REG32); - assert(arg.mod != mod_REG); - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 5, arg); -} - -void x87_fld1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe8); -} - -void x87_fldl2e( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xea); -} - -void x87_fldln2( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xed); -} - -void x87_fwait( struct x86_function *p ) -{ - emit_1ub(p, 0x9b); -} - -void x87_fnclex( struct x86_function *p ) -{ - emit_2ub(p, 0xdb, 0xe2); -} - -void x87_fclex( struct x86_function *p ) -{ - x87_fwait(p); - x87_fnclex(p); -} - - -static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, - unsigned char dst0ub0, - unsigned char dst0ub1, - unsigned char arg0ub0, - unsigned char arg0ub1, - unsigned char argmem_noreg) -{ - assert(dst.file == file_x87); - - if (arg.file == file_x87) { - if (dst.idx == 0) - emit_2ub(p, dst0ub0, dst0ub1+arg.idx); - else if (arg.idx == 0) - emit_2ub(p, arg0ub0, arg0ub1+arg.idx); - else - assert(0); - } - else if (dst.idx == 0) { - assert(arg.file == file_REG32); - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, argmem_noreg, arg); - } - else - assert(0); -} - -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc8, - 0xdc, 0xc8, - 4); -} - -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe0, - 0xdc, 0xe8, - 4); -} - -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe8, - 0xdc, 0xe0, - 5); -} - -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc0, - 0xdc, 0xc0, - 0); -} - -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf0, - 0xdc, 0xf8, - 6); -} - -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf8, - 0xdc, 0xf0, - 7); -} - -void x87_fmulp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc8+dst.idx); -} - -void x87_fsubp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe8+dst.idx); -} - -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe0+dst.idx); -} - -void x87_faddp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc0+dst.idx); -} - -void x87_fdivp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf8+dst.idx); -} - -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf0+dst.idx); -} - -void x87_fucom( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe0+arg.idx); -} - -void x87_fucomp( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe8+arg.idx); -} - -void x87_fucompp( struct x86_function *p ) -{ - emit_2ub(p, 0xda, 0xe9); -} - -void x87_fxch( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xd9, 0xc8+arg.idx); -} - -void x87_fabs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe1); -} - -void x87_fchs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe0); -} - -void x87_fcos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xff); -} - - -void x87_fprndint( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfc); -} - -void x87_fscale( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfd); -} - -void x87_fsin( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfe); -} - -void x87_fsincos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfb); -} - -void x87_fsqrt( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfa); -} - -void x87_fxtract( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf4); -} - -/* st0 = (2^st0)-1 - * - * Restrictions: -1.0 <= st0 <= 1.0 - */ -void x87_f2xm1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf0); -} - -/* st1 = st1 * log2(st0); - * pop_stack; - */ -void x87_fyl2x( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf1); -} - -/* st1 = st1 * log2(st0 + 1.0); - * pop_stack; - * - * A fast operation, with restrictions: -.29 < st0 < .29 - */ -void x87_fyl2xp1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf9); -} - - -void x87_fld( struct x86_function *p, struct x86_reg arg ) -{ - if (arg.file == file_x87) - emit_2ub(p, 0xd9, 0xc0 + arg.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 0, arg); - } -} - -void x87_fst( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fstp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 3, dst); - } -} - -void x87_fcom( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fcomp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 3, dst); - } -} - - -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_REG32); - - if (dst.idx == reg_AX && - dst.mod == mod_REG) - emit_2ub(p, 0xdf, 0xe0); - else { - emit_1ub(p, 0xdd); - emit_modrm_noreg(p, 7, dst); - } -} - - - - -/*********************************************************************** - * MMX instructions - */ - -void mmx_emms( struct x86_function *p ) -{ - assert(p->need_emms); - emit_2ub(p, 0x0f, 0x77); - p->need_emms = 0; -} - -void mmx_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x6b); - emit_modrm( p, dst, src ); -} - -void mmx_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void mmx_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - -void mmx_movq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -} - - -/*********************************************************************** - * Helper functions - */ - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity: - */ -struct x86_reg x86_fn_arg( struct x86_function *p, - unsigned arg ) -{ - return x86_make_disp(x86_make_reg(file_REG32, reg_SP), - p->stack_offset + arg * 4); /* ??? */ -} - - -void x86_init_func( struct x86_function *p ) -{ - p->size = 0; - p->store = NULL; - p->csr = p->store; -} - -int x86_init_func_size( struct x86_function *p, unsigned code_size ) -{ - p->size = code_size; - p->store = _mesa_exec_malloc(code_size); - p->csr = p->store; - return p->store != NULL; -} - -void x86_release_func( struct x86_function *p ) -{ - _mesa_exec_free(p->store); - p->store = NULL; - p->csr = NULL; - p->size = 0; -} - - -void (*x86_get_func( struct x86_function *p ))(void) -{ - if (DISASSEM && p->store) - printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) (unsigned long) p->store; -} - -#else - -void x86sse_dummy( void ) -{ -} - -#endif - -#else /* USE_X86_ASM */ - -int x86sse_c_dummy_var; /* silence warning */ - -#endif /* USE_X86_ASM */ diff --git a/mesalib/src/mesa/x86/rtasm/x86sse.h b/mesalib/src/mesa/x86/rtasm/x86sse.h deleted file mode 100644 index f6282f5bd..000000000 --- a/mesalib/src/mesa/x86/rtasm/x86sse.h +++ /dev/null @@ -1,256 +0,0 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ - -#if defined(__i386__) || defined(__386__) - -/* It is up to the caller to ensure that instructions issued are - * suitable for the host cpu. There are no checks made in this module - * for mmx/sse/sse2 support on the cpu. - */ -struct x86_reg { - unsigned file:3; - unsigned idx:3; - unsigned mod:2; /* mod_REG if this is just a register */ - int disp:24; /* only +/- 23bits of offset - should be enough... */ -}; - -struct x86_function { - unsigned size; - unsigned char *store; - unsigned char *csr; - unsigned stack_offset; - int need_emms; - const char *fn; -}; - -enum x86_reg_file { - file_REG32, - file_MMX, - file_XMM, - file_x87 -}; - -/* Values for mod field of modr/m byte - */ -enum x86_reg_mod { - mod_INDIRECT, - mod_DISP8, - mod_DISP32, - mod_REG -}; - -enum x86_reg_name { - reg_AX, - reg_CX, - reg_DX, - reg_BX, - reg_SP, - reg_BP, - reg_SI, - reg_DI -}; - - -enum x86_cc { - cc_O, /* overflow */ - cc_NO, /* not overflow */ - cc_NAE, /* not above or equal / carry */ - cc_AE, /* above or equal / not carry */ - cc_E, /* equal / zero */ - cc_NE /* not equal / not zero */ -}; - -enum sse_cc { - cc_Equal, - cc_LessThan, - cc_LessThanEqual, - cc_Unordered, - cc_NotEqual, - cc_NotLessThan, - cc_NotLessThanEqual, - cc_Ordered -}; - -#define cc_Z cc_E -#define cc_NZ cc_NE - -/* Begin/end/retreive function creation: - */ - - -void x86_init_func( struct x86_function *p ); -int x86_init_func_size( struct x86_function *p, unsigned code_size ); -void x86_release_func( struct x86_function *p ); -void (*x86_get_func( struct x86_function *p ))( void ); - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ); - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ); - -struct x86_reg x86_deref( struct x86_reg reg ); - -struct x86_reg x86_get_base_reg( struct x86_reg reg ); - - -/* Labels, jumps and fixup: - */ -unsigned char *x86_get_label( struct x86_function *p ); - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ); - -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ); - -unsigned char *x86_jmp_forward( struct x86_function *p); - -unsigned char *x86_call_forward( struct x86_function *p); - -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ); - -void x86_jmp( struct x86_function *p, unsigned char *label ); - -/* void x86_call( struct x86_function *p, void (*label)() ); */ -void x86_call( struct x86_function *p, struct x86_reg reg); - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); - - -/* Macro for sse_shufps() and sse2_pshufd(): - */ -#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) -#define SHUF_NOOP RSW(0,1,2,3) -#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) - -void mmx_emms( struct x86_function *p ); -void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc ); -void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); - -void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_dec( struct x86_function *p, struct x86_reg reg ); -void x86_inc( struct x86_function *p, struct x86_reg reg ); -void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mul( struct x86_function *p, struct x86_reg src ); -void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_pop( struct x86_function *p, struct x86_reg reg ); -void x86_push( struct x86_function *p, struct x86_reg reg ); -void x86_ret( struct x86_function *p ); -void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_sahf( struct x86_function *p ); - -void x87_f2xm1( struct x86_function *p ); -void x87_fabs( struct x86_function *p ); -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_faddp( struct x86_function *p, struct x86_reg dst ); -void x87_fchs( struct x86_function *p ); -void x87_fclex( struct x86_function *p ); -void x87_fcom( struct x86_function *p, struct x86_reg dst ); -void x87_fcomp( struct x86_function *p, struct x86_reg dst ); -void x87_fcos( struct x86_function *p ); -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivp( struct x86_function *p, struct x86_reg dst ); -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); -void x87_fild( struct x86_function *p, struct x86_reg arg ); -void x87_fist( struct x86_function *p, struct x86_reg dst ); -void x87_fistp( struct x86_function *p, struct x86_reg dst ); -void x87_fld( struct x86_function *p, struct x86_reg arg ); -void x87_fld1( struct x86_function *p ); -void x87_fldcw( struct x86_function *p, struct x86_reg arg ); -void x87_fldl2e( struct x86_function *p ); -void x87_fldln2( struct x86_function *p ); -void x87_fldz( struct x86_function *p ); -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fmulp( struct x86_function *p, struct x86_reg dst ); -void x87_fnclex( struct x86_function *p ); -void x87_fprndint( struct x86_function *p ); -void x87_fscale( struct x86_function *p ); -void x87_fsin( struct x86_function *p ); -void x87_fsincos( struct x86_function *p ); -void x87_fsqrt( struct x86_function *p ); -void x87_fst( struct x86_function *p, struct x86_reg dst ); -void x87_fstp( struct x86_function *p, struct x86_reg dst ); -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubp( struct x86_function *p, struct x86_reg dst ); -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); -void x87_fxch( struct x86_function *p, struct x86_reg dst ); -void x87_fxtract( struct x86_function *p ); -void x87_fyl2x( struct x86_function *p ); -void x87_fyl2xp1( struct x86_function *p ); -void x87_fwait( struct x86_function *p ); -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); -void x87_fucompp( struct x86_function *p ); -void x87_fucomp( struct x86_function *p, struct x86_reg arg ); -void x87_fucom( struct x86_function *p, struct x86_reg arg ); - - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity. Note - doesn't track explict - * manipulation of ESP by other instructions. - */ -struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); - -#endif -#endif |