diff --git a/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/egl_dri2.c.bak b/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/egl_dri2.c.bak deleted file mode 100644 index f5aa9db724..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/egl_dri2.c.bak +++ /dev/null @@ -1,1780 +0,0 @@ -/* - * Copyright © 2010 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kristian Høgsberg - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define EGL_EGLEXT_PROTOTYPES -#include -#include - -#include "eglmode.h" -#include "eglscreen.h" - -#include "egl_dri2.h" - -typedef unsigned int lib_handle; - -lib_handle load_library(const char *name); -void *get_proc_address(lib_handle lib, char *proc_name); - -const __DRIuseInvalidateExtension use_invalidate = { - { __DRI_USE_INVALIDATE, 1 } -}; - -EGLint dri2_to_egl_attribute_map[] = { - 0, - EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */ - EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */ - EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */ - EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */ - EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */ - EGL_LUMINANCE_SIZE, /* __DRI_ATTRIB_LUMINANCE_SIZE */ - EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */ - 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */ - EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */ - EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */ - 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */ - 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */ - 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */ - 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */ - EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */ - EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */ - 0, /* __DRI_ATTRIB_RENDER_TYPE, */ - 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */ - 0, /* __DRI_ATTRIB_CONFORMANT */ - 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */ - 0, /* __DRI_ATTRIB_STEREO */ - 0, /* __DRI_ATTRIB_AUX_BUFFERS */ - 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */ - 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */ - 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */ - 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */ - 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */ - 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */ - 0, /* __DRI_ATTRIB_FLOAT_MODE (deprecated) */ - 0, /* __DRI_ATTRIB_RED_MASK */ - 0, /* __DRI_ATTRIB_GREEN_MASK */ - 0, /* __DRI_ATTRIB_BLUE_MASK */ - 0, /* __DRI_ATTRIB_ALPHA_MASK */ - EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */ - EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */ - EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */ - 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */ - 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */ - 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */ - 0, /* __DRI_ATTRIB_SWAP_METHOD */ - EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */ - EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */ - 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */ - 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */ - 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */ - 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */ - EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ - 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ -}; - -static EGLBoolean -dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) -{ - if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) - return EGL_FALSE; - - if (!_eglMatchConfig(conf, criteria)) - return EGL_FALSE; - - return EGL_TRUE; -} - -struct dri2_egl_config * -dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, - int depth, EGLint surface_type, const EGLint *attr_list, - const unsigned int *rgba_masks) -{ - struct dri2_egl_config *conf; - struct dri2_egl_display *dri2_dpy; - _EGLConfig base; - unsigned int attrib, value, double_buffer; - EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; - unsigned int dri_masks[4] = { 0, 0, 0, 0 }; - _EGLConfig *matching_config; - EGLint num_configs = 0; - EGLint config_id; - int i; - - dri2_dpy = disp->DriverData; - _eglInitConfig(&base, disp, id); - - i = 0; - double_buffer = 0; - bind_to_texture_rgb = 0; - bind_to_texture_rgba = 0; - - while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { - switch (attrib) { - case __DRI_ATTRIB_RENDER_TYPE: - if (value & __DRI_ATTRIB_RGBA_BIT) - value = EGL_RGB_BUFFER; - else if (value & __DRI_ATTRIB_LUMINANCE_BIT) - value = EGL_LUMINANCE_BUFFER; - else - return NULL; - _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value); - break; - - case __DRI_ATTRIB_CONFIG_CAVEAT: - if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) - value = EGL_NON_CONFORMANT_CONFIG; - else if (value & __DRI_ATTRIB_SLOW_BIT) - value = EGL_SLOW_CONFIG; - else - value = EGL_NONE; - _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value); - break; - - case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB: - bind_to_texture_rgb = value; - break; - - case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA: - bind_to_texture_rgba = value; - break; - - case __DRI_ATTRIB_DOUBLE_BUFFER: - double_buffer = value; - break; - - case __DRI_ATTRIB_RED_MASK: - dri_masks[0] = value; - break; - - case __DRI_ATTRIB_GREEN_MASK: - dri_masks[1] = value; - break; - - case __DRI_ATTRIB_BLUE_MASK: - dri_masks[2] = value; - break; - - case __DRI_ATTRIB_ALPHA_MASK: - dri_masks[3] = value; - break; - - default: - key = dri2_to_egl_attribute_map[attrib]; - if (key != 0) - _eglSetConfigKey(&base, key, value); - break; - } - } - - if (attr_list) - for (i = 0; attr_list[i] != EGL_NONE; i += 2) - _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]); - - /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. Otherwise - * it will only match a 32-bit RGBA visual. On a composited window manager - * on X11, this will make all of the EGLConfigs with destination alpha get - * blended by the compositor. This is probably not what the application - * wants... especially on drivers that only have 32-bit RGBA EGLConfigs! - */ - if (depth > 0 && depth != base.BufferSize - && !(depth == 24 && base.BufferSize == 32)) - return NULL; - - if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks))) - return NULL; - - base.NativeRenderable = EGL_TRUE; - - base.SurfaceType = surface_type; - if (surface_type & (EGL_PBUFFER_BIT | - (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) { - base.BindToTextureRGB = bind_to_texture_rgb; - if (base.AlphaSize > 0) - base.BindToTextureRGBA = bind_to_texture_rgba; - } - - base.RenderableType = disp->ClientAPIs; - base.Conformant = disp->ClientAPIs; - - base.MinSwapInterval = dri2_dpy->min_swap_interval; - base.MaxSwapInterval = dri2_dpy->max_swap_interval; - - if (!_eglValidateConfig(&base, EGL_FALSE)) { - _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); - return NULL; - } - - config_id = base.ConfigID; - base.ConfigID = EGL_DONT_CARE; - base.SurfaceType = EGL_DONT_CARE; - num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1, - (_EGLArrayForEach) dri2_match_config, &base); - - if (num_configs == 1) { - conf = (struct dri2_egl_config *) matching_config; - - if (double_buffer && !conf->dri_double_config) - conf->dri_double_config = dri_config; - else if (!double_buffer && !conf->dri_single_config) - conf->dri_single_config = dri_config; - else - /* a similar config type is already added (unlikely) => discard */ - return NULL; - } - else if (num_configs == 0) { - conf = malloc(sizeof *conf); - if (conf == NULL) - return NULL; - - memcpy(&conf->base, &base, sizeof base); - if (double_buffer) { - conf->dri_double_config = dri_config; - conf->dri_single_config = NULL; - } else { - conf->dri_single_config = dri_config; - conf->dri_double_config = NULL; - } - conf->base.SurfaceType = 0; - conf->base.ConfigID = config_id; - - _eglLinkConfig(&conf->base); - } - else { - assert(0); - return NULL; - } - - if (double_buffer) { - surface_type &= ~EGL_PIXMAP_BIT; - } - - conf->base.SurfaceType |= surface_type; - - return conf; -} - -__DRIimage * -dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data) -{ - _EGLDisplay *disp = data; - struct dri2_egl_image *dri2_img; - _EGLImage *img; - - (void) screen; - - img = _eglLookupImage(image, disp); - if (img == NULL) { - _eglError(EGL_BAD_PARAMETER, "dri2_lookup_egl_image"); - return NULL; - } - - dri2_img = dri2_egl_image(image); - - return dri2_img->dri_image; -} - -const __DRIimageLookupExtension image_lookup_extension = { - { __DRI_IMAGE_LOOKUP, 1 }, - dri2_lookup_egl_image -}; - -static const char dri_driver_path[] = "";//DEFAULT_DRIVER_DIR; - -struct dri2_extension_match { - const char *name; - int version; - int offset; -}; - -static struct dri2_extension_match dri2_driver_extensions[] = { - { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, - { __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) }, - { NULL, 0, 0 } -}; - -static struct dri2_extension_match dri2_core_extensions[] = { - { __DRI2_FLUSH, 1, offsetof(struct dri2_egl_display, flush) }, - { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, - { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, - { NULL, 0, 0 } -}; - -static struct dri2_extension_match swrast_driver_extensions[] = { - { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) }, - { __DRI_SWRAST, 2, offsetof(struct dri2_egl_display, swrast) }, - { NULL, 0, 0 } -}; - -static struct dri2_extension_match swrast_core_extensions[] = { - { __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) }, - { NULL, 0, 0 } -}; - -static EGLBoolean -dri2_bind_extensions(struct dri2_egl_display *dri2_dpy, - struct dri2_extension_match *matches, - const __DRIextension **extensions) -{ - int i, j, ret = EGL_TRUE; - void *field; - - for (i = 0; extensions[i]; i++) { - _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name); - for (j = 0; matches[j].name; j++) { - if (strcmp(extensions[i]->name, matches[j].name) == 0 && - extensions[i]->version >= matches[j].version) { - field = ((char *) dri2_dpy + matches[j].offset); - *(const __DRIextension **) field = extensions[i]; - _eglLog(_EGL_INFO, "DRI2: found extension %s version %d", - extensions[i]->name, extensions[i]->version); - } - } - } - - for (j = 0; matches[j].name; j++) { - field = ((char *) dri2_dpy + matches[j].offset); - if (*(const __DRIextension **) field == NULL) { - _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d", - matches[j].name, matches[j].version); - ret = EGL_FALSE; - } - } - - return ret; -} - -#if 0 - -static const __DRIextension ** -dri2_open_driver(_EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = disp->DriverData; - const __DRIextension **extensions; - char path[PATH_MAX], *search_paths, *p, *next, *end; - - search_paths = NULL; - if (geteuid() == getuid()) { - /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ - search_paths = getenv("LIBGL_DRIVERS_PATH"); - } -// if (search_paths == NULL) -// search_paths = DEFAULT_DRIVER_DIR; - - dri2_dpy->driver = NULL; - end = search_paths + strlen(search_paths); - for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) { - int len; - next = strchr(p, ':'); - if (next == NULL) - next = end; - - len = next - p; -#if GLX_USE_TLS - snprintf(path, sizeof path, - "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name); - dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); -#endif - if (dri2_dpy->driver == NULL) { - snprintf(path, sizeof path, - "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name); - dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (dri2_dpy->driver == NULL) - _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror()); - } - } - - if (dri2_dpy->driver == NULL) { - _eglLog(_EGL_WARNING, - "DRI2: failed to open %s (search paths %s)", - dri2_dpy->driver_name, search_paths); - return NULL; - } - - _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); - extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - _eglLog(_EGL_WARNING, - "DRI2: driver exports no extensions (%s)", dlerror()); - dlclose(dri2_dpy->driver); - } - - return extensions; -} - -EGLBoolean -dri2_load_driver(_EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = disp->DriverData; - const __DRIextension **extensions; - - extensions = dri2_open_driver(disp); - if (!extensions) - return EGL_FALSE; - - if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) { - dlclose(dri2_dpy->driver); - return EGL_FALSE; - } - - return EGL_TRUE; -} - -EGLBoolean -dri2_load_driver_swrast(_EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = disp->DriverData; - const __DRIextension **extensions; - - dri2_dpy->driver_name = "swrast"; - extensions = dri2_open_driver(disp); - - if (!extensions) - return EGL_FALSE; - - if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions)) { - dlclose(dri2_dpy->driver); - return EGL_FALSE; - } - - return EGL_TRUE; -} -#endif - -void -dri2_setup_screen(_EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - unsigned int api_mask; - - if (dri2_dpy->dri2) { - api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen); - } else { - assert(dri2_dpy->swrast); - api_mask = 1 << __DRI_API_OPENGL | - 1 << __DRI_API_GLES | - 1 << __DRI_API_GLES2 | - 1 << __DRI_API_GLES3; - } - - disp->ClientAPIs = 0; - if (api_mask & (1 <<__DRI_API_OPENGL)) - disp->ClientAPIs |= EGL_OPENGL_BIT; - if (api_mask & (1 <<__DRI_API_GLES)) - disp->ClientAPIs |= EGL_OPENGL_ES_BIT; - if (api_mask & (1 << __DRI_API_GLES2)) - disp->ClientAPIs |= EGL_OPENGL_ES2_BIT; - if (api_mask & (1 << __DRI_API_GLES3)) - disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR; - - assert(dri2_dpy->dri2 || dri2_dpy->swrast); - disp->Extensions.KHR_surfaceless_context = EGL_TRUE; - - disp->Extensions.MESA_screen_surface = EGL_TRUE; - - if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) { - disp->Extensions.KHR_create_context = EGL_TRUE; - - if (dri2_dpy->robustness) - disp->Extensions.EXT_create_context_robustness = EGL_TRUE; - } - - if (dri2_dpy->image) { - disp->Extensions.MESA_drm_image = EGL_TRUE; - disp->Extensions.KHR_image_base = EGL_TRUE; - disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; - if (dri2_dpy->image->base.version >= 5 && - dri2_dpy->image->createImageFromTexture) { - disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; - disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE; - } - } - { - _EGLMode *mode; - _EGLScreen *screen = malloc(sizeof(*screen)); - - _eglInitScreen(screen, disp, 3); - mode = &screen->Modes[0]; - mode->Width = 800; - mode->Height = 600; - mode->RefreshRate = 60; - mode->Optimal = EGL_FALSE; - mode->Interlaced = EGL_FALSE; - mode->Name = "800 x 600 60Hz"; - - - mode = &screen->Modes[1]; - mode->Width = 1024; - mode->Height = 768; - mode->RefreshRate = 60; - mode->Optimal = EGL_FALSE; - mode->Interlaced = EGL_FALSE; - mode->Name = "1024 x 768 60Hz"; - - mode = &screen->Modes[2]; - mode->Width = 1280; - mode->Height = 1024; - mode->RefreshRate = 60; - mode->Optimal = EGL_FALSE; - mode->Interlaced = EGL_FALSE; - mode->Name = "1280 x 1024 60Hz"; - - _eglLinkScreen(screen); - } -} - -EGLBoolean -dri2_create_screen(_EGLDisplay *disp) -{ - const __DRIextension **extensions; - struct dri2_egl_display *dri2_dpy; - - dri2_dpy = disp->DriverData; - - if (dri2_dpy->dri2) { - dri2_dpy->dri_screen = - dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); - } else { - assert(dri2_dpy->swrast); - dri2_dpy->dri_screen = - dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions, - &dri2_dpy->driver_configs, disp); - } - - if (dri2_dpy->dri_screen == NULL) { - _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen"); - return EGL_FALSE; - } - - dri2_dpy->own_dri_screen = 1; - - extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); - - if (dri2_dpy->dri2) { - unsigned i; - - if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions)) - goto cleanup_dri_screen; - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0) { - dri2_dpy->robustness = (__DRIrobustnessExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0) { - dri2_dpy->config = (__DRI2configQueryExtension *) extensions[i]; - } - } - } else { - assert(dri2_dpy->swrast); - if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions)) - goto cleanup_dri_screen; - } - - dri2_setup_screen(disp); - - return EGL_TRUE; - - cleanup_dri_screen: - dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); - - return EGL_FALSE; -} - -/** - * Called via eglInitialize(), GLX_drv->API.Initialize(). - */ -static EGLBoolean -dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) -{ - /* not until swrast_dri is supported */ - if (disp->Options.UseFallback) - return EGL_FALSE; - - return dri2_initialize_drm(drv, disp); - -#if 0 - switch (disp->Platform) { -#ifdef HAVE_X11_PLATFORM - case _EGL_PLATFORM_X11: - if (disp->Options.TestOnly) - return EGL_TRUE; - return dri2_initialize_x11(drv, disp); -#endif - -#ifdef HAVE_LIBUDEV -#ifdef HAVE_DRM_PLATFORM - case _EGL_PLATFORM_DRM: - if (disp->Options.TestOnly) - return EGL_TRUE; - return dri2_initialize_drm(drv, disp); -#endif -#ifdef HAVE_WAYLAND_PLATFORM - case _EGL_PLATFORM_WAYLAND: - if (disp->Options.TestOnly) - return EGL_TRUE; - return dri2_initialize_wayland(drv, disp); -#endif -#endif -#ifdef HAVE_ANDROID_PLATFORM - case _EGL_PLATFORM_ANDROID: - if (disp->Options.TestOnly) - return EGL_TRUE; - return dri2_initialize_android(drv, disp); -#endif - - default: - return EGL_FALSE; - } -#endif -} - -/** - * Called via eglTerminate(), drv->API.Terminate(). - */ -static EGLBoolean -dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - _eglReleaseDisplayResources(drv, disp); - _eglCleanupDisplay(disp); - - if (dri2_dpy->own_dri_screen) - dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); -// if (dri2_dpy->fd) -// close(dri2_dpy->fd); -// if (dri2_dpy->driver) -// dlclose(dri2_dpy->driver); - free(dri2_dpy->device_name); - - if (disp->PlatformDisplay == NULL) { - switch (disp->Platform) { -#ifdef HAVE_X11_PLATFORM - case _EGL_PLATFORM_X11: - xcb_disconnect(dri2_dpy->conn); - break; -#endif -#ifdef HAVE_DRM_PLATFORM - case _EGL_PLATFORM_DRM: - if (dri2_dpy->own_device) { - gbm_device_destroy(&dri2_dpy->gbm_dri->base.base); - } - break; -#endif - default: - break; - } - } - - free(dri2_dpy); - disp->DriverData = NULL; - - return EGL_TRUE; -} - -/** - * Set the error code after a call to - * dri2_egl_display::dri2::createContextAttribs. - */ -static void -dri2_create_context_attribs_error(int dri_error) -{ - EGLint egl_error; - - switch (dri_error) { - case __DRI_CTX_ERROR_SUCCESS: - return; - - case __DRI_CTX_ERROR_NO_MEMORY: - egl_error = EGL_BAD_ALLOC; - break; - - /* From the EGL_KHR_create_context spec, section "Errors": - * - * * If does not support a client API context compatible - * with the requested API major and minor version, [...] context flags, - * and context reset notification behavior (for client API types where - * these attributes are supported), then an EGL_BAD_MATCH error is - * generated. - * - * * If an OpenGL ES context is requested and the values for - * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and - * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that - * is not defined, than an EGL_BAD_MATCH error is generated. - * - * * If an OpenGL context is requested, the requested version is - * greater than 3.2, and the value for attribute - * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has any - * bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR and - * EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has more than - * one of these bits set; or if the implementation does not support - * the requested profile, then an EGL_BAD_MATCH error is generated. - */ - case __DRI_CTX_ERROR_BAD_API: - case __DRI_CTX_ERROR_BAD_VERSION: - case __DRI_CTX_ERROR_BAD_FLAG: - egl_error = EGL_BAD_MATCH; - break; - - /* From the EGL_KHR_create_context spec, section "Errors": - * - * * If an attribute name or attribute value in is not - * recognized (including unrecognized bits in bitmask attributes), - * then an EGL_BAD_ATTRIBUTE error is generated." - */ - case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: - case __DRI_CTX_ERROR_UNKNOWN_FLAG: - egl_error = EGL_BAD_ATTRIBUTE; - break; - - default: - assert(0); - egl_error = EGL_BAD_MATCH; - break; - } - - _eglError(egl_error, "dri2_create_context"); -} - -/** - * Called via eglCreateContext(), drv->API.CreateContext(). - */ -static _EGLContext * -dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - _EGLContext *share_list, const EGLint *attrib_list) -{ - struct dri2_egl_context *dri2_ctx; - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); - __DRIcontext *shared = - dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL; - struct dri2_egl_config *dri2_config = dri2_egl_config(conf); - const __DRIconfig *dri_config; - int api; - - (void) drv; - - dri2_ctx = malloc(sizeof *dri2_ctx); - if (!dri2_ctx) { - _eglError(EGL_BAD_ALLOC, "eglCreateContext"); - return NULL; - } - - if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) - goto cleanup; - - switch (dri2_ctx->base.ClientAPI) { - case EGL_OPENGL_ES_API: - switch (dri2_ctx->base.ClientMajorVersion) { - case 1: - api = __DRI_API_GLES; - break; - case 2: - api = __DRI_API_GLES2; - break; - case 3: - api = __DRI_API_GLES3; - break; - default: - _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); - return NULL; - } - break; - case EGL_OPENGL_API: - if ((dri2_ctx->base.ClientMajorVersion >= 4 - || (dri2_ctx->base.ClientMajorVersion == 3 - && dri2_ctx->base.ClientMinorVersion >= 2)) - && dri2_ctx->base.Profile == EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) - api = __DRI_API_OPENGL_CORE; - else - api = __DRI_API_OPENGL; - break; - default: - _eglError(EGL_BAD_PARAMETER, "eglCreateContext"); - free(dri2_ctx); - return NULL; - } - - if (conf != NULL) { - /* The config chosen here isn't necessarily - * used for surfaces later. - * A pixmap surface will use the single config. - * This opportunity depends on disabling the - * doubleBufferMode check in - * src/mesa/main/context.c:check_compatible() - */ - if (dri2_config->dri_double_config) - dri_config = dri2_config->dri_double_config; - else - dri_config = dri2_config->dri_single_config; - - /* EGL_WINDOW_BIT is set only when there is a dri_double_config. This - * makes sure the back buffer will always be used. - */ - if (conf->SurfaceType & EGL_WINDOW_BIT) - dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER; - } - else - dri_config = NULL; - - if (dri2_dpy->dri2) { - if (dri2_dpy->dri2->base.version >= 3) { - unsigned error; - unsigned num_attribs = 0; - uint32_t ctx_attribs[8]; - - ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; - ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion; - ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; - ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion; - - if (dri2_ctx->base.Flags != 0) { - /* If the implementation doesn't support the __DRI2_ROBUSTNESS - * extension, don't even try to send it the robust-access flag. - * It may explode. Instead, generate the required EGL error here. - */ - if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0 - && !dri2_dpy->robustness) { - _eglError(EGL_BAD_MATCH, "eglCreateContext"); - goto cleanup; - } - - ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS; - ctx_attribs[num_attribs++] = dri2_ctx->base.Flags; - } - - if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) { - /* If the implementation doesn't support the __DRI2_ROBUSTNESS - * extension, don't even try to send it a reset strategy. It may - * explode. Instead, generate the required EGL error here. - */ - if (!dri2_dpy->robustness) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - goto cleanup; - } - - ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY; - ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT; - } - - assert(num_attribs <= ARRAY_SIZE(ctx_attribs)); - - dri2_ctx->dri_context = - dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, - api, - dri_config, - shared, - num_attribs / 2, - ctx_attribs, - & error, - dri2_ctx); - dri2_create_context_attribs_error(error); - } else { - dri2_ctx->dri_context = - dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, - api, - dri_config, - shared, - dri2_ctx); - } - } else { - assert(dri2_dpy->swrast); - dri2_ctx->dri_context = - dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen, - api, - dri_config, - shared, - dri2_ctx); - } - - if (!dri2_ctx->dri_context) - goto cleanup; - - return &dri2_ctx->base; - - cleanup: - free(dri2_ctx); - return NULL; -} - -/** - * Called via eglDestroyContext(), drv->API.DestroyContext(). - */ -static EGLBoolean -dri2_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) -{ - struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - if (_eglPutContext(ctx)) { - dri2_dpy->core->destroyContext(dri2_ctx->dri_context); - free(dri2_ctx); - } - - return EGL_TRUE; -} - -/** - * Called via eglMakeCurrent(), drv->API.MakeCurrent(). - */ -static EGLBoolean -dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, - _EGLSurface *rsurf, _EGLContext *ctx) -{ - struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf); - struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf); - struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); - _EGLContext *old_ctx; - _EGLSurface *old_dsurf, *old_rsurf; - __DRIdrawable *ddraw, *rdraw; - __DRIcontext *cctx; - - /* make new bindings */ - if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf)) - return EGL_FALSE; - - /* flush before context switch */ - if (old_ctx && dri2_drv->glFlush) - dri2_drv->glFlush(); - - ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; - rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL; - cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; - - printf("%s cctx %p ddraw %p, rdraw %p\n", - __FUNCTION__, cctx, ddraw, rdraw); - - __asm__ __volatile__ ("int3"); - - if (old_ctx) { - __DRIcontext *old_cctx = dri2_egl_context(old_ctx)->dri_context; - dri2_dpy->core->unbindContext(old_cctx); - } - - if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || - dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { - if (old_dsurf) - drv->API.DestroySurface(drv, disp, old_dsurf); - if (old_rsurf) - drv->API.DestroySurface(drv, disp, old_rsurf); - if (old_ctx) - drv->API.DestroyContext(drv, disp, old_ctx); - - return EGL_TRUE; - } else { - /* undo the previous _eglBindContext */ - _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf); - assert(&dri2_ctx->base == ctx && - &dri2_dsurf->base == dsurf && - &dri2_rsurf->base == rsurf); - - _eglPutSurface(dsurf); - _eglPutSurface(rsurf); - _eglPutContext(ctx); - - _eglPutSurface(old_dsurf); - _eglPutSurface(old_rsurf); - _eglPutContext(old_ctx); - - return EGL_FALSE; - } -} - -/* - * Called from eglGetProcAddress() via drv->API.GetProcAddress(). - */ -static _EGLProc -dri2_get_proc_address(_EGLDriver *drv, const char *procname) -{ - struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - - return dri2_drv->get_proc_address(procname); -} - -static EGLBoolean -dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface); - - (void) drv; - - /* FIXME: If EGL allows frontbuffer rendering for window surfaces, - * we need to copy fake to real here.*/ - - if (dri2_dpy->flush != NULL) - dri2_dpy->flush->flush(dri2_surf->dri_drawable); - - return EGL_TRUE; -} - -static EGLBoolean -dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) -{ - (void) drv; - (void) disp; - - if (engine != EGL_CORE_NATIVE_ENGINE) - return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); - /* glXWaitX(); */ - - return EGL_TRUE; -} - -static EGLBoolean -dri2_bind_tex_image(_EGLDriver *drv, - _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); - struct dri2_egl_context *dri2_ctx; - _EGLContext *ctx; - GLint format, target; - - ctx = _eglGetCurrentContext(); - dri2_ctx = dri2_egl_context(ctx); - - if (!_eglBindTexImage(drv, disp, surf, buffer)) - return EGL_FALSE; - - switch (dri2_surf->base.TextureFormat) { - case EGL_TEXTURE_RGB: - format = __DRI_TEXTURE_FORMAT_RGB; - break; - case EGL_TEXTURE_RGBA: - format = __DRI_TEXTURE_FORMAT_RGBA; - break; - default: - assert(0); - } - - switch (dri2_surf->base.TextureTarget) { - case EGL_TEXTURE_2D: - target = GL_TEXTURE_2D; - break; - default: - assert(0); - } - - (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context, - target, format, - dri2_surf->dri_drawable); - - return EGL_TRUE; -} - -static EGLBoolean -dri2_release_tex_image(_EGLDriver *drv, - _EGLDisplay *disp, _EGLSurface *surf, EGLint buffer) -{ -#if __DRI_TEX_BUFFER_VERSION >= 3 - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); - struct dri2_egl_context *dri2_ctx; - _EGLContext *ctx; - GLint target; - - ctx = _eglGetCurrentContext(); - dri2_ctx = dri2_egl_context(ctx); - - if (!_eglReleaseTexImage(drv, disp, surf, buffer)) - return EGL_FALSE; - - switch (dri2_surf->base.TextureTarget) { - case EGL_TEXTURE_2D: - target = GL_TEXTURE_2D; - break; - default: - assert(0); - } - if (dri2_dpy->tex_buffer->releaseTexBuffer!=NULL) - (*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context, - target, - dri2_surf->dri_drawable); -#endif - - return EGL_TRUE; -} - -static _EGLImage * -dri2_create_image(_EGLDisplay *disp, __DRIimage *dri_image) -{ - struct dri2_egl_image *dri2_img; - - if (dri_image == NULL) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image"); - return NULL; - } - - dri2_img = malloc(sizeof *dri2_img); - if (!dri2_img) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image"); - return NULL; - } - - if (!_eglInitImage(&dri2_img->base, disp)) { - free(dri2_img); - return NULL; - } - - dri2_img->dri_image = dri_image; - - return &dri2_img->base; -} - -static _EGLImage * -dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx, - EGLClientBuffer buffer, - const EGLint *attr_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); - GLuint renderbuffer = (GLuint) (uintptr_t) buffer; - __DRIimage *dri_image; - - if (renderbuffer == 0) { - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } - - dri_image = - dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context, - renderbuffer, NULL); - - return dri2_create_image(disp, dri_image); -} - -static _EGLImage * -dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx, - EGLClientBuffer buffer, const EGLint *attr_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - EGLint format, name, pitch, err; - _EGLImageAttribs attrs; - __DRIimage *dri_image; - - name = (EGLint) (uintptr_t) buffer; - - err = _eglParseImageAttribList(&attrs, disp, attr_list); - if (err != EGL_SUCCESS) - return NULL; - - if (attrs.Width <= 0 || attrs.Height <= 0 || - attrs.DRMBufferStrideMESA <= 0) { - _eglError(EGL_BAD_PARAMETER, - "bad width, height or stride"); - return NULL; - } - - switch (attrs.DRMBufferFormatMESA) { - case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: - format = __DRI_IMAGE_FORMAT_ARGB8888; - pitch = attrs.DRMBufferStrideMESA; - break; - default: - _eglError(EGL_BAD_PARAMETER, - "dri2_create_image_khr: unsupported pixmap depth"); - return NULL; - } - - dri_image = - dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, - attrs.Width, - attrs.Height, - format, - name, - pitch, - NULL); - - return dri2_create_image(disp, dri_image); -} - -#ifdef HAVE_WAYLAND_PLATFORM - -/* This structure describes how a wl_buffer maps to one or more - * __DRIimages. A wl_drm_buffer stores the wl_drm format code and the - * offsets and strides of the planes in the buffer. This table maps a - * wl_drm format code to a description of the planes in the buffer - * that lets us create a __DRIimage for each of the planes. */ - -static const struct wl_drm_components_descriptor { - uint32_t dri_components; - EGLint components; - int nplanes; -} wl_drm_components[] = { - { __DRI_IMAGE_COMPONENTS_RGB, EGL_TEXTURE_RGB, 1 }, - { __DRI_IMAGE_COMPONENTS_RGBA, EGL_TEXTURE_RGBA, 1 }, - { __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 }, - { __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 }, - { __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 }, -}; - -static _EGLImage * -dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, - EGLClientBuffer _buffer, - const EGLint *attr_list) -{ - struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - const struct wl_drm_components_descriptor *f; - __DRIimage *dri_image; - _EGLImageAttribs attrs; - EGLint err; - int32_t plane; - - if (!wayland_buffer_is_drm(&buffer->buffer)) - return NULL; - - err = _eglParseImageAttribList(&attrs, disp, attr_list); - plane = attrs.PlaneWL; - if (err != EGL_SUCCESS) { - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); - return NULL; - } - - f = buffer->driver_format; - if (plane < 0 || plane >= f->nplanes) { - _eglError(EGL_BAD_PARAMETER, - "dri2_create_image_wayland_wl_buffer (plane out of bounds)"); - return NULL; - } - - dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); - - if (dri_image == NULL) { - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); - return NULL; - } - - return dri2_create_image(disp, dri_image); -} -#endif - -/** - * Set the error code after a call to - * dri2_egl_image::dri_image::createImageFromTexture. - */ -static void -dri2_create_image_khr_texture_error(int dri_error) -{ - EGLint egl_error; - - switch (dri_error) { - case __DRI_IMAGE_ERROR_SUCCESS: - return; - - case __DRI_IMAGE_ERROR_BAD_ALLOC: - egl_error = EGL_BAD_ALLOC; - break; - - case __DRI_IMAGE_ERROR_BAD_MATCH: - egl_error = EGL_BAD_MATCH; - break; - - case __DRI_IMAGE_ERROR_BAD_PARAMETER: - egl_error = EGL_BAD_PARAMETER; - break; - - default: - assert(0); - egl_error = EGL_BAD_MATCH; - break; - } - - _eglError(egl_error, "dri2_create_image_khr_texture"); -} - -static _EGLImage * -dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attr_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); - struct dri2_egl_image *dri2_img; - GLuint texture = (GLuint) (uintptr_t) buffer; - _EGLImageAttribs attrs; - GLuint depth; - GLenum gl_target; - unsigned error; - - if (texture == 0) { - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } - - if (_eglParseImageAttribList(&attrs, disp, attr_list) != EGL_SUCCESS) - return EGL_NO_IMAGE_KHR; - - switch (target) { - case EGL_GL_TEXTURE_2D_KHR: - depth = 0; - gl_target = GL_TEXTURE_2D; - break; - case EGL_GL_TEXTURE_3D_KHR: - depth = attrs.GLTextureZOffset; - gl_target = GL_TEXTURE_3D; - break; - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: - depth = target - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; - gl_target = GL_TEXTURE_CUBE_MAP; - break; - default: - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } - - dri2_img = malloc(sizeof *dri2_img); - if (!dri2_img) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } - - if (!_eglInitImage(&dri2_img->base, disp)) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); - free(dri2_img); - return EGL_NO_IMAGE_KHR; - } - - dri2_img->dri_image = - dri2_dpy->image->createImageFromTexture(dri2_ctx->dri_context, - gl_target, - texture, - depth, - attrs.GLTextureLevel, - &error, - dri2_img); - dri2_create_image_khr_texture_error(error); - - if (!dri2_img->dri_image) { - free(dri2_img); - return EGL_NO_IMAGE_KHR; - } - return &dri2_img->base; -} - -_EGLImage * -dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, - _EGLContext *ctx, EGLenum target, - EGLClientBuffer buffer, const EGLint *attr_list) -{ - (void) drv; - - switch (target) { - case EGL_GL_TEXTURE_2D_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: - case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: - return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list); - case EGL_GL_RENDERBUFFER_KHR: - return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list); - case EGL_DRM_BUFFER_MESA: - return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list); -#ifdef HAVE_WAYLAND_PLATFORM - case EGL_WAYLAND_BUFFER_WL: - return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list); -#endif - default: - _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } -} - -static EGLBoolean -dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_image *dri2_img = dri2_egl_image(image); - - (void) drv; - - dri2_dpy->image->destroyImage(dri2_img->dri_image); - free(dri2_img); - - return EGL_TRUE; -} - -static _EGLImage * -dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, - const EGLint *attr_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_image *dri2_img; - _EGLImageAttribs attrs; - unsigned int dri_use, valid_mask; - int format; - EGLint err = EGL_SUCCESS; - - (void) drv; - - dri2_img = malloc(sizeof *dri2_img); - if (!dri2_img) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr"); - return EGL_NO_IMAGE_KHR; - } - - if (!attr_list) { - err = EGL_BAD_PARAMETER; - goto cleanup_img; - } - - if (!_eglInitImage(&dri2_img->base, disp)) { - err = EGL_BAD_PARAMETER; - goto cleanup_img; - } - - err = _eglParseImageAttribList(&attrs, disp, attr_list); - if (err != EGL_SUCCESS) - goto cleanup_img; - - if (attrs.Width <= 0 || attrs.Height <= 0) { - _eglLog(_EGL_WARNING, "bad width or height (%dx%d)", - attrs.Width, attrs.Height); - goto cleanup_img; - } - - switch (attrs.DRMBufferFormatMESA) { - case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA: - format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - default: - _eglLog(_EGL_WARNING, "bad image format value 0x%04x", - attrs.DRMBufferFormatMESA); - goto cleanup_img; - } - - valid_mask = - EGL_DRM_BUFFER_USE_SCANOUT_MESA | - EGL_DRM_BUFFER_USE_SHARE_MESA | - EGL_DRM_BUFFER_USE_CURSOR_MESA; - if (attrs.DRMBufferUseMESA & ~valid_mask) { - _eglLog(_EGL_WARNING, "bad image use bit 0x%04x", - attrs.DRMBufferUseMESA & ~valid_mask); - goto cleanup_img; - } - - dri_use = 0; - if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA) - dri_use |= __DRI_IMAGE_USE_SHARE; - if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) - dri_use |= __DRI_IMAGE_USE_SCANOUT; - if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) - dri_use |= __DRI_IMAGE_USE_CURSOR; - - dri2_img->dri_image = - dri2_dpy->image->createImage(dri2_dpy->dri_screen, - attrs.Width, attrs.Height, - format, dri_use, dri2_img); - if (dri2_img->dri_image == NULL) { - err = EGL_BAD_ALLOC; - goto cleanup_img; - } - - return &dri2_img->base; - - cleanup_img: - free(dri2_img); - _eglError(err, "dri2_create_drm_image_mesa"); - - return EGL_NO_IMAGE_KHR; -} - -static EGLBoolean -dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, - EGLint *name, EGLint *handle, EGLint *stride) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_image *dri2_img = dri2_egl_image(img); - - (void) drv; - - if (name && !dri2_dpy->image->queryImage(dri2_img->dri_image, - __DRI_IMAGE_ATTRIB_NAME, name)) { - _eglError(EGL_BAD_ALLOC, "dri2_export_drm_image_mesa"); - return EGL_FALSE; - } - - if (handle) - dri2_dpy->image->queryImage(dri2_img->dri_image, - __DRI_IMAGE_ATTRIB_HANDLE, handle); - - if (stride) - dri2_dpy->image->queryImage(dri2_img->dri_image, - __DRI_IMAGE_ATTRIB_STRIDE, stride); - - return EGL_TRUE; -} - -#ifdef HAVE_WAYLAND_PLATFORM - -static void -dri2_wl_reference_buffer(void *user_data, uint32_t name, int fd, - struct wl_drm_buffer *buffer) -{ - _EGLDisplay *disp = user_data; - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - __DRIimage *img; - int i, dri_components = 0; - - if (fd == -1) - img = dri2_dpy->image->createImageFromNames(dri2_dpy->dri_screen, - buffer->buffer.width, - buffer->buffer.height, - buffer->format, - (int*)&name, 1, - buffer->stride, - buffer->offset, - NULL); - else - img = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, - buffer->buffer.width, - buffer->buffer.height, - buffer->format, - &fd, 1, - buffer->stride, - buffer->offset, - NULL); - - if (img == NULL) - return; - - dri2_dpy->image->queryImage(img, __DRI_IMAGE_ATTRIB_COMPONENTS, &dri_components); - - buffer->driver_format = NULL; - for (i = 0; i < ARRAY_SIZE(wl_drm_components); i++) - if (wl_drm_components[i].dri_components == dri_components) - buffer->driver_format = &wl_drm_components[i]; - - if (buffer->driver_format == NULL) - dri2_dpy->image->destroyImage(img); - else - buffer->driver_buffer = img; -} - -static void -dri2_wl_release_buffer(void *user_data, struct wl_drm_buffer *buffer) -{ - _EGLDisplay *disp = user_data; - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - dri2_dpy->image->destroyImage(buffer->driver_buffer); -} - -static struct wayland_drm_callbacks wl_drm_callbacks = { - .authenticate = NULL, - .reference_buffer = dri2_wl_reference_buffer, - .release_buffer = dri2_wl_release_buffer -}; - -static EGLBoolean -dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, - struct wl_display *wl_dpy) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - int ret, flags = 0; - uint64_t cap; - - (void) drv; - - if (dri2_dpy->wl_server_drm) - return EGL_FALSE; - - wl_drm_callbacks.authenticate = - (int(*)(void *, uint32_t)) dri2_dpy->authenticate; - - ret = drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap); - if (ret == 0 && cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) && - dri2_dpy->image->base.version >= 7 && - dri2_dpy->image->createImageFromFds != NULL) - flags |= WAYLAND_DRM_PRIME; - - dri2_dpy->wl_server_drm = - wayland_drm_init(wl_dpy, dri2_dpy->device_name, - &wl_drm_callbacks, disp, flags); - - if (!dri2_dpy->wl_server_drm) - return EGL_FALSE; - - return EGL_TRUE; -} - -static EGLBoolean -dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp, - struct wl_display *wl_dpy) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - (void) drv; - - if (!dri2_dpy->wl_server_drm) - return EGL_FALSE; - - wayland_drm_uninit(dri2_dpy->wl_server_drm); - dri2_dpy->wl_server_drm = NULL; - - return EGL_TRUE; -} - -static EGLBoolean -dri2_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *disp, - struct wl_buffer *_buffer, - EGLint attribute, EGLint *value) -{ - struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer; - const struct wl_drm_components_descriptor *format; - - if (!wayland_buffer_is_drm(&buffer->buffer)) - return EGL_FALSE; - - format = buffer->driver_format; - switch (attribute) { - case EGL_TEXTURE_FORMAT: - *value = format->components; - return EGL_TRUE; - case EGL_WIDTH: - *value = buffer->buffer.width; - return EGL_TRUE; - case EGL_HEIGHT: - *value = buffer->buffer.height; - return EGL_TRUE; - } - - return EGL_FALSE; -} -#endif - -static void -dri2_unload(_EGLDriver *drv) -{ - struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - -// if (dri2_drv->handle) -// dlclose(dri2_drv->handle); - free(dri2_drv); -} - -static EGLBoolean -dri2_load(_EGLDriver *drv) -{ - struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - const char *libname = "libGL.dll"; - - lib_handle handle; - - handle = load_library(libname); - if (handle) { - dri2_drv->get_proc_address = (_EGLProc (*)(const char *)) - get_proc_address(handle, "_glapi_get_proc_address"); - if (!dri2_drv->get_proc_address) { - /* no need to keep a reference */ - handle = 0; - } - } - - /* if glapi is not available, loading DRI drivers will fail */ - if (!dri2_drv->get_proc_address) { - _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address"); - return EGL_FALSE; - } - - dri2_drv->glFlush = (void (*)(void)) - dri2_drv->get_proc_address("glFlush"); - - dri2_drv->handle = (void*)handle; - - return EGL_TRUE; -} - -/** - * This is the main entrypoint into the driver, called by libEGL. - * Create a new _EGLDriver object and init its dispatch table. - */ -_EGLDriver * -_eglBuiltInDriverDRI2(const char *args) -{ - struct dri2_egl_driver *dri2_drv; - - (void) args; - - dri2_drv = calloc(1, sizeof *dri2_drv); - if (!dri2_drv) - return NULL; - - if (!dri2_load(&dri2_drv->base)) { - free(dri2_drv); - return NULL; - } - - _eglInitDriverFallbacks(&dri2_drv->base); - dri2_drv->base.API.Initialize = dri2_initialize; - dri2_drv->base.API.Terminate = dri2_terminate; - dri2_drv->base.API.CreateContext = dri2_create_context; - dri2_drv->base.API.DestroyContext = dri2_destroy_context; - dri2_drv->base.API.MakeCurrent = dri2_make_current; - dri2_drv->base.API.GetProcAddress = dri2_get_proc_address; - dri2_drv->base.API.WaitClient = dri2_wait_client; - dri2_drv->base.API.WaitNative = dri2_wait_native; - dri2_drv->base.API.BindTexImage = dri2_bind_tex_image; - dri2_drv->base.API.ReleaseTexImage = dri2_release_tex_image; - dri2_drv->base.API.CreateImageKHR = dri2_create_image_khr; - dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr; - dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa; - dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa; -#ifdef HAVE_WAYLAND_PLATFORM - dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl; - dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl; - dri2_drv->base.API.QueryWaylandBufferWL = dri2_query_wayland_buffer_wl; -#endif - - dri2_drv->base.Name = "DRI2"; - dri2_drv->base.Unload = dri2_unload; - - return &dri2_drv->base; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/platform_drm.c.bak b/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/platform_drm.c.bak deleted file mode 100644 index c1a8d7f2a5..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/drivers/dri2/platform_drm.c.bak +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Kristian Høgsberg - */ - -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include - -#define EGL_EGLEXT_PROTOTYPES -#include -#include - -#include "egl_dri2.h" - -int sna_bitmap_from_handle(bitmap_t *bitmap, uint32_t handle); -void sna_set_bo_handle(bitmap_t *bitmap, int handle); -int sna_blit_tex(bitmap_t *bitmap, int scale, int dst_x, int dst_y, - int w, int h, int src_x, int src_y); - -static struct gbm_bo * -lock_front_buffer(struct gbm_surface *_surf) -{ - struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf; - struct dri2_egl_surface *dri2_surf = surf->dri_private; - struct gbm_bo *bo; - - if (dri2_surf->current == NULL) { - _eglError(EGL_BAD_SURFACE, "no front buffer"); - return NULL; - } - - bo = dri2_surf->current->bo; - dri2_surf->current->locked = 1; - dri2_surf->current = NULL; - - return bo; -} - -static void -release_buffer(struct gbm_surface *_surf, struct gbm_bo *bo) -{ - struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf; - struct dri2_egl_surface *dri2_surf = surf->dri_private; - int i; - - for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { - if (dri2_surf->color_buffers[i].bo == bo) { - dri2_surf->color_buffers[i].locked = 0; - } - } -} - -static int -has_free_buffers(struct gbm_surface *_surf) -{ - struct gbm_dri_surface *surf = (struct gbm_dri_surface *) _surf; - struct dri2_egl_surface *dri2_surf = surf->dri_private; - int i; - - for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) - if (!dri2_surf->color_buffers[i].locked) - return 1; - - return 0; -} - -static _EGLSurface * -dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, - _EGLConfig *conf, EGLNativeWindowType window, - const EGLint *attrib_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); - struct dri2_egl_surface *dri2_surf; - struct gbm_dri_surface *surf; - - (void) drv; - - dri2_surf = calloc(1, sizeof *dri2_surf); - if (!dri2_surf) { - _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); - return NULL; - } - - if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) - goto cleanup_surf; - - switch (type) { - case EGL_WINDOW_BIT: - if (!window) - return NULL; - surf = gbm_dri_surface((struct gbm_surface *) window); - dri2_surf->gbm_surf = surf; - dri2_surf->base.Width = surf->base.width; - dri2_surf->base.Height = surf->base.height; - surf->dri_private = dri2_surf; - break; - default: - goto cleanup_surf; - } - - dri2_surf->dri_drawable = - (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, - dri2_conf->dri_double_config, - dri2_surf->gbm_surf); - - if (dri2_surf->dri_drawable == NULL) { - _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); - goto cleanup_surf; - } - - return &dri2_surf->base; - - cleanup_surf: - free(dri2_surf); - - return NULL; -} - -static _EGLSurface * -dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, - _EGLConfig *conf, EGLNativeWindowType window, - const EGLint *attrib_list) -{ - return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf, - window, attrib_list); -} - -static EGLBoolean -dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); - int i; - - if (!_eglPutSurface(surf)) - return EGL_TRUE; - - (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); - - for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { - if (dri2_surf->color_buffers[i].bo) - gbm_bo_destroy(dri2_surf->color_buffers[i].bo); - } - - for (i = 0; i < __DRI_BUFFER_COUNT; i++) { - if (dri2_surf->dri_buffers[i]) - dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, - dri2_surf->dri_buffers[i]); - } - - free(surf); - - return EGL_TRUE; -} - -static int -get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer) -{ - struct dri2_egl_display *dri2_dpy = - dri2_egl_display(dri2_surf->base.Resource.Display); - struct gbm_dri_bo *bo; - struct gbm_dri_surface *surf = dri2_surf->gbm_surf; - int i, name, pitch; - - if (dri2_surf->back == NULL) { - for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { - if (!dri2_surf->color_buffers[i].locked) { - dri2_surf->back = &dri2_surf->color_buffers[i]; - break; - } - } - } - - if (dri2_surf->back == NULL) - return -1; - if (dri2_surf->back->bo == NULL) - dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base.base, - surf->base.width, surf->base.height, - surf->base.format, surf->base.flags); - if (dri2_surf->back->bo == NULL) - return -1; - - bo = (struct gbm_dri_bo *) dri2_surf->back->bo; - - dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name); - dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch); - - buffer->attachment = __DRI_BUFFER_BACK_LEFT; - buffer->name = name; - buffer->pitch = pitch; - buffer->cpp = 4; - buffer->flags = 0; - - return 0; -} - -static int -get_aux_bo(struct dri2_egl_surface *dri2_surf, - unsigned int attachment, unsigned int format, __DRIbuffer *buffer) -{ - struct dri2_egl_display *dri2_dpy = - dri2_egl_display(dri2_surf->base.Resource.Display); - __DRIbuffer *b = dri2_surf->dri_buffers[attachment]; - - if (b == NULL) { - b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, - attachment, format, - dri2_surf->base.Width, - dri2_surf->base.Height); - dri2_surf->dri_buffers[attachment] = b; - } - if (b == NULL) - return -1; - - memcpy(buffer, b, sizeof *buffer); - - return 0; -} - -static __DRIbuffer * -dri2_get_buffers_with_format(__DRIdrawable *driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *loaderPrivate) -{ - struct dri2_egl_surface *dri2_surf = loaderPrivate; - int i, j; - - dri2_surf->buffer_count = 0; - for (i = 0, j = 0; i < 2 * count; i += 2, j++) { - assert(attachments[i] < __DRI_BUFFER_COUNT); - assert(dri2_surf->buffer_count < 5); - - switch (attachments[i]) { - case __DRI_BUFFER_BACK_LEFT: - if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) { - _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer"); - return NULL; - } - break; - default: - if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1], - &dri2_surf->buffers[j]) < 0) { - _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer"); - return NULL; - } - break; - } - } - - *out_count = j; - if (j == 0) - return NULL; - - *width = dri2_surf->base.Width; - *height = dri2_surf->base.Height; - - return dri2_surf->buffers; -} - -static __DRIbuffer * -dri2_get_buffers(__DRIdrawable * driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *loaderPrivate) -{ - unsigned int *attachments_with_format; - __DRIbuffer *buffer; - const unsigned int format = 32; - int i; - - attachments_with_format = calloc(count * 2, sizeof(unsigned int)); - if (!attachments_with_format) { - *out_count = 0; - return NULL; - } - - for (i = 0; i < count; ++i) { - attachments_with_format[2*i] = attachments[i]; - attachments_with_format[2*i + 1] = format; - } - - buffer = - dri2_get_buffers_with_format(driDrawable, - width, height, - attachments_with_format, count, - out_count, loaderPrivate); - - free(attachments_with_format); - - return buffer; -} - -static void -dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) -{ - (void) driDrawable; - (void) loaderPrivate; -} - -static EGLBoolean -dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); - __DRIbuffer buffer; - static bitmap_t bm; - - int i; - - if (dri2_surf->base.Type == EGL_WINDOW_BIT) { - if (dri2_surf->current) - _eglError(EGL_BAD_SURFACE, "dri2_swap_buffers"); - for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) - if (dri2_surf->color_buffers[i].age > 0) - dri2_surf->color_buffers[i].age++; - - if ( (dri2_surf->back != NULL) && - (dri2_surf->back->bo != NULL)) - { - struct gbm_dri_bo *bo; - bo = (struct gbm_dri_bo *)dri2_surf->back->bo; - - if(bm.width == 0) - { - printf("%s bo: %p handle: %d width: %d height: %d pitch %d format %x\n", - __FUNCTION__, bo, bo->base.base.handle.s32, bo->base.base.width, - bo->base.base.height, (int)bo->base.base.stride, - bo->base.base.format); - - bm.width = bo->base.base.width; - bm.height = bo->base.base.height; - bm.pitch = (int)bo->base.base.stride; - bm.max_width = bo->base.base.width; - bm.max_height = bo->base.base.height; - bm.flags = HW_TEX_BLIT; - - if( sna_bitmap_from_handle(&bm, bo->base.base.handle.s32)) - { - printf("sna_bitmap_from_handle failed\n"); - } - } - if( bm.handle != 0) - { - sna_set_bo_handle(&bm, bo->base.base.handle.s32); - sna_blit_tex(&bm, 0, 5, 22, bm.width, bm.height, 0, 0); - } - } - - dri2_surf->current = dri2_surf->back; - dri2_surf->current->age = 1; - dri2_surf->back = NULL; - } - - (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); - (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); - - return EGL_TRUE; -} - -static EGLint -dri2_query_buffer_age(_EGLDriver *drv, - _EGLDisplay *disp, _EGLSurface *surface) -{ - struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); - __DRIbuffer buffer; - - if (get_back_bo(dri2_surf, &buffer) < 0) { - _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); - return 0; - } - - return dri2_surf->back->age; -} - -static _EGLImage * -dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, - EGLClientBuffer buffer, const EGLint *attr_list) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer); - struct dri2_egl_image *dri2_img; - - dri2_img = malloc(sizeof *dri2_img); - if (!dri2_img) { - _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); - return NULL; - } - - if (!_eglInitImage(&dri2_img->base, disp)) { - free(dri2_img); - return NULL; - } - - dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img); - if (dri2_img->dri_image == NULL) { - free(dri2_img); - _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap"); - return NULL; - } - - return &dri2_img->base; -} - -static _EGLImage * -dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, - _EGLContext *ctx, EGLenum target, - EGLClientBuffer buffer, const EGLint *attr_list) -{ - (void) drv; - - switch (target) { - case EGL_NATIVE_PIXMAP_KHR: - return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list); - default: - return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); - } -} - -#if 0 -static int -dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id) -{ - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - return drmAuthMagic(dri2_dpy->fd, id); -} -#endif - -EGLBoolean -dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) -{ - struct dri2_egl_display *dri2_dpy; - struct gbm_device *gbm; - int fd = -1; - int i; - - dri2_dpy = calloc(1, sizeof *dri2_dpy); - if (!dri2_dpy) - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - - disp->DriverData = (void *) dri2_dpy; - - gbm = disp->PlatformDisplay; - if (gbm == NULL) { - fd = get_service("DISPLAY"); - dri2_dpy->own_device = 1; - gbm = gbm_create_device(fd); - if (gbm == NULL) - return EGL_FALSE; - } - - if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) { - free(dri2_dpy); - return EGL_FALSE; - } - - dri2_dpy->gbm_dri = gbm_dri_device(gbm); - if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) { - free(dri2_dpy); - return EGL_FALSE; - } - - dri2_dpy->fd = fd; - dri2_dpy->device_name = strdup("drm device"); //dri2_get_device_name_for_fd(dri2_dpy->fd); - dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name; - - dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen; - dri2_dpy->core = dri2_dpy->gbm_dri->core; - dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2; - dri2_dpy->image = dri2_dpy->gbm_dri->image; - dri2_dpy->flush = dri2_dpy->gbm_dri->flush; - dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs; - - dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image; - dri2_dpy->gbm_dri->lookup_user_data = disp; - - dri2_dpy->gbm_dri->get_buffers = dri2_get_buffers; - dri2_dpy->gbm_dri->flush_front_buffer = dri2_flush_front_buffer; - dri2_dpy->gbm_dri->get_buffers_with_format = dri2_get_buffers_with_format; - - dri2_dpy->gbm_dri->base.base.surface_lock_front_buffer = lock_front_buffer; - dri2_dpy->gbm_dri->base.base.surface_release_buffer = release_buffer; - dri2_dpy->gbm_dri->base.base.surface_has_free_buffers = has_free_buffers; - - dri2_setup_screen(disp); - - for (i = 0; dri2_dpy->driver_configs[i]; i++) - dri2_add_config(disp, dri2_dpy->driver_configs[i], - i + 1, 0, EGL_WINDOW_BIT, NULL, NULL); - - drv->API.CreateWindowSurface = dri2_create_window_surface; - drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface; - drv->API.DestroySurface = dri2_destroy_surface; - drv->API.SwapBuffers = dri2_swap_buffers; - drv->API.CreateImageKHR = dri2_drm_create_image_khr; - drv->API.QueryBufferAge = dri2_query_buffer_age; - - disp->Extensions.EXT_buffer_age = EGL_TRUE; - -#ifdef HAVE_WAYLAND_PLATFORM - disp->Extensions.WL_bind_wayland_display = EGL_TRUE; -#endif -// dri2_dpy->authenticate = dri2_drm_authenticate; - - /* we're supporting EGL 1.4 */ - disp->VersionMajor = 1; - disp->VersionMinor = 4; - - return EGL_TRUE; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglapi.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglapi.c.bak deleted file mode 100644 index 7984fb2ca7..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglapi.c.bak +++ /dev/null @@ -1,1614 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010-2011 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Public EGL API entrypoints - * - * Generally, we use the EGLDisplay parameter as a key to lookup the - * appropriate device driver handle, then jump though the driver's - * dispatch table to handle the function. - * - * That allows us the option of supporting multiple, simultaneous, - * heterogeneous hardware devices in the future. - * - * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are - * opaque handles. Internal objects are linked to a display to - * create the handles. - * - * For each public API entry point, the opaque handles are looked up - * before being dispatched to the drivers. When it fails to look up - * a handle, one of - * - * EGL_BAD_DISPLAY - * EGL_BAD_CONFIG - * EGL_BAD_CONTEXT - * EGL_BAD_SURFACE - * EGL_BAD_SCREEN_MESA - * EGL_BAD_MODE_MESA - * - * is generated and the driver function is not called. An - * uninitialized EGLDisplay has no driver associated with it. When - * such display is detected, - * - * EGL_NOT_INITIALIZED - * - * is generated. - * - * Some of the entry points use current display, context, or surface - * implicitly. For such entry points, the implicit objects are also - * checked before calling the driver function. Other than the - * errors listed above, - * - * EGL_BAD_CURRENT_SURFACE - * - * may also be generated. - * - * Notes on naming conventions: - * - * eglFooBar - public EGL function - * EGL_FOO_BAR - public EGL token - * EGLDatatype - public EGL datatype - * - * _eglFooBar - private EGL function - * _EGLDatatype - private EGL datatype, typedef'd struct - * _egl_struct - private EGL struct, non-typedef'd - * - */ - - -#include -#include -#include - -#include "eglcontext.h" -#include "egldisplay.h" -#include "egltypedefs.h" -#include "eglcurrent.h" -#include "egldriver.h" -#include "eglsurface.h" -#include "eglconfig.h" -#include "eglscreen.h" -#include "eglmode.h" -#include "eglimage.h" -#include "eglsync.h" - - -/** - * Macros to help return an API entrypoint. - * - * These macros will unlock the display and record the error code. - */ -#define RETURN_EGL_ERROR(disp, err, ret) \ - do { \ - if (disp) \ - _eglUnlockDisplay(disp); \ - /* EGL error codes are non-zero */ \ - if (err) \ - _eglError(err, __FUNCTION__); \ - return ret; \ - } while (0) - -#define RETURN_EGL_SUCCESS(disp, ret) \ - RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret) - -/* record EGL_SUCCESS only when ret evaluates to true */ -#define RETURN_EGL_EVAL(disp, ret) \ - RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) - - -/* - * A bunch of macros and checks to simplify error checking. - */ - -#define _EGL_CHECK_DISPLAY(disp, ret, drv) \ - do { \ - drv = _eglCheckDisplay(disp, __FUNCTION__); \ - if (!drv) \ - RETURN_EGL_ERROR(disp, 0, ret); \ - } while (0) - -#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \ - do { \ - drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ - if (!drv) \ - RETURN_EGL_ERROR(disp, 0, ret); \ - } while (0) - -#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv) - -#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Context, context, ret, drv) - -#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv) - -#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv) - -#define _EGL_CHECK_MODE(disp, m, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv) - -#define _EGL_CHECK_SYNC(disp, s, ret, drv) \ - _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv) - - -static INLINE _EGLDriver * -_eglCheckDisplay(_EGLDisplay *disp, const char *msg) -{ - if (!disp) { - _eglError(EGL_BAD_DISPLAY, msg); - return NULL; - } - if (!disp->Initialized) { - _eglError(EGL_NOT_INITIALIZED, msg); - return NULL; - } - return disp->Driver; -} - - -static INLINE _EGLDriver * -_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!surf) { - _eglError(EGL_BAD_SURFACE, msg); - return NULL; - } - return drv; -} - - -static INLINE _EGLDriver * -_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!context) { - _eglError(EGL_BAD_CONTEXT, msg); - return NULL; - } - return drv; -} - - -static INLINE _EGLDriver * -_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!conf) { - _eglError(EGL_BAD_CONFIG, msg); - return NULL; - } - return drv; -} - - -static INLINE _EGLDriver * -_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!s) { - _eglError(EGL_BAD_PARAMETER, msg); - return NULL; - } - return drv; -} - - -#ifdef EGL_MESA_screen_surface - - -static INLINE _EGLDriver * -_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!scrn) { - _eglError(EGL_BAD_SCREEN_MESA, msg); - return NULL; - } - return drv; -} - - -static INLINE _EGLDriver * -_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) -{ - _EGLDriver *drv = _eglCheckDisplay(disp, msg); - if (!drv) - return NULL; - if (!m) { - _eglError(EGL_BAD_MODE_MESA, msg); - return NULL; - } - return drv; -} - - -#endif /* EGL_MESA_screen_surface */ - - -/** - * Lookup and lock a display. - */ -static INLINE _EGLDisplay * -_eglLockDisplay(EGLDisplay display) -{ - _EGLDisplay *dpy = _eglLookupDisplay(display); - if (dpy) - _eglLockMutex(&dpy->Mutex); - return dpy; -} - - -/** - * Unlock a display. - */ -static INLINE void -_eglUnlockDisplay(_EGLDisplay *dpy) -{ - _eglUnlockMutex(&dpy->Mutex); -} - - -/** - * This is typically the first EGL function that an application calls. - * It associates a private _EGLDisplay object to the native display. - */ -EGLDisplay EGLAPIENTRY -eglGetDisplay(EGLNativeDisplayType nativeDisplay) -{ - _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay); - _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay); - return _eglGetDisplayHandle(dpy); -} - - -/** - * This is typically the second EGL function that an application calls. - * Here we load/initialize the actual hardware driver. - */ -EGLBoolean EGLAPIENTRY -eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - - if (!disp) - RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); - - if (!disp->Initialized) { - if (!_eglMatchDriver(disp, EGL_FALSE)) - RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); - - /* limit to APIs supported by core */ - disp->ClientAPIs &= _EGL_API_ALL_BITS; - } - - /* Update applications version of major and minor if not NULL */ - if ((major != NULL) && (minor != NULL)) { - *major = disp->VersionMajor; - *minor = disp->VersionMinor; - } - - RETURN_EGL_SUCCESS(disp, EGL_TRUE); -} - - -EGLBoolean EGLAPIENTRY -eglTerminate(EGLDisplay dpy) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - - if (!disp) - RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); - - if (disp->Initialized) { - _EGLDriver *drv = disp->Driver; - - drv->API.Terminate(drv, disp); - /* do not reset disp->Driver */ - disp->Initialized = EGL_FALSE; - } - - RETURN_EGL_SUCCESS(disp, EGL_TRUE); -} - - -const char * EGLAPIENTRY -eglQueryString(EGLDisplay dpy, EGLint name) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - const char *ret; - - _EGL_CHECK_DISPLAY(disp, NULL, drv); - ret = drv->API.QueryString(drv, disp, name); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, - EGLint config_size, EGLint *num_config) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, - EGLint config_size, EGLint *num_config) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, - config_size, num_config); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv); - ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLContext EGLAPIENTRY -eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, - const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLContext *share = _eglLookupContext(share_list, disp); - _EGLDriver *drv; - _EGLContext *context; - EGLContext ret; - - _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv); - - if (!config) { - /* config may be NULL if surfaceless */ - if (!disp->Extensions.KHR_surfaceless_context) - RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT); - } - - if (!share && share_list != EGL_NO_CONTEXT) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); - - context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); - ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglDestroyContext(EGLDisplay dpy, EGLContext ctx) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *context = _eglLookupContext(ctx, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); - _eglUnlinkContext(context); - ret = drv->API.DestroyContext(drv, disp, context); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, - EGLContext ctx) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *context = _eglLookupContext(ctx, disp); - _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); - _EGLSurface *read_surf = _eglLookupSurface(read, disp); - _EGLDriver *drv; - EGLBoolean ret; - - if (!disp) - RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); - drv = disp->Driver; - - /* display is allowed to be uninitialized under certain condition */ - if (!disp->Initialized) { - if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || - ctx != EGL_NO_CONTEXT) - RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); - } - if (!drv) - RETURN_EGL_SUCCESS(disp, EGL_TRUE); - - if (!context && ctx != EGL_NO_CONTEXT) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); - if (!draw_surf || !read_surf) { - /* surfaces may be NULL if surfaceless */ - if (!disp->Extensions.KHR_surfaceless_context) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - - if ((!draw_surf && draw != EGL_NO_SURFACE) || - (!read_surf && read != EGL_NO_SURFACE)) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - if (draw_surf || read_surf) - RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE); - } - - ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryContext(EGLDisplay dpy, EGLContext ctx, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *context = _eglLookupContext(ctx, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv); - ret = drv->API.QueryContext(drv, disp, context, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLSurface EGLAPIENTRY -eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, - EGLNativeWindowType window, const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay)) - RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); - - surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLSurface EGLAPIENTRY -eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, - EGLNativePixmapType pixmap, const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay)) - RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE); - - surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLSurface EGLAPIENTRY -eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - - surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); - - printf("%s surface: %p\n", __FUNCTION__, surf); - - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglDestroySurface(EGLDisplay dpy, EGLSurface surface) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - _eglUnlinkSurface(surf); - ret = drv->API.DestroySurface(drv, disp, surf); - - RETURN_EGL_EVAL(disp, ret); -} - -EGLBoolean EGLAPIENTRY -eglQuerySurface(EGLDisplay dpy, EGLSurface surface, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - -EGLBoolean EGLAPIENTRY -eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, - EGLint attribute, EGLint value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - ret = drv->API.BindTexImage(drv, disp, surf, buffer); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglSwapInterval(EGLDisplay dpy, EGLint interval) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLSurface *surf; - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - ctx->Resource.Display != disp) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); - - surf = ctx->DrawSurface; - if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - - ret = drv->API.SwapInterval(drv, disp, surf, interval); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - - /* surface must be bound to current context in EGL 1.4 */ - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - surf != ctx->DrawSurface) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - - ret = drv->API.SwapBuffers(drv, disp, surf); - - RETURN_EGL_EVAL(disp, ret); -} - - -#ifdef EGL_EXT_swap_buffers_with_damage - -EGLBoolean EGLAPIENTRY -eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface, - EGLint *rects, EGLint n_rects) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - - /* surface must be bound to current context in EGL 1.4 */ - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - surf != ctx->DrawSurface) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - - if ((n_rects > 0 && rects == NULL) || n_rects < 0) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects); - - RETURN_EGL_EVAL(disp, ret); -} - -#endif /* EGL_EXT_swap_buffers_with_damage */ - -EGLBoolean EGLAPIENTRY -eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay)) - RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE); - ret = drv->API.CopyBuffers(drv, disp, surf, target); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglWaitClient(void) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLDisplay *disp; - _EGLDriver *drv; - EGLBoolean ret; - - if (!ctx) - RETURN_EGL_SUCCESS(NULL, EGL_TRUE); - - disp = ctx->Resource.Display; - _eglLockMutex(&disp->Mutex); - - /* let bad current context imply bad current surface */ - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) - RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); - - /* a valid current context implies an initialized current display */ - assert(disp->Initialized); - drv = disp->Driver; - ret = drv->API.WaitClient(drv, disp, ctx); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglWaitGL(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = t->CurrentAPIIndex; - EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); - EGLBoolean ret; - - if (api_index != es_index && _eglIsCurrentThreadDummy()) - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); - - t->CurrentAPIIndex = es_index; - ret = eglWaitClient(); - t->CurrentAPIIndex = api_index; - return ret; -} - - -EGLBoolean EGLAPIENTRY -eglWaitNative(EGLint engine) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLDisplay *disp; - _EGLDriver *drv; - EGLBoolean ret; - - if (!ctx) - RETURN_EGL_SUCCESS(NULL, EGL_TRUE); - - disp = ctx->Resource.Display; - _eglLockMutex(&disp->Mutex); - - /* let bad current context imply bad current surface */ - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE) - RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); - - /* a valid current context implies an initialized current display */ - assert(disp->Initialized); - drv = disp->Driver; - ret = drv->API.WaitNative(drv, disp, engine); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLDisplay EGLAPIENTRY -eglGetCurrentDisplay(void) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - EGLDisplay ret; - - ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; - - RETURN_EGL_SUCCESS(NULL, ret); -} - - -EGLContext EGLAPIENTRY -eglGetCurrentContext(void) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - EGLContext ret; - - ret = _eglGetContextHandle(ctx); - - RETURN_EGL_SUCCESS(NULL, ret); -} - - -EGLSurface EGLAPIENTRY -eglGetCurrentSurface(EGLint readdraw) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - EGLint err = EGL_SUCCESS; - _EGLSurface *surf; - EGLSurface ret; - - if (!ctx) - RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE); - - switch (readdraw) { - case EGL_DRAW: - surf = ctx->DrawSurface; - break; - case EGL_READ: - surf = ctx->ReadSurface; - break; - default: - surf = NULL; - err = EGL_BAD_PARAMETER; - break; - } - - ret = _eglGetSurfaceHandle(surf); - - RETURN_EGL_ERROR(NULL, err, ret); -} - - -EGLint EGLAPIENTRY -eglGetError(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint e = t->LastError; - if (!_eglIsCurrentThreadDummy()) - t->LastError = EGL_SUCCESS; - return e; -} - - -__eglMustCastToProperFunctionPointerType EGLAPIENTRY -eglGetProcAddress(const char *procname) -{ - static const struct { - const char *name; - _EGLProc function; - } egl_functions[] = { - /* core functions should not be queryable, but, well... */ -#ifdef _EGL_GET_CORE_ADDRESSES - /* alphabetical order */ - { "eglBindAPI", (_EGLProc) eglBindAPI }, - { "eglBindTexImage", (_EGLProc) eglBindTexImage }, - { "eglChooseConfig", (_EGLProc) eglChooseConfig }, - { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, - { "eglCreateContext", (_EGLProc) eglCreateContext }, - { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, - { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, - { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, - { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, - { "eglDestroyContext", (_EGLProc) eglDestroyContext }, - { "eglDestroySurface", (_EGLProc) eglDestroySurface }, - { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, - { "eglGetConfigs", (_EGLProc) eglGetConfigs }, - { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, - { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, - { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, - { "eglGetDisplay", (_EGLProc) eglGetDisplay }, - { "eglGetError", (_EGLProc) eglGetError }, - { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, - { "eglInitialize", (_EGLProc) eglInitialize }, - { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, - { "eglQueryAPI", (_EGLProc) eglQueryAPI }, - { "eglQueryContext", (_EGLProc) eglQueryContext }, - { "eglQueryString", (_EGLProc) eglQueryString }, - { "eglQuerySurface", (_EGLProc) eglQuerySurface }, - { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, - { "eglReleaseThread", (_EGLProc) eglReleaseThread }, - { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, - { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, - { "eglSwapInterval", (_EGLProc) eglSwapInterval }, - { "eglTerminate", (_EGLProc) eglTerminate }, - { "eglWaitClient", (_EGLProc) eglWaitClient }, - { "eglWaitGL", (_EGLProc) eglWaitGL }, - { "eglWaitNative", (_EGLProc) eglWaitNative }, -#endif /* _EGL_GET_CORE_ADDRESSES */ -#ifdef EGL_MESA_screen_surface - { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA }, - { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, - { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA }, - { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA }, - { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA }, - { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA }, - { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA }, - { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA }, - { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA }, - { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA }, - { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, - { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, -#endif /* EGL_MESA_screen_surface */ -#ifdef EGL_MESA_drm_display - { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA }, -#endif - { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, - { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, - { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, - { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR }, - { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR }, - { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR }, - { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR }, -#ifdef EGL_NOK_swap_region - { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK }, -#endif -#ifdef EGL_MESA_drm_image - { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA }, - { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA }, -#endif -#ifdef EGL_WL_bind_wayland_display - { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL }, - { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL }, - { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL }, -#endif - { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV }, -#ifdef EGL_EXT_swap_buffers_with_damage - { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT }, -#endif - { NULL, NULL } - }; - EGLint i; - _EGLProc ret; - - if (!procname) - RETURN_EGL_SUCCESS(NULL, NULL); - - ret = NULL; - if (strncmp(procname, "egl", 3) == 0) { - for (i = 0; egl_functions[i].name; i++) { - if (strcmp(egl_functions[i].name, procname) == 0) { - ret = egl_functions[i].function; - break; - } - } - } - if (!ret) - ret = _eglGetDriverProc(procname); - - RETURN_EGL_SUCCESS(NULL, ret); -} - - -#ifdef EGL_MESA_screen_surface - - -/* - * EGL_MESA_screen extension - */ - -EGLBoolean EGLAPIENTRY -eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, - const EGLint *attrib_list, EGLModeMESA *modes, - EGLint modes_size, EGLint *num_modes) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, - modes, modes_size, num_modes); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, - EGLint mode_size, EGLint *num_mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv); - ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, - EGLint mask) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *source_context = _eglLookupContext(source, disp); - _EGLContext *dest_context = _eglLookupContext(dest, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv); - if (!dest_context) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); - - ret = drv->API.CopyContextMESA(drv, disp, - source_context, dest_context, mask); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, - EGLint max_screens, EGLint *num_screens) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLSurface EGLAPIENTRY -eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - - surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, - EGLSurface surface, EGLModeMESA mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - if (!surf && surface != EGL_NO_SURFACE) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - if (!m && mode != EGL_NO_MODE_MESA) - RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); - - ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen(screen, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface *surface) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); - if (ret && surface) - *surface = _eglGetSurfaceHandle(surf); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); - _EGLDriver *drv; - _EGLMode *m; - EGLBoolean ret; - - _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv); - ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); - if (ret && mode) - *mode = m->Handle; - - RETURN_EGL_EVAL(disp, ret); -} - - -const char * EGLAPIENTRY -eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLMode *m = _eglLookupMode(mode, disp); - _EGLDriver *drv; - const char *ret; - - _EGL_CHECK_MODE(disp, m, NULL, drv); - ret = drv->API.QueryModeStringMESA(drv, disp, m); - - RETURN_EGL_EVAL(disp, ret); -} - - -#endif /* EGL_MESA_screen_surface */ - - -#ifdef EGL_MESA_drm_display - -EGLDisplay EGLAPIENTRY -eglGetDRMDisplayMESA(int fd) -{ - _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd); - return _eglGetDisplayHandle(dpy); -} - -#endif /* EGL_MESA_drm_display */ - -/** - ** EGL 1.2 - **/ - -/** - * Specify the client API to use for subsequent calls including: - * eglCreateContext() - * eglGetCurrentContext() - * eglGetCurrentDisplay() - * eglGetCurrentSurface() - * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT) - * eglWaitClient() - * eglWaitNative() - * See section 3.7 "Rendering Context" in the EGL specification for details. - */ -EGLBoolean EGLAPIENTRY -eglBindAPI(EGLenum api) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - - if (_eglIsCurrentThreadDummy()) - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); - - if (!_eglIsApiValid(api)) - RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); - - t->CurrentAPIIndex = _eglConvertApiToIndex(api); - - RETURN_EGL_SUCCESS(NULL, EGL_TRUE); -} - - -/** - * Return the last value set with eglBindAPI(). - */ -EGLenum EGLAPIENTRY -eglQueryAPI(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLenum ret; - - /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ - ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); - - RETURN_EGL_SUCCESS(NULL, ret); -} - - -EGLSurface EGLAPIENTRY -eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, - EGLClientBuffer buffer, EGLConfig config, - const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLConfig *conf = _eglLookupConfig(config, disp); - _EGLDriver *drv; - _EGLSurface *surf; - EGLSurface ret; - - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv); - - surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, - conf, attrib_list); - ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglReleaseThread(void) -{ - /* unbind current contexts */ - if (!_eglIsCurrentThreadDummy()) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - EGLint api_index = t->CurrentAPIIndex; - EGLint i; - - for (i = 0; i < _EGL_API_NUM_APIS; i++) { - _EGLContext *ctx = t->CurrentContexts[i]; - if (ctx) { - _EGLDisplay *disp = ctx->Resource.Display; - _EGLDriver *drv; - - t->CurrentAPIIndex = i; - - _eglLockMutex(&disp->Mutex); - drv = disp->Driver; - (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); - _eglUnlockMutex(&disp->Mutex); - } - } - - t->CurrentAPIIndex = api_index; - } - - _eglDestroyCurrentThread(); - - RETURN_EGL_SUCCESS(NULL, EGL_TRUE); -} - - -EGLImageKHR EGLAPIENTRY -eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, - EGLClientBuffer buffer, const EGLint *attr_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLContext *context = _eglLookupContext(ctx, disp); - _EGLDriver *drv; - _EGLImage *img; - EGLImageKHR ret; - - _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); - if (!disp->Extensions.KHR_image_base) - RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); - if (!context && ctx != EGL_NO_CONTEXT) - RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); - - img = drv->API.CreateImageKHR(drv, - disp, context, target, buffer, attr_list); - ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLImage *img = _eglLookupImage(image, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - if (!disp->Extensions.KHR_image_base) - RETURN_EGL_EVAL(disp, EGL_FALSE); - if (!img) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - _eglUnlinkImage(img); - ret = drv->API.DestroyImageKHR(drv, disp, img); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLSyncKHR EGLAPIENTRY -eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - _EGLSync *sync; - EGLSyncKHR ret; - - _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); - if (!disp->Extensions.KHR_reusable_sync) - RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); - - sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); - ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR; - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); - assert(disp->Extensions.KHR_reusable_sync); - - _eglUnlinkSync(s); - ret = drv->API.DestroySyncKHR(drv, disp, s); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLint EGLAPIENTRY -eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); - _EGLDriver *drv; - EGLint ret; - - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); - assert(disp->Extensions.KHR_reusable_sync); - ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); - assert(disp->Extensions.KHR_reusable_sync); - ret = drv->API.SignalSyncKHR(drv, disp, s, mode); - - RETURN_EGL_EVAL(disp, ret); -} - - -EGLBoolean EGLAPIENTRY -eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSync *s = _eglLookupSync(sync, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); - assert(disp->Extensions.KHR_reusable_sync); - ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} - - -#ifdef EGL_NOK_swap_region - -EGLBoolean EGLAPIENTRY -eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, - EGLint numRects, const EGLint *rects) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - - if (!disp->Extensions.NOK_swap_region) - RETURN_EGL_EVAL(disp, EGL_FALSE); - - /* surface must be bound to current context in EGL 1.4 */ - if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT || - surf != ctx->DrawSurface) - RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - - ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects); - - RETURN_EGL_EVAL(disp, ret); -} - -#endif /* EGL_NOK_swap_region */ - - -#ifdef EGL_MESA_drm_image - -EGLImageKHR EGLAPIENTRY -eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - _EGLImage *img; - EGLImageKHR ret; - - _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv); - if (!disp->Extensions.MESA_drm_image) - RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR); - - img = drv->API.CreateDRMImageMESA(drv, disp, attr_list); - ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; - - RETURN_EGL_EVAL(disp, ret); -} - -EGLBoolean EGLAPIENTRY -eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image, - EGLint *name, EGLint *handle, EGLint *stride) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLImage *img = _eglLookupImage(image, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - assert(disp->Extensions.MESA_drm_image); - - if (!img) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride); - - RETURN_EGL_EVAL(disp, ret); -} - -#endif - -#ifdef EGL_WL_bind_wayland_display -struct wl_display; - -EGLBoolean EGLAPIENTRY -eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - assert(disp->Extensions.WL_bind_wayland_display); - - if (!display) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - ret = drv->API.BindWaylandDisplayWL(drv, disp, display); - - RETURN_EGL_EVAL(disp, ret); -} - -EGLBoolean EGLAPIENTRY -eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - assert(disp->Extensions.WL_bind_wayland_display); - - if (!display) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display); - - RETURN_EGL_EVAL(disp, ret); -} - -EGLBoolean EGLAPIENTRY -eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer, - EGLint attribute, EGLint *value) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv); - assert(disp->Extensions.WL_bind_wayland_display); - - if (!buffer) - RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); - - ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value); - - RETURN_EGL_EVAL(disp, ret); -} -#endif - - -EGLBoolean EGLAPIENTRY -eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, - EGLint x, EGLint y, EGLint width, EGLint height) -{ - _EGLDisplay *disp = _eglLockDisplay(dpy); - _EGLSurface *surf = _eglLookupSurface(surface, disp); - _EGLDriver *drv; - EGLBoolean ret; - - _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv); - - if (!disp->Extensions.NV_post_sub_buffer) - RETURN_EGL_EVAL(disp, EGL_FALSE); - - ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height); - - RETURN_EGL_EVAL(disp, ret); -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglarray.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglarray.c.bak deleted file mode 100644 index f6d8f704ed..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglarray.c.bak +++ /dev/null @@ -1,213 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include - -#define EGL_EGLEXT_PROTOTYPES -#include -#include - -#include "egllog.h" -#include "eglarray.h" - - -/** - * Grow the size of the array. - */ -static EGLBoolean -_eglGrowArray(_EGLArray *array) -{ - EGLint new_size; - void **elems; - - new_size = array->MaxSize; - while (new_size <= array->Size) - new_size *= 2; - - elems = realloc(array->Elements, new_size * sizeof(array->Elements[0])); - if (!elems) { - _eglLog(_EGL_DEBUG, "failed to grow %s array to %d", - array->Name, new_size); - return EGL_FALSE; - } - - array->Elements = elems; - array->MaxSize = new_size; - - return EGL_TRUE; -} - - -/** - * Create an array. - */ -_EGLArray * -_eglCreateArray(const char *name, EGLint init_size) -{ - _EGLArray *array; - - array = calloc(1, sizeof(*array)); - if (array) { - array->Name = name; - array->MaxSize = (init_size > 0) ? init_size : 1; - if (!_eglGrowArray(array)) { - free(array); - array = NULL; - } - } - - return array; -} - - -/** - * Destroy an array, optionally free the data. - */ -void -_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *)) -{ - if (free_cb) { - EGLint i; - for (i = 0; i < array->Size; i++) - free_cb(array->Elements[i]); - } - free(array->Elements); - free(array); -} - - -/** - * Append a element to an array. - */ -void -_eglAppendArray(_EGLArray *array, void *elem) -{ - if (array->Size >= array->MaxSize && !_eglGrowArray(array)) - return; - - array->Elements[array->Size++] = elem; -} - - -/** - * Erase an element from an array. - */ -void -_eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *)) -{ - if (free_cb) - free_cb(array->Elements[i]); - if (i < array->Size - 1) { - memmove(&array->Elements[i], &array->Elements[i + 1], - (array->Size - i - 1) * sizeof(array->Elements[0])); - } - array->Size--; -} - - -/** - * Find in an array for the given element. - */ -void * -_eglFindArray(_EGLArray *array, void *elem) -{ - EGLint i; - - if (!array) - return NULL; - - for (i = 0; i < array->Size; i++) - if (array->Elements[i] == elem) - return elem; - return NULL; -} - - -/** - * Filter an array and return the number of filtered elements. - */ -EGLint -_eglFilterArray(_EGLArray *array, void **data, EGLint size, - _EGLArrayForEach filter, void *filter_data) -{ - EGLint count = 0, i; - - if (!array) - return 0; - - if (filter) { - for (i = 0; i < array->Size; i++) { - if (filter(array->Elements[i], filter_data)) { - if (data && count < size) - data[count] = array->Elements[i]; - count++; - } - if (data && count >= size) - break; - } - } - else { - if (data) { - count = (size < array->Size) ? size : array->Size; - memcpy(data, array->Elements, count * sizeof(array->Elements[0])); - } - else { - count = array->Size; - } - } - - return count; -} - - -/** - * Flatten an array by converting array elements into another form and store - * them in a buffer. - */ -EGLint -_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size, - _EGLArrayForEach flatten) -{ - EGLint i, count; - - if (!array) - return 0; - - count = array->Size; - if (buffer) { - /* do not exceed buffer size */ - if (count > size) - count = size; - for (i = 0; i < count; i++) - flatten(array->Elements[i], - (void *) ((char *) buffer + elem_size * i)); - } - - return count; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglconfig.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglconfig.c.bak deleted file mode 100644 index a2e083399a..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglconfig.c.bak +++ /dev/null @@ -1,852 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010-2011 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * EGL Configuration (pixel format) functions. - */ - - -#include -#include -#include -#include "eglconfig.h" -#include "egldisplay.h" -#include "eglcurrent.h" -#include "egllog.h" - - -#define MIN2(A, B) (((A) < (B)) ? (A) : (B)) - - -/** - * Init the given _EGLconfig to default values. - * \param id the configuration's ID. - * - * Note that id must be positive for the config to be valid. - * It is also recommended that when there are N configs, their - * IDs are from 1 to N respectively. - */ -void -_eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id) -{ - memset(conf, 0, sizeof(*conf)); - - conf->Display = dpy; - - /* some attributes take non-zero default values */ - conf->ConfigID = id; - conf->ConfigCaveat = EGL_NONE; - conf->TransparentType = EGL_NONE; - conf->NativeVisualType = EGL_NONE; - conf->ColorBufferType = EGL_RGB_BUFFER; -} - - -/** - * Link a config to its display and return the handle of the link. - * The handle can be passed to client directly. - * - * Note that we just save the ptr to the config (we don't copy the config). - */ -PUBLIC EGLConfig -_eglLinkConfig(_EGLConfig *conf) -{ - _EGLDisplay *dpy = conf->Display; - - /* sanity check */ - assert(dpy && conf->ConfigID > 0); - - if (!dpy->Configs) { - dpy->Configs = _eglCreateArray("Config", 16); - if (!dpy->Configs) - return (EGLConfig) NULL; - } - - _eglAppendArray(dpy->Configs, (void *) conf); - - return (EGLConfig) conf; -} - - -/** - * Lookup a handle to find the linked config. - * Return NULL if the handle has no corresponding linked config. - */ -_EGLConfig * -_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy) -{ - _EGLConfig *conf; - - if (!dpy) - return NULL; - - conf = (_EGLConfig *) _eglFindArray(dpy->Configs, (void *) config); - if (conf) - assert(conf->Display == dpy); - - return conf; -} - - -enum { - /* types */ - ATTRIB_TYPE_INTEGER, - ATTRIB_TYPE_BOOLEAN, - ATTRIB_TYPE_BITMASK, - ATTRIB_TYPE_ENUM, - ATTRIB_TYPE_PSEUDO, /* non-queryable */ - ATTRIB_TYPE_PLATFORM, /* platform-dependent */ - /* criteria */ - ATTRIB_CRITERION_EXACT, - ATTRIB_CRITERION_ATLEAST, - ATTRIB_CRITERION_MASK, - ATTRIB_CRITERION_SPECIAL, - ATTRIB_CRITERION_IGNORE -}; - - -/* EGL spec Table 3.1 and 3.4 */ -static const struct { - EGLint attr; - EGLint type; - EGLint criterion; - EGLint default_value; -} _eglValidationTable[] = -{ - /* core */ - { EGL_BUFFER_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_RED_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_GREEN_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_BLUE_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_LUMINANCE_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_ALPHA_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_ALPHA_MASK_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_BIND_TO_TEXTURE_RGB, ATTRIB_TYPE_BOOLEAN, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_BIND_TO_TEXTURE_RGBA, ATTRIB_TYPE_BOOLEAN, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_COLOR_BUFFER_TYPE, ATTRIB_TYPE_ENUM, - ATTRIB_CRITERION_EXACT, - EGL_RGB_BUFFER }, - { EGL_CONFIG_CAVEAT, ATTRIB_TYPE_ENUM, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_CONFIG_ID, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_CONFORMANT, ATTRIB_TYPE_BITMASK, - ATTRIB_CRITERION_MASK, - 0 }, - { EGL_DEPTH_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_LEVEL, ATTRIB_TYPE_PLATFORM, - ATTRIB_CRITERION_EXACT, - 0 }, - { EGL_MAX_PBUFFER_WIDTH, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_IGNORE, - 0 }, - { EGL_MAX_PBUFFER_HEIGHT, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_IGNORE, - 0 }, - { EGL_MAX_PBUFFER_PIXELS, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_IGNORE, - 0 }, - { EGL_MAX_SWAP_INTERVAL, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_MIN_SWAP_INTERVAL, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_NATIVE_RENDERABLE, ATTRIB_TYPE_BOOLEAN, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_NATIVE_VISUAL_ID, ATTRIB_TYPE_PLATFORM, - ATTRIB_CRITERION_IGNORE, - 0 }, - { EGL_NATIVE_VISUAL_TYPE, ATTRIB_TYPE_PLATFORM, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_RENDERABLE_TYPE, ATTRIB_TYPE_BITMASK, - ATTRIB_CRITERION_MASK, - EGL_OPENGL_ES_BIT }, - { EGL_SAMPLE_BUFFERS, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_SAMPLES, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_STENCIL_SIZE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_ATLEAST, - 0 }, - { EGL_SURFACE_TYPE, ATTRIB_TYPE_BITMASK, - ATTRIB_CRITERION_MASK, - EGL_WINDOW_BIT }, - { EGL_TRANSPARENT_TYPE, ATTRIB_TYPE_ENUM, - ATTRIB_CRITERION_EXACT, - EGL_NONE }, - { EGL_TRANSPARENT_RED_VALUE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_TRANSPARENT_GREEN_VALUE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_TRANSPARENT_BLUE_VALUE, ATTRIB_TYPE_INTEGER, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE }, - { EGL_MATCH_NATIVE_PIXMAP, ATTRIB_TYPE_PSEUDO, - ATTRIB_CRITERION_SPECIAL, - EGL_NONE }, - /* extensions */ - { EGL_Y_INVERTED_NOK, ATTRIB_TYPE_BOOLEAN, - ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE } -}; - - -/** - * Return true if a config is valid. When for_matching is true, - * EGL_DONT_CARE is accepted as a valid attribute value, and checks - * for conflicting attribute values are skipped. - * - * Note that some attributes are platform-dependent and are not - * checked. - */ -EGLBoolean -_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) -{ - EGLint i, attr, val; - EGLBoolean valid = EGL_TRUE; - - /* check attributes by their types */ - for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { - EGLint mask; - - attr = _eglValidationTable[i].attr; - val = _eglGetConfigKey(conf, attr); - - switch (_eglValidationTable[i].type) { - case ATTRIB_TYPE_INTEGER: - switch (attr) { - case EGL_CONFIG_ID: - /* config id must be positive */ - if (val <= 0) - valid = EGL_FALSE; - break; - case EGL_SAMPLE_BUFFERS: - /* there can be at most 1 sample buffer */ - if (val > 1 || val < 0) - valid = EGL_FALSE; - break; - default: - if (val < 0) - valid = EGL_FALSE; - break; - } - break; - case ATTRIB_TYPE_BOOLEAN: - if (val != EGL_TRUE && val != EGL_FALSE) - valid = EGL_FALSE; - break; - case ATTRIB_TYPE_ENUM: - switch (attr) { - case EGL_CONFIG_CAVEAT: - if (val != EGL_NONE && val != EGL_SLOW_CONFIG && - val != EGL_NON_CONFORMANT_CONFIG) - valid = EGL_FALSE; - break; - case EGL_TRANSPARENT_TYPE: - if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB) - valid = EGL_FALSE; - break; - case EGL_COLOR_BUFFER_TYPE: - if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER) - valid = EGL_FALSE; - break; - default: - assert(0); - break; - } - break; - case ATTRIB_TYPE_BITMASK: - switch (attr) { - case EGL_SURFACE_TYPE: - mask = EGL_PBUFFER_BIT | - EGL_PIXMAP_BIT | - EGL_WINDOW_BIT | - EGL_VG_COLORSPACE_LINEAR_BIT | - EGL_VG_ALPHA_FORMAT_PRE_BIT | - EGL_MULTISAMPLE_RESOLVE_BOX_BIT | - EGL_SWAP_BEHAVIOR_PRESERVED_BIT; -#ifdef EGL_MESA_screen_surface - if (conf->Display->Extensions.MESA_screen_surface) - mask |= EGL_SCREEN_BIT_MESA; -#endif - break; - case EGL_RENDERABLE_TYPE: - case EGL_CONFORMANT: - mask = EGL_OPENGL_ES_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENGL_ES3_BIT_KHR | - EGL_OPENGL_BIT; - break; - default: - assert(0); - mask = 0; - break; - } - if (val & ~mask) - valid = EGL_FALSE; - break; - case ATTRIB_TYPE_PLATFORM: - /* unable to check platform-dependent attributes here */ - break; - case ATTRIB_TYPE_PSEUDO: - /* pseudo attributes should not be set */ - if (val != 0) - valid = EGL_FALSE; - break; - default: - assert(0); - break; - } - - if (!valid && for_matching) { - /* accept EGL_DONT_CARE as a valid value */ - if (val == EGL_DONT_CARE) - valid = EGL_TRUE; - if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL) - valid = EGL_TRUE; - } - if (!valid) { - _eglLog(_EGL_DEBUG, - "attribute 0x%04x has an invalid value 0x%x", attr, val); - break; - } - } - - /* any invalid attribute value should have been catched */ - if (!valid || for_matching) - return valid; - - /* now check for conflicting attribute values */ - - switch (conf->ColorBufferType) { - case EGL_RGB_BUFFER: - if (conf->LuminanceSize) - valid = EGL_FALSE; - if (conf->RedSize + conf->GreenSize + - conf->BlueSize + conf->AlphaSize != conf->BufferSize) - valid = EGL_FALSE; - break; - case EGL_LUMINANCE_BUFFER: - if (conf->RedSize || conf->GreenSize || conf->BlueSize) - valid = EGL_FALSE; - if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize) - valid = EGL_FALSE; - break; - } - if (!valid) { - _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes"); - return EGL_FALSE; - } - - if (!conf->SampleBuffers && conf->Samples) - valid = EGL_FALSE; - if (!valid) { - _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers"); - return EGL_FALSE; - } - - if (!(conf->SurfaceType & EGL_WINDOW_BIT)) { - if (conf->NativeVisualID != 0 || conf->NativeVisualType != EGL_NONE) - valid = EGL_FALSE; - } - if (!(conf->SurfaceType & EGL_PBUFFER_BIT)) { - if (conf->BindToTextureRGB || conf->BindToTextureRGBA) - valid = EGL_FALSE; - } - if (!valid) { - _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding"); - return EGL_FALSE; - } - - return valid; -} - - -/** - * Return true if a config matches the criteria. This and - * _eglParseConfigAttribList together implement the algorithm - * described in "Selection of EGLConfigs". - * - * Note that attributes that are special (currently, only - * EGL_MATCH_NATIVE_PIXMAP) are ignored. - */ -EGLBoolean -_eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) -{ - EGLint attr, val, i; - EGLBoolean matched = EGL_TRUE; - - printf("_eglMatchConfig\n"); - asm volatile ("int3"); - - for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { - EGLint cmp; - if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_IGNORE) - continue; - - attr = _eglValidationTable[i].attr; - cmp = _eglGetConfigKey(criteria, attr); - if (cmp == EGL_DONT_CARE) - continue; - - val = _eglGetConfigKey(conf, attr); - switch (_eglValidationTable[i].criterion) { - case ATTRIB_CRITERION_EXACT: - if (val != cmp) - matched = EGL_FALSE; - break; - case ATTRIB_CRITERION_ATLEAST: - if (val < cmp) - matched = EGL_FALSE; - break; - case ATTRIB_CRITERION_MASK: - if ((val & cmp) != cmp) - matched = EGL_FALSE; - break; - case ATTRIB_CRITERION_SPECIAL: - /* ignored here */ - break; - default: - assert(0); - break; - } - - if (!matched) { -#ifndef DEBUG - /* only print the common errors when DEBUG is not defined */ - if (attr != EGL_RENDERABLE_TYPE) - break; -#endif -// _eglLog(_EGL_DEBUG, -// "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)", -// val, attr, cmp); - printf("the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)", - val, attr, cmp); - - break; - } - } - - return matched; -} - -static INLINE EGLBoolean -_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr) -{ - if (_eglOffsetOfConfig(attr) < 0) - return EGL_FALSE; - - switch (attr) { - case EGL_Y_INVERTED_NOK: - return conf->Display->Extensions.NOK_texture_from_pixmap; - default: - break; - } - - return EGL_TRUE; -} - -/** - * Initialize a criteria config from the given attribute list. - * Return EGL_FALSE if any of the attribute is invalid. - */ -EGLBoolean -_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy, - const EGLint *attrib_list) -{ - EGLint attr, val, i; - - _eglInitConfig(conf, dpy, EGL_DONT_CARE); - - /* reset to default values */ - for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { - attr = _eglValidationTable[i].attr; - val = _eglValidationTable[i].default_value; - _eglSetConfigKey(conf, attr, val); - } - - /* parse the list */ - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) { - attr = attrib_list[i]; - val = attrib_list[i + 1]; - - if (!_eglIsConfigAttribValid(conf, attr)) - return EGL_FALSE; - - _eglSetConfigKey(conf, attr, val); - } - - if (!_eglValidateConfig(conf, EGL_TRUE)) - return EGL_FALSE; - - /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */ - if (conf->Level == EGL_DONT_CARE || - conf->MatchNativePixmap == EGL_DONT_CARE) - return EGL_FALSE; - - /* ignore other attributes when EGL_CONFIG_ID is given */ - if (conf->ConfigID != EGL_DONT_CARE) { - for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { - attr = _eglValidationTable[i].attr; - if (attr != EGL_CONFIG_ID) - _eglSetConfigKey(conf, attr, EGL_DONT_CARE); - } - } - else { - if (!(conf->SurfaceType & EGL_WINDOW_BIT)) - conf->NativeVisualType = EGL_DONT_CARE; - - if (conf->TransparentType == EGL_NONE) { - conf->TransparentRedValue = EGL_DONT_CARE; - conf->TransparentGreenValue = EGL_DONT_CARE; - conf->TransparentBlueValue = EGL_DONT_CARE; - } - } - - return EGL_TRUE; -} - - -/** - * Decide the ordering of conf1 and conf2, under the given criteria. - * When compare_id is true, this implements the algorithm described - * in "Sorting of EGLConfigs". When compare_id is false, - * EGL_CONFIG_ID is not compared. - * - * It returns a negative integer if conf1 is considered to come - * before conf2; a positive integer if conf2 is considered to come - * before conf1; zero if the ordering cannot be decided. - * - * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is - * ignored here. - */ -EGLint -_eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, - const _EGLConfig *criteria, EGLBoolean compare_id) -{ - const EGLint compare_attribs[] = { - EGL_BUFFER_SIZE, - EGL_SAMPLE_BUFFERS, - EGL_SAMPLES, - EGL_DEPTH_SIZE, - EGL_STENCIL_SIZE, - EGL_ALPHA_MASK_SIZE, - }; - EGLint val1, val2; - EGLint i; - - if (conf1 == conf2) - return 0; - - /* the enum values have the desired ordering */ - assert(EGL_NONE < EGL_SLOW_CONFIG); - assert(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); - val1 = conf1->ConfigCaveat - conf2->ConfigCaveat; - if (val1) - return val1; - - /* the enum values have the desired ordering */ - assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); - val1 = conf1->ColorBufferType - conf2->ColorBufferType; - if (val1) - return val1; - - if (criteria) { - val1 = val2 = 0; - if (conf1->ColorBufferType == EGL_RGB_BUFFER) { - if (criteria->RedSize > 0) { - val1 += conf1->RedSize; - val2 += conf2->RedSize; - } - if (criteria->GreenSize > 0) { - val1 += conf1->GreenSize; - val2 += conf2->GreenSize; - } - if (criteria->BlueSize > 0) { - val1 += conf1->BlueSize; - val2 += conf2->BlueSize; - } - } - else { - if (criteria->LuminanceSize > 0) { - val1 += conf1->LuminanceSize; - val2 += conf2->LuminanceSize; - } - } - if (criteria->AlphaSize > 0) { - val1 += conf1->AlphaSize; - val2 += conf2->AlphaSize; - } - } - else { - /* assume the default criteria, which gives no specific ordering */ - val1 = val2 = 0; - } - - /* for color bits, larger one is preferred */ - if (val1 != val2) - return (val2 - val1); - - for (i = 0; i < ARRAY_SIZE(compare_attribs); i++) { - val1 = _eglGetConfigKey(conf1, compare_attribs[i]); - val2 = _eglGetConfigKey(conf2, compare_attribs[i]); - if (val1 != val2) - return (val1 - val2); - } - - /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */ - - return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0; -} - - -static INLINE -void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2) -{ - const _EGLConfig *tmp = *conf1; - *conf1 = *conf2; - *conf2 = tmp; -} - - -/** - * Quick sort an array of configs. This differs from the standard - * qsort() in that the compare function accepts an additional - * argument. - */ -static void -_eglSortConfigs(const _EGLConfig **configs, EGLint count, - EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, - void *), - void *priv_data) -{ - const EGLint pivot = 0; - EGLint i, j; - - if (count <= 1) - return; - - _eglSwapConfigs(&configs[pivot], &configs[count / 2]); - i = 1; - j = count - 1; - do { - while (i < count && compare(configs[i], configs[pivot], priv_data) < 0) - i++; - while (compare(configs[j], configs[pivot], priv_data) > 0) - j--; - if (i < j) { - _eglSwapConfigs(&configs[i], &configs[j]); - i++; - j--; - } - else if (i == j) { - i++; - j--; - break; - } - } while (i <= j); - _eglSwapConfigs(&configs[pivot], &configs[j]); - - _eglSortConfigs(configs, j, compare, priv_data); - _eglSortConfigs(configs + i, count - i, compare, priv_data); -} - - -/** - * A helper function for implementing eglChooseConfig. See _eglFilterArray and - * _eglSortConfigs for the meanings of match and compare. - */ -EGLBoolean -_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs, - EGLint config_size, EGLint *num_configs, - EGLBoolean (*match)(const _EGLConfig *, void *), - EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, - void *), - void *priv_data) -{ - _EGLConfig **configList; - EGLint i, count; - - if (!num_configs) - return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); - - /* get the number of matched configs */ - count = _eglFilterArray(array, NULL, 0, - (_EGLArrayForEach) match, priv_data); - if (!count) { - *num_configs = count; - printf("_eglFilterConfigArray count %d\n", count); - return EGL_TRUE; - } - - configList = malloc(sizeof(*configList) * count); - if (!configList) - return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); - - /* get the matched configs */ - _eglFilterArray(array, (void **) configList, count, - (_EGLArrayForEach) match, priv_data); - - /* perform sorting of configs */ - if (configs && count) { - _eglSortConfigs((const _EGLConfig **) configList, count, - compare, priv_data); - count = MIN2(count, config_size); - for (i = 0; i < count; i++) - configs[i] = _eglGetConfigHandle(configList[i]); - } - - free(configList); - - *num_configs = count; - - return EGL_TRUE; -} - - -static EGLBoolean -_eglFallbackMatch(const _EGLConfig *conf, void *priv_data) -{ - return _eglMatchConfig(conf, (const _EGLConfig *) priv_data); -} - - -static EGLint -_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2, - void *priv_data) -{ - return _eglCompareConfigs(conf1, conf2, - (const _EGLConfig *) priv_data, EGL_TRUE); -} - - -/** - * Typical fallback routine for eglChooseConfig - */ -EGLBoolean -_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, - EGLConfig *configs, EGLint config_size, EGLint *num_configs) -{ - _EGLConfig criteria; - - if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) - return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); - - printf("%s attrib %p size %d\n", __FUNCTION__, attrib_list, config_size); - asm volatile ("int3"); - - return _eglFilterConfigArray(disp->Configs, - configs, config_size, num_configs, - _eglFallbackMatch, _eglFallbackCompare, - (void *) &criteria); -} - - -/** - * Fallback for eglGetConfigAttrib. - */ -EGLBoolean -_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - EGLint attribute, EGLint *value) -{ - if (!_eglIsConfigAttribValid(conf, attribute)) - return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); - - /* nonqueryable attributes */ - switch (attribute) { - case EGL_MATCH_NATIVE_PIXMAP: - return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); - break; - default: - break; - } - - if (!value) - return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib"); - - *value = _eglGetConfigKey(conf, attribute); - return EGL_TRUE; -} - - -static EGLBoolean -_eglFlattenConfig(void *elem, void *buffer) -{ - _EGLConfig *conf = (_EGLConfig *) elem; - EGLConfig *handle = (EGLConfig *) buffer; - *handle = _eglGetConfigHandle(conf); - return EGL_TRUE; -} - -/** - * Fallback for eglGetConfigs. - */ -EGLBoolean -_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs, - EGLint config_size, EGLint *num_config) -{ - if (!num_config) - return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs"); - - *num_config = _eglFlattenArray(disp->Configs, (void *) configs, - sizeof(configs[0]), config_size, _eglFlattenConfig); - - return EGL_TRUE; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglcontext.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglcontext.c.bak deleted file mode 100644 index 76ee57fc28..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglcontext.c.bak +++ /dev/null @@ -1,618 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010-2011 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include -#include -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "eglcurrent.h" -#include "eglsurface.h" -#include "egllog.h" - - -/** - * Return the API bit (one of EGL_xxx_BIT) of the context. - */ -static EGLint -_eglGetContextAPIBit(_EGLContext *ctx) -{ - EGLint bit = 0; - - switch (ctx->ClientAPI) { - case EGL_OPENGL_ES_API: - switch (ctx->ClientMajorVersion) { - case 1: - bit = EGL_OPENGL_ES_BIT; - break; - case 2: - bit = EGL_OPENGL_ES2_BIT; - break; - case 3: - bit = EGL_OPENGL_ES3_BIT_KHR; - break; - default: - break; - } - break; - case EGL_OPENVG_API: - bit = EGL_OPENVG_BIT; - break; - case EGL_OPENGL_API: - bit = EGL_OPENGL_BIT; - break; - default: - break; - } - - return bit; -} - - -/** - * Parse the list of context attributes and return the proper error code. - */ -static EGLint -_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy, - const EGLint *attrib_list) -{ - EGLenum api = ctx->ClientAPI; - EGLint i, err = EGL_SUCCESS; - - if (!attrib_list) - return EGL_SUCCESS; - - if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) { - _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]); - return EGL_BAD_ATTRIBUTE; - } - - for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; - - switch (attr) { - case EGL_CONTEXT_CLIENT_VERSION: - ctx->ClientMajorVersion = val; - break; - - case EGL_CONTEXT_MINOR_VERSION_KHR: - if (!dpy->Extensions.KHR_create_context) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->ClientMinorVersion = val; - break; - - case EGL_CONTEXT_FLAGS_KHR: - if (!dpy->Extensions.KHR_create_context) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - /* The EGL_KHR_create_context spec says: - * - * "Flags are only defined for OpenGL context creation, and - * specifying a flags value other than zero for other types of - * contexts, including OpenGL ES contexts, will generate an - * error." - */ - if (api != EGL_OPENGL_API && val != 0) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->Flags = val; - break; - - case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: - if (!dpy->Extensions.KHR_create_context) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - /* The EGL_KHR_create_context spec says: - * - * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for - * OpenGL contexts, and specifying it for other types of - * contexts, including OpenGL ES contexts, will generate an - * error." - */ - if (api != EGL_OPENGL_API) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->Profile = val; - break; - - case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR: - /* The EGL_KHR_create_context spec says: - * - * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only - * meaningful for OpenGL contexts, and specifying it for other - * types of contexts, including OpenGL ES contexts, will generate - * an error." - */ - if (!dpy->Extensions.KHR_create_context - || api != EGL_OPENGL_API) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->ResetNotificationStrategy = val; - break; - - case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: - /* The EGL_EXT_create_context_robustness spec says: - * - * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only - * meaningful for OpenGL ES contexts, and specifying it for other - * types of contexts will generate an EGL_BAD_ATTRIBUTE error." - */ - if (!dpy->Extensions.EXT_create_context_robustness - || api != EGL_OPENGL_ES_API) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->ResetNotificationStrategy = val; - break; - - case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: - if (!dpy->Extensions.EXT_create_context_robustness) { - err = EGL_BAD_ATTRIBUTE; - break; - } - - ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; - break; - - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr); - break; - } - } - - if (api == EGL_OPENGL_API) { - /* The EGL_KHR_create_context spec says: - * - * "If the requested OpenGL version is less than 3.2, - * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the - * functionality of the context is determined solely by the - * requested version." - * - * Since the value is ignored, only validate the setting if the version - * is >= 3.2. - */ - if (ctx->ClientMajorVersion >= 4 - || (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) { - switch (ctx->Profile) { - case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR: - case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR: - break; - - default: - /* The EGL_KHR_create_context spec says: - * - * "* If an OpenGL context is requested, the requested version - * is greater than 3.2, and the value for attribute - * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has - * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR - * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has - * more than one of these bits set; or if the implementation does - * not support the requested profile, then an EGL_BAD_MATCH error - * is generated." - */ - err = EGL_BAD_MATCH; - break; - } - } - - /* The EGL_KHR_create_context spec says: - * - * "* If an OpenGL context is requested and the values for - * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and - * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with - * the value for attribute - * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL - * version and feature set that are not defined, than an - * EGL_BAD_MATCH error is generated. - * - * ... Thus, examples of invalid combinations of attributes - * include: - * - * - Major version < 1 or > 4 - * - Major version == 1 and minor version < 0 or > 5 - * - Major version == 2 and minor version < 0 or > 1 - * - Major version == 3 and minor version < 0 or > 2 - * - Major version == 4 and minor version < 0 or > 2 - * - Forward-compatible flag set and major version < 3" - */ - if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) - err = EGL_BAD_MATCH; - - switch (ctx->ClientMajorVersion) { - case 1: - if (ctx->ClientMinorVersion > 5 - || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) - err = EGL_BAD_MATCH; - break; - - case 2: - if (ctx->ClientMinorVersion > 1 - || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) - err = EGL_BAD_MATCH; - break; - - case 3: - /* Note: The text above is incorrect. There *is* an OpenGL 3.3! - */ - if (ctx->ClientMinorVersion > 3) - err = EGL_BAD_MATCH; - break; - - case 4: - default: - /* Don't put additional version checks here. We don't know that - * there won't be versions > 4.2. - */ - break; - } - } else if (api == EGL_OPENGL_ES_API) { - /* The EGL_KHR_create_context spec says: - * - * "* If an OpenGL ES context is requested and the values for - * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and - * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that - * is not defined, than an EGL_BAD_MATCH error is generated. - * - * ... Examples of invalid combinations of attributes include: - * - * - Major version < 1 or > 2 - * - Major version == 1 and minor version < 0 or > 1 - * - Major version == 2 and minor version != 0 - */ - if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) - err = EGL_BAD_MATCH; - - switch (ctx->ClientMajorVersion) { - case 1: - if (ctx->ClientMinorVersion > 1) - err = EGL_BAD_MATCH; - break; - - case 2: - if (ctx->ClientMinorVersion > 0) - err = EGL_BAD_MATCH; - break; - - case 3: - default: - /* Don't put additional version checks here. We don't know that - * there won't be versions > 3.0. - */ - break; - } - } - - switch (ctx->ResetNotificationStrategy) { - case EGL_NO_RESET_NOTIFICATION_KHR: - case EGL_LOSE_CONTEXT_ON_RESET_KHR: - break; - - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR - | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR - | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) { - err = EGL_BAD_ATTRIBUTE; - } - - return err; -} - - -/** - * Initialize the given _EGLContext object to defaults and/or the values - * in the attrib_list. - */ -EGLBoolean -_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - const EGLenum api = eglQueryAPI(); - EGLint err; - - if (api == EGL_NONE) { - _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)"); - return EGL_FALSE; - } - - _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy); - ctx->ClientAPI = api; - ctx->Config = conf; - ctx->WindowRenderBuffer = EGL_NONE; - ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - - ctx->ClientMajorVersion = 1; /* the default, per EGL spec */ - ctx->ClientMinorVersion = 0; - ctx->Flags = 0; - ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR; - - err = _eglParseContextAttribList(ctx, dpy, attrib_list); - if (err == EGL_SUCCESS && ctx->Config) { - EGLint api_bit; - - api_bit = _eglGetContextAPIBit(ctx); - if (!(ctx->Config->RenderableType & api_bit)) { - _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x", - api_bit, ctx->Config->RenderableType); - err = EGL_BAD_CONFIG; - } - } - if (err != EGL_SUCCESS) - return _eglError(err, "eglCreateContext"); - - return EGL_TRUE; -} - - -static EGLint -_eglQueryContextRenderBuffer(_EGLContext *ctx) -{ - _EGLSurface *surf = ctx->DrawSurface; - EGLint rb; - - if (!surf) - return EGL_NONE; - if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE) - rb = ctx->WindowRenderBuffer; - else - rb = surf->RenderBuffer; - return rb; -} - - -EGLBoolean -_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, - EGLint attribute, EGLint *value) -{ - (void) drv; - (void) dpy; - - if (!value) - return _eglError(EGL_BAD_PARAMETER, "eglQueryContext"); - - switch (attribute) { - case EGL_CONFIG_ID: - if (!c->Config) - return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); - *value = c->Config->ConfigID; - break; - case EGL_CONTEXT_CLIENT_VERSION: - *value = c->ClientMajorVersion; - break; - case EGL_CONTEXT_CLIENT_TYPE: - *value = c->ClientAPI; - break; - case EGL_RENDER_BUFFER: - *value = _eglQueryContextRenderBuffer(c); - break; - default: - return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); - } - - return EGL_TRUE; -} - - -/** - * Bind the context to the thread and return the previous context. - * - * Note that the context may be NULL. - */ -static _EGLContext * -_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t) -{ - EGLint apiIndex; - _EGLContext *oldCtx; - - apiIndex = (ctx) ? - _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex; - - oldCtx = t->CurrentContexts[apiIndex]; - if (ctx != oldCtx) { - if (oldCtx) - oldCtx->Binding = NULL; - if (ctx) - ctx->Binding = t; - - t->CurrentContexts[apiIndex] = ctx; - } - - return oldCtx; -} - - -/** - * Return true if the given context and surfaces can be made current. - */ -static EGLBoolean -_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLDisplay *dpy; - EGLint conflict_api; - - if (_eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); - - /* this is easy */ - if (!ctx) { - if (draw || read) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - return EGL_TRUE; - } - - dpy = ctx->Resource.Display; - if (!dpy->Extensions.KHR_surfaceless_context - && (draw == NULL || read == NULL)) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - - /* - * The spec says - * - * "If ctx is current to some other thread, or if either draw or read are - * bound to contexts in another thread, an EGL_BAD_ACCESS error is - * generated." - * - * and - * - * "at most one context may be bound to a particular surface at a given - * time" - */ - if (ctx->Binding && ctx->Binding != t) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - if (draw && draw->CurrentContext && draw->CurrentContext != ctx) { - if (draw->CurrentContext->Binding != t || - draw->CurrentContext->ClientAPI != ctx->ClientAPI) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - } - if (read && read->CurrentContext && read->CurrentContext != ctx) { - if (read->CurrentContext->Binding != t || - read->CurrentContext->ClientAPI != ctx->ClientAPI) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - } - - /* simply require the configs to be equal */ - if ((draw && draw->Config != ctx->Config) || - (read && read->Config != ctx->Config)) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - - switch (ctx->ClientAPI) { - /* OpenGL and OpenGL ES are conflicting */ - case EGL_OPENGL_ES_API: - conflict_api = EGL_OPENGL_API; - break; - case EGL_OPENGL_API: - conflict_api = EGL_OPENGL_ES_API; - break; - default: - conflict_api = -1; - break; - } - - if (conflict_api >= 0 && _eglGetAPIContext(conflict_api)) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - - return EGL_TRUE; -} - - -/** - * Bind the context to the current thread and given surfaces. Return the - * previous bound context and surfaces. The caller should unreference the - * returned context and surfaces. - * - * Making a second call with the resources returned by the first call - * unsurprisingly undoes the first call, except for the resouce reference - * counts. - */ -EGLBoolean -_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read, - _EGLContext **old_ctx, - _EGLSurface **old_draw, _EGLSurface **old_read) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *prev_ctx; - _EGLSurface *prev_draw, *prev_read; - - printf("%s\n",__FUNCTION__); - - if (!_eglCheckMakeCurrent(ctx, draw, read)) - return EGL_FALSE; - - /* increment refcounts before binding */ - _eglGetContext(ctx); - _eglGetSurface(draw); - _eglGetSurface(read); - - /* bind the new context */ - prev_ctx = _eglBindContextToThread(ctx, t); - - /* break previous bindings */ - if (prev_ctx) { - prev_draw = prev_ctx->DrawSurface; - prev_read = prev_ctx->ReadSurface; - - if (prev_draw) - prev_draw->CurrentContext = NULL; - if (prev_read) - prev_read->CurrentContext = NULL; - - prev_ctx->DrawSurface = NULL; - prev_ctx->ReadSurface = NULL; - } - else { - prev_draw = prev_read = NULL; - } - - /* establish new bindings */ - if (ctx) { - if (draw) - draw->CurrentContext = ctx; - if (read) - read->CurrentContext = ctx; - - ctx->DrawSurface = draw; - ctx->ReadSurface = read; - } - - assert(old_ctx && old_draw && old_read); - *old_ctx = prev_ctx; - *old_draw = prev_draw; - *old_read = prev_read; - - printf("leave %s\n",__FUNCTION__); - - return EGL_TRUE; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/egldisplay.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/egldisplay.c.bak deleted file mode 100644 index 546f8508f4..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/egldisplay.c.bak +++ /dev/null @@ -1,395 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010-2011 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Functions related to EGLDisplay. - */ - -#include -#include -#include -#include "eglcontext.h" -#include "eglsurface.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmutex.h" -#include "egllog.h" - -/* Includes for _eglNativePlatformDetectNativeDisplay */ -#ifdef HAVE_MINCORE -#include -#include -#endif -#ifdef HAVE_WAYLAND_PLATFORM -#include -#endif -#ifdef HAVE_DRM_PLATFORM -#include -#endif -#ifdef HAVE_FBDEV_PLATFORM -#include -#include -#include -#endif - - -/** - * Map --with-egl-platforms names to platform types. - */ -static const struct { - _EGLPlatformType platform; - const char *name; -} egl_platforms[_EGL_NUM_PLATFORMS] = { - { _EGL_PLATFORM_DRM, "drm" } -}; - - -/** - * Return the native platform by parsing EGL_PLATFORM. - */ -static _EGLPlatformType -_eglGetNativePlatformFromEnv(void) -{ - _EGLPlatformType plat = _EGL_INVALID_PLATFORM; - const char *plat_name; - EGLint i; - - plat_name = getenv("EGL_PLATFORM"); - /* try deprecated env variable */ - if (!plat_name || !plat_name[0]) - plat_name = getenv("EGL_DISPLAY"); - if (!plat_name || !plat_name[0]) - return _EGL_INVALID_PLATFORM; - - for (i = 0; i < _EGL_NUM_PLATFORMS; i++) { - if (strcmp(egl_platforms[i].name, plat_name) == 0) { - plat = egl_platforms[i].platform; - break; - } - } - - return plat; -} - - -/** - * Perform validity checks on a generic pointer. - */ -static EGLBoolean -_eglPointerIsDereferencable(void *p) -{ -#ifdef HAVE_MINCORE - uintptr_t addr = (uintptr_t) p; - unsigned char valid = 0; - const long page_size = getpagesize(); - - if (p == NULL) - return EGL_FALSE; - - /* align addr to page_size */ - addr &= ~(page_size - 1); - - if (mincore((void *) addr, page_size, &valid) < 0) { - _eglLog(_EGL_DEBUG, "mincore failed: %m"); - return EGL_FALSE; - } - - return (valid & 0x01) == 0x01; -#else - return p != NULL; -#endif -} - - -/** - * Try detecting native platform with the help of native display characteristcs. - */ -static _EGLPlatformType -_eglNativePlatformDetectNativeDisplay(EGLNativeDisplayType nativeDisplay) -{ - return _EGL_PLATFORM_DRM; -} - - -/** - * Return the native platform. It is the platform of the EGL native types. - */ -_EGLPlatformType -_eglGetNativePlatform(EGLNativeDisplayType nativeDisplay) -{ - return _EGL_PLATFORM_DRM; -} - - -/** - * Finish display management. - */ -void -_eglFiniDisplay(void) -{ - _EGLDisplay *dpyList, *dpy; - - /* atexit function is called with global mutex locked */ - dpyList = _eglGlobal.DisplayList; - while (dpyList) { - EGLint i; - - /* pop list head */ - dpy = dpyList; - dpyList = dpyList->Next; - - for (i = 0; i < _EGL_NUM_RESOURCES; i++) { - if (dpy->ResourceLists[i]) { - _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); - break; - } - } - - free(dpy); - } - _eglGlobal.DisplayList = NULL; -} - - -/** - * Find the display corresponding to the specified native display, or create a - * new one. - */ -_EGLDisplay * -_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy) -{ - _EGLDisplay *dpy; - - if (plat == _EGL_INVALID_PLATFORM) - return NULL; - - _eglLockMutex(_eglGlobal.Mutex); - - /* search the display list first */ - dpy = _eglGlobal.DisplayList; - while (dpy) { - if (dpy->Platform == plat && dpy->PlatformDisplay == plat_dpy) - break; - dpy = dpy->Next; - } - - /* create a new display */ - if (!dpy) { - dpy = calloc(1, sizeof(_EGLDisplay)); - if (dpy) { - _eglInitMutex(&dpy->Mutex); - dpy->Platform = plat; - dpy->PlatformDisplay = plat_dpy; - - /* add to the display list */ - dpy->Next = _eglGlobal.DisplayList; - _eglGlobal.DisplayList = dpy; - } - } - - _eglUnlockMutex(_eglGlobal.Mutex); - - return dpy; -} - - -/** - * Destroy the contexts and surfaces that are linked to the display. - */ -void -_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) -{ - _EGLResource *list; - - list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; - while (list) { - _EGLContext *ctx = (_EGLContext *) list; - list = list->Next; - - _eglUnlinkContext(ctx); - drv->API.DestroyContext(drv, display, ctx); - } - assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); - - list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; - while (list) { - _EGLSurface *surf = (_EGLSurface *) list; - list = list->Next; - - _eglUnlinkSurface(surf); - drv->API.DestroySurface(drv, display, surf); - } - assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); -} - - -/** - * Free all the data hanging of an _EGLDisplay object, but not - * the object itself. - */ -void -_eglCleanupDisplay(_EGLDisplay *disp) -{ - if (disp->Configs) { - _eglDestroyArray(disp->Configs, free); - disp->Configs = NULL; - } - - /* XXX incomplete */ -} - - -/** - * Return EGL_TRUE if the given handle is a valid handle to a display. - */ -EGLBoolean -_eglCheckDisplayHandle(EGLDisplay dpy) -{ - _EGLDisplay *cur; - - _eglLockMutex(_eglGlobal.Mutex); - cur = _eglGlobal.DisplayList; - while (cur) { - if (cur == (_EGLDisplay *) dpy) - break; - cur = cur->Next; - } - _eglUnlockMutex(_eglGlobal.Mutex); - return (cur != NULL); -} - - -/** - * Return EGL_TRUE if the given resource is valid. That is, the display does - * own the resource. - */ -EGLBoolean -_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy) -{ - _EGLResource *list = dpy->ResourceLists[type]; - - if (!res) - return EGL_FALSE; - - while (list) { - if (res == (void *) list) { - assert(list->Display == dpy); - break; - } - list = list->Next; - } - - return (list != NULL); -} - - -/** - * Initialize a display resource. - */ -void -_eglInitResource(_EGLResource *res, EGLint size, _EGLDisplay *dpy) -{ - memset(res, 0, size); - res->Display = dpy; - res->RefCount = 1; -} - - -/** - * Increment reference count for the resource. - */ -void -_eglGetResource(_EGLResource *res) -{ - assert(res && res->RefCount > 0); - /* hopefully a resource is always manipulated with its display locked */ - res->RefCount++; -} - - -/** - * Decrement reference count for the resource. - */ -EGLBoolean -_eglPutResource(_EGLResource *res) -{ - assert(res && res->RefCount > 0); - res->RefCount--; - return (!res->RefCount); -} - - -/** - * Link a resource to its display. - */ -void -_eglLinkResource(_EGLResource *res, _EGLResourceType type) -{ - assert(res->Display); - - printf("%s Resource: %p\n", __FUNCTION__, res); - - res->IsLinked = EGL_TRUE; - res->Next = res->Display->ResourceLists[type]; - res->Display->ResourceLists[type] = res; - _eglGetResource(res); -} - - -/** - * Unlink a linked resource from its display. - */ -void -_eglUnlinkResource(_EGLResource *res, _EGLResourceType type) -{ - _EGLResource *prev; - - prev = res->Display->ResourceLists[type]; - if (prev != res) { - while (prev) { - if (prev->Next == res) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = res->Next; - } - else { - res->Display->ResourceLists[type] = res->Next; - } - - res->Next = NULL; - res->IsLinked = EGL_FALSE; - _eglPutResource(res); - - /* We always unlink before destroy. The driver still owns a reference */ - assert(res->RefCount); -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/egldriver.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/egldriver.c.bak deleted file mode 100644 index 783e515911..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/egldriver.c.bak +++ /dev/null @@ -1,689 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010-2011 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Functions for choosing and opening/loading device drivers. - */ - - -#include -#include -#include -#include - -#include "eglstring.h" -#include "egldefines.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "egllog.h" -#include "eglmutex.h" - -typedef unsigned int lib_handle; - -lib_handle load_library(const char *name); -void *get_proc_address(lib_handle lib, char *proc_name); - - -typedef struct _egl_module { - char *Path; - _EGLMain_t BuiltIn; - void *Handle; - _EGLDriver *Driver; -} _EGLModule; - -static _EGL_DECLARE_MUTEX(_eglModuleMutex); -static _EGLArray *_eglModules; - -const struct { - const char *name; - _EGLMain_t main; -} _eglBuiltInDrivers[] = { -#ifdef _EGL_BUILT_IN_DRIVER_GALLIUM - { "egl_gallium", _eglBuiltInDriverGALLIUM }, -#endif -#ifdef _EGL_BUILT_IN_DRIVER_DRI2 - { "egl_dri2", _eglBuiltInDriverDRI2 }, -#endif -#ifdef _EGL_BUILT_IN_DRIVER_GLX - { "egl_glx", _eglBuiltInDriverGLX }, -#endif - { NULL, NULL } -}; - -/** - * Wrappers for dlopen/dlclose() - */ -#if defined(_EGL_OS_WINDOWS) - - -typedef HMODULE lib_handle; - -static HMODULE -open_library(const char *filename) -{ - return LoadLibrary(filename); -} - -static void -close_library(HMODULE lib) -{ - FreeLibrary(lib); -} - - -static const char * -library_suffix(void) -{ - return ".dll"; -} - - -#elif defined(_EGL_OS_UNIX) - - -typedef void * lib_handle; - -static void * -open_library(const char *filename) -{ - return dlopen(filename, RTLD_LAZY); -} - -static void -close_library(void *lib) -{ - dlclose(lib); -} - - -static const char * -library_suffix(void) -{ - return ".so"; -} - - -#endif - -/** - * Open the named driver and find its bootstrap function: _eglMain(). - */ -static _EGLMain_t -_eglOpenLibrary(const char *driverPath, lib_handle *handle) -{ - lib_handle lib; - _EGLMain_t mainFunc = NULL; - const char *error = "unknown error"; - - assert(driverPath); - - _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); - lib = load_library(driverPath); - if (!lib) { - _eglLog(_EGL_WARNING, "Could not open driver %s (%s)", - driverPath, error); - return NULL; - } - - mainFunc = (_EGLMain_t) get_proc_address(lib, "_eglMain"); - - if (!mainFunc) { - _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)", - driverPath, error); - return NULL; - } - - *handle = lib; - return mainFunc; -} - - -/** - * Load a module and create the driver object. - */ -static EGLBoolean -_eglLoadModule(_EGLModule *mod) -{ - _EGLMain_t mainFunc; - lib_handle lib; - _EGLDriver *drv; - - if (mod->Driver) - return EGL_TRUE; - - if (mod->BuiltIn) { - lib = (lib_handle) NULL; - mainFunc = mod->BuiltIn; - } - else { - mainFunc = _eglOpenLibrary(mod->Path, &lib); - if (!mainFunc) - return EGL_FALSE; - } - - drv = mainFunc(NULL); - if (!drv) { - return EGL_FALSE; - } - - if (!drv->Name) { - _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path); - drv->Name = "UNNAMED"; - } - - mod->Handle = (void *) lib; - mod->Driver = drv; - - return EGL_TRUE; -} - - -/** - * Unload a module. - */ -static void -_eglUnloadModule(_EGLModule *mod) -{ -#if defined(_EGL_OS_UNIX) - /* destroy the driver */ - if (mod->Driver && mod->Driver->Unload) - mod->Driver->Unload(mod->Driver); - - /* - * XXX At this point (atexit), the module might be the last reference to - * libEGL. Closing the module might unmap libEGL and give problems. - */ -#if 0 - if (mod->Handle) - close_library(mod->Handle); -#endif -#elif defined(_EGL_OS_WINDOWS) - /* XXX Windows unloads DLLs before atexit */ -#endif - - mod->Driver = NULL; - mod->Handle = NULL; -} - - -/** - * Add a module to the module array. - */ -static _EGLModule * -_eglAddModule(const char *path) -{ - _EGLModule *mod; - EGLint i; - - if (!_eglModules) { - _eglModules = _eglCreateArray("Module", 8); - if (!_eglModules) - return NULL; - } - - /* find duplicates */ - for (i = 0; i < _eglModules->Size; i++) { - mod = _eglModules->Elements[i]; - if (strcmp(mod->Path, path) == 0) - return mod; - } - - /* allocate a new one */ - mod = calloc(1, sizeof(*mod)); - if (mod) { - mod->Path = _eglstrdup(path); - if (!mod->Path) { - free(mod); - mod = NULL; - } - } - if (mod) { - _eglAppendArray(_eglModules, (void *) mod); - _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path); - } - - return mod; -} - - -/** - * Free a module. - */ -static void -_eglFreeModule(void *module) -{ - _EGLModule *mod = (_EGLModule *) module; - - _eglUnloadModule(mod); - free(mod->Path); - free(mod); -} - -#if 0 -/** - * A loader function for use with _eglPreloadForEach. The loader data is the - * filename of the driver. This function stops on the first valid driver. - */ -static EGLBoolean -_eglLoaderFile(const char *dir, size_t len, void *loader_data) -{ - char path[1024]; - const char *filename = (const char *) loader_data; - size_t flen = strlen(filename); - - /* make a full path */ - if (len + flen + 2 > sizeof(path)) - return EGL_TRUE; - if (len) { - memcpy(path, dir, len); - path[len++] = '/'; - } - memcpy(path + len, filename, flen); - len += flen; - path[len] = '\0'; - - if (library_suffix()) { - const char *suffix = library_suffix(); - size_t slen = strlen(suffix); - const char *p; - EGLBoolean need_suffix; - - p = filename + flen - slen; - need_suffix = (p < filename || strcmp(p, suffix) != 0); - if (need_suffix) { - /* overflow */ - if (len + slen + 1 > sizeof(path)) - return EGL_TRUE; - strcpy(path + len, suffix); - } - } - -#if defined(_EGL_OS_UNIX) - /* check if the file exists */ - if (access(path, F_OK)) - return EGL_TRUE; -#endif - - _eglAddModule(path); - - return EGL_TRUE; -} - - -/** - * Run the callback function on each driver directory. - * - * The process may end prematurely if the callback function returns false. - */ -static void -_eglPreloadForEach(const char *search_path, - EGLBoolean (*loader)(const char *, size_t, void *), - void *loader_data) -{ - const char *cur, *next; - size_t len; - - cur = search_path; - while (cur) { - next = strchr(cur, ':'); - len = (next) ? next - cur : strlen(cur); - - if (!loader(cur, len, loader_data)) - break; - - cur = (next) ? next + 1 : NULL; - } -} - - -/** - * Return a list of colon-separated driver directories. - */ -static const char * -_eglGetSearchPath(void) -{ - static char search_path[1024]; - -#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) - if (search_path[0] == '\0') { - char *buf = search_path; - size_t len = sizeof(search_path); - EGLBoolean use_env; - char dir_sep; - int ret; - -#if defined(_EGL_OS_UNIX) - use_env = (geteuid() == getuid() && getegid() == getgid()); - dir_sep = '/'; -#else - use_env = EGL_TRUE; - dir_sep = '\\'; -#endif - - if (use_env) { - char *p; - - /* extract the dirname from EGL_DRIVER */ - p = getenv("EGL_DRIVER"); - if (p && strchr(p, dir_sep)) { - ret = _eglsnprintf(buf, len, "%s", p); - if (ret > 0 && ret < len) { - p = strrchr(buf, dir_sep); - *p++ = ':'; - - len -= p - buf; - buf = p; - } - } - - /* append EGL_DRIVERS_PATH */ - p = getenv("EGL_DRIVERS_PATH"); - if (p) { - ret = _eglsnprintf(buf, len, "%s:", p); - if (ret > 0 && ret < len) { - buf += ret; - len -= ret; - } - } - } - else { - _eglLog(_EGL_DEBUG, - "ignore EGL_DRIVERS_PATH for setuid/setgid binaries"); - } - - ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR); - if (ret < 0 || ret >= len) - search_path[0] = '\0'; - - _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path); - } -#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */ - - return search_path; -} - - -/** - * Add the user driver to the module array. - * - * The user driver is specified by EGL_DRIVER. - */ -static EGLBoolean -_eglAddUserDriver(void) -{ - const char *search_path = _eglGetSearchPath(); - char *env; - size_t name_len = 0; - - env = getenv("EGL_DRIVER"); -#if defined(_EGL_OS_UNIX) - if (env && strchr(env, '/')) { - search_path = ""; - if ((geteuid() != getuid() || getegid() != getgid())) { - _eglLog(_EGL_DEBUG, - "ignore EGL_DRIVER for setuid/setgid binaries"); - env = NULL; - } - } - else if (env) { - char *suffix = strchr(env, '.'); - name_len = (suffix) ? suffix - env : strlen(env); - } -#else - if (env) - name_len = strlen(env); -#endif /* _EGL_OS_UNIX */ - - /* - * Try built-in drivers first if we know the driver name. This makes sure - * we do not load the outdated external driver that is still on the - * filesystem. - */ - if (name_len) { - _EGLModule *mod; - EGLint i; - - for (i = 0; _eglBuiltInDrivers[i].name; i++) { - if (strlen(_eglBuiltInDrivers[i].name) == name_len && - !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) { - mod = _eglAddModule(env); - if (mod) - mod->BuiltIn = _eglBuiltInDrivers[i].main; - - return EGL_TRUE; - } - } - } - - /* otherwise, treat env as a path */ - if (env) { - _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env); - - return EGL_TRUE; - } - - return EGL_FALSE; -} - - -/** - * Add egl_gallium to the module array. - */ -static void -_eglAddGalliumDriver(void) -{ -#ifndef _EGL_BUILT_IN_DRIVER_GALLIUM - void *external = (void *) "egl_gallium"; - _eglPreloadForEach(_eglGetSearchPath(), _eglLoaderFile, external); -#endif -} -#endif - - -/** - * Add built-in drivers to the module array. - */ -static void -_eglAddBuiltInDrivers(void) -{ - _EGLModule *mod; - EGLint i; - - for (i = 0; _eglBuiltInDrivers[i].name; i++) { - mod = _eglAddModule(_eglBuiltInDrivers[i].name); - if (mod) - mod->BuiltIn = _eglBuiltInDrivers[i].main; - } -} - - -/** - * Add drivers to the module array. Drivers will be loaded as they are matched - * to displays. - */ -static EGLBoolean -_eglAddDrivers(void) -{ - if (_eglModules) - return EGL_TRUE; - -// if (!_eglAddUserDriver()) { - /* - * Add other drivers only when EGL_DRIVER is not set. The order here - * decides the priorities. - */ -// _eglAddGalliumDriver(); - _eglAddBuiltInDrivers(); -// } - - return (_eglModules != NULL); -} - - -/** - * A helper function for _eglMatchDriver. It finds the first driver that can - * initialize the display and return. - */ -static _EGLDriver * -_eglMatchAndInitialize(_EGLDisplay *dpy) -{ - _EGLDriver *drv = NULL; - EGLint i = 0; - - if (!_eglAddDrivers()) { - _eglLog(_EGL_WARNING, "failed to find any driver"); - return NULL; - } - - if (dpy->Driver) { - drv = dpy->Driver; - /* no re-matching? */ - if (!drv->API.Initialize(drv, dpy)) - drv = NULL; - return drv; - } - - while (i < _eglModules->Size) { - _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; - - if (!_eglLoadModule(mod)) { - /* remove invalid modules */ - _eglEraseArray(_eglModules, i, _eglFreeModule); - continue; - } - - if (mod->Driver->API.Initialize(mod->Driver, dpy)) { - drv = mod->Driver; - break; - } - else { - i++; - } - } - - return drv; -} - - -/** - * Match a display to a driver. The display is initialized unless test_only is - * true. The matching is done by finding the first driver that can initialize - * the display. - */ -_EGLDriver * -_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) -{ - _EGLDriver *best_drv; - - assert(!dpy->Initialized); - - _eglLockMutex(&_eglModuleMutex); - - /* set options */ - dpy->Options.TestOnly = test_only; - dpy->Options.UseFallback = EGL_FALSE; - - best_drv = _eglMatchAndInitialize(dpy); - if (!best_drv) { - dpy->Options.UseFallback = EGL_TRUE; - best_drv = _eglMatchAndInitialize(dpy); - } - - _eglUnlockMutex(&_eglModuleMutex); - - if (best_drv) { - _eglLog(_EGL_DEBUG, "the best driver is %s%s", - best_drv->Name, (test_only) ? " (test only) " : ""); - if (!test_only) { - dpy->Driver = best_drv; - dpy->Initialized = EGL_TRUE; - } - } - - return best_drv; -} - - -__eglMustCastToProperFunctionPointerType -_eglGetDriverProc(const char *procname) -{ - EGLint i; - _EGLProc proc = NULL; - - if (!_eglModules) { - /* load the driver for the default display */ - EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); - _EGLDisplay *dpy = _eglLookupDisplay(egldpy); - if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) - return NULL; - } - - for (i = 0; i < _eglModules->Size; i++) { - _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; - - if (!mod->Driver) - break; - proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); - if (proc) - break; - } - - return proc; -} - - -/** - * Unload all drivers. - */ -void -_eglUnloadDrivers(void) -{ - /* this is called at atexit time */ - if (_eglModules) { - _eglDestroyArray(_eglModules, _eglFreeModule); - _eglModules = NULL; - } -} - -#if 0 -/** - * Invoke a callback function on each EGL search path. - * - * The first argument of the callback function is the name of the search path. - * The second argument is the length of the name. - */ -void -_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *), - void *callback_data) -{ - const char *search_path = _eglGetSearchPath(); - _eglPreloadForEach(search_path, callback, callback_data); -} -#endif diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglscreen.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglscreen.c.bak deleted file mode 100644 index 7cc9d2d13d..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglscreen.c.bak +++ /dev/null @@ -1,240 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/* - * Ideas for screen management extension to EGL. - * - * Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc). - * The screens' handles can be obtained with eglGetScreensMESA(). - * - * A new kind of EGLSurface is possible- one which can be directly scanned - * out on a screen. Such a surface is created with eglCreateScreenSurface(). - * - * To actually display a screen surface on a screen, the eglShowSurface() - * function is called. - */ - -#include -#include -#include - -#define EGL_EGLEXT_PROTOTYPES -#include -#include - -#include "egldisplay.h" -#include "eglcurrent.h" -#include "eglmode.h" -#include "eglsurface.h" -#include "eglscreen.h" -#include "eglmutex.h" - -//#define EGL_MESA_screen_surface - -#ifdef EGL_MESA_screen_surface - - -/* ugh, no atomic op? */ -static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex); -static EGLScreenMESA _eglNextScreenHandle = 1; - - -/** - * Return a new screen handle/ID. - * NOTE: we never reuse these! - */ -static EGLScreenMESA -_eglAllocScreenHandle(void) -{ - EGLScreenMESA s; - - _eglLockMutex(&_eglNextScreenHandleMutex); - s = _eglNextScreenHandle; - _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES; - _eglUnlockMutex(&_eglNextScreenHandleMutex); - - return s; -} - - -/** - * Initialize an _EGLScreen object to default values. - */ -void -_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes) -{ - memset(screen, 0, sizeof(_EGLScreen)); - - screen->Display = dpy; - screen->NumModes = num_modes; - screen->StepX = 1; - screen->StepY = 1; - - if (num_modes > _EGL_SCREEN_MAX_MODES) - num_modes = _EGL_SCREEN_MAX_MODES; - screen->Modes = calloc(num_modes, sizeof(*screen->Modes)); - screen->NumModes = (screen->Modes) ? num_modes : 0; -} - - -/** - * Link a screen to its display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLScreenMESA -_eglLinkScreen(_EGLScreen *screen) -{ - _EGLDisplay *display; - EGLint i; - - assert(screen && screen->Display); - display = screen->Display; - - if (!display->Screens) { - display->Screens = _eglCreateArray("Screen", 4); - if (!display->Screens) - return (EGLScreenMESA) 0; - } - - screen->Handle = _eglAllocScreenHandle(); - for (i = 0; i < screen->NumModes; i++) - screen->Modes[i].Handle = screen->Handle + i; - - _eglAppendArray(display->Screens, (void *) screen); - - return screen->Handle; -} - - -/** - * Lookup a handle to find the linked config. - * Return NULL if the handle has no corresponding linked config. - */ -_EGLScreen * -_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display) -{ - EGLint i; - - if (!display || !display->Screens) - return NULL; - - for (i = 0; i < display->Screens->Size; i++) { - _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i]; - if (scr->Handle == screen) { - assert(scr->Display == display); - return scr; - } - } - return NULL; -} - - -static EGLBoolean -_eglFlattenScreen(void *elem, void *buffer) -{ - _EGLScreen *scr = (_EGLScreen *) elem; - EGLScreenMESA *handle = (EGLScreenMESA *) buffer; - *handle = _eglGetScreenHandle(scr); - return EGL_TRUE; -} - - -EGLBoolean -_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens, - EGLint max_screens, EGLint *num_screens) -{ - *num_screens = _eglFlattenArray(display->Screens, (void *) screens, - sizeof(screens[0]), max_screens, _eglFlattenScreen); - - return EGL_TRUE; -} - - -/** - * Set a screen's surface origin. - */ -EGLBoolean -_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scrn, EGLint x, EGLint y) -{ - scrn->OriginX = x; - scrn->OriginY = y; - - return EGL_TRUE; -} - - -/** - * Query a screen's current surface. - */ -EGLBoolean -_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *scrn, _EGLSurface **surf) -{ - *surf = scrn->CurrentSurface; - return EGL_TRUE; -} - - -/** - * Query a screen's current mode. - */ -EGLBoolean -_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - _EGLMode **m) -{ - *m = scrn->CurrentMode; - return EGL_TRUE; -} - - -EGLBoolean -_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, - EGLint attribute, EGLint *value) -{ - switch (attribute) { - case EGL_SCREEN_POSITION_MESA: - value[0] = scrn->OriginX; - value[1] = scrn->OriginY; - break; - case EGL_SCREEN_POSITION_GRANULARITY_MESA: - value[0] = scrn->StepX; - value[1] = scrn->StepY; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA"); - return EGL_FALSE; - } - - return EGL_TRUE; -} - - -#endif /* EGL_MESA_screen_surface */ diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.c.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.c.bak deleted file mode 100644 index c80c85396d..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.c.bak +++ /dev/null @@ -1,543 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Surface-related functions. - */ - - -#include -#include -#include -#include "egldisplay.h" -#include "egldriver.h" -#include "eglcontext.h" -#include "eglconfig.h" -#include "eglcurrent.h" -#include "egllog.h" -#include "eglsurface.h" - - -static void -_eglClampSwapInterval(_EGLSurface *surf, EGLint interval) -{ - EGLint bound = surf->Config->MaxSwapInterval; - if (interval >= bound) { - interval = bound; - } - else { - bound = surf->Config->MinSwapInterval; - if (interval < bound) - interval = bound; - } - surf->SwapInterval = interval; -} - - -#ifdef EGL_MESA_screen_surface -static EGLint -_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) -{ - EGLint i, err = EGL_SUCCESS; - - if (!attrib_list) - return EGL_SUCCESS; - - for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; - - switch (attr) { - case EGL_WIDTH: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Width = val; - break; - case EGL_HEIGHT: - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Height = val; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); - break; - } - } - - return err; -} -#endif /* EGL_MESA_screen_surface */ - - -/** - * Parse the list of surface attributes and return the proper error code. - */ -static EGLint -_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) -{ - _EGLDisplay *dpy = surf->Resource.Display; - EGLint type = surf->Type; - EGLint texture_type = EGL_PBUFFER_BIT; - EGLint i, err = EGL_SUCCESS; - - if (!attrib_list) - return EGL_SUCCESS; - -#ifdef EGL_MESA_screen_surface - if (type == EGL_SCREEN_BIT_MESA) - return _eglParseScreenSurfaceAttribList(surf, attrib_list); -#endif - - if (dpy->Extensions.NOK_texture_from_pixmap) - texture_type |= EGL_PIXMAP_BIT; - - for (i = 0; attrib_list[i] != EGL_NONE; i++) { - EGLint attr = attrib_list[i++]; - EGLint val = attrib_list[i]; - - switch (attr) { - /* common attributes */ - case EGL_VG_COLORSPACE: - switch (val) { - case EGL_VG_COLORSPACE_sRGB: - case EGL_VG_COLORSPACE_LINEAR: - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surf->VGColorspace = val; - break; - case EGL_VG_ALPHA_FORMAT: - switch (val) { - case EGL_VG_ALPHA_FORMAT_NONPRE: - case EGL_VG_ALPHA_FORMAT_PRE: - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surf->VGAlphaFormat = val; - break; - /* window surface attributes */ - case EGL_RENDER_BUFFER: - if (type != EGL_WINDOW_BIT) { - err = EGL_BAD_ATTRIBUTE; - break; - } - if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) { - err = EGL_BAD_ATTRIBUTE; - break; - } - surf->RenderBuffer = val; - break; - case EGL_POST_SUB_BUFFER_SUPPORTED_NV: - if (!dpy->Extensions.NV_post_sub_buffer || - type != EGL_WINDOW_BIT) { - err = EGL_BAD_ATTRIBUTE; - break; - } - if (val != EGL_TRUE && val != EGL_FALSE) { - err = EGL_BAD_PARAMETER; - break; - } - surf->PostSubBufferSupportedNV = val; - break; - /* pbuffer surface attributes */ - case EGL_WIDTH: - if (type != EGL_PBUFFER_BIT) { - err = EGL_BAD_ATTRIBUTE; - break; - } - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Width = val; - break; - case EGL_HEIGHT: - if (type != EGL_PBUFFER_BIT) { - err = EGL_BAD_ATTRIBUTE; - break; - } - if (val < 0) { - err = EGL_BAD_PARAMETER; - break; - } - surf->Height = val; - break; - case EGL_LARGEST_PBUFFER: - if (type != EGL_PBUFFER_BIT) { - err = EGL_BAD_ATTRIBUTE; - break; - } - surf->LargestPbuffer = !!val; - break; - /* for eglBindTexImage */ - case EGL_TEXTURE_FORMAT: - if (!(type & texture_type)) { - err = EGL_BAD_ATTRIBUTE; - break; - } - switch (val) { - case EGL_TEXTURE_RGB: - case EGL_TEXTURE_RGBA: - case EGL_NO_TEXTURE: - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surf->TextureFormat = val; - break; - case EGL_TEXTURE_TARGET: - if (!(type & texture_type)) { - err = EGL_BAD_ATTRIBUTE; - break; - } - switch (val) { - case EGL_TEXTURE_2D: - case EGL_NO_TEXTURE: - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surf->TextureTarget = val; - break; - case EGL_MIPMAP_TEXTURE: - if (!(type & texture_type)) { - err = EGL_BAD_ATTRIBUTE; - break; - } - surf->MipmapTexture = !!val; - break; - /* no pixmap surface specific attributes */ - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) { - _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); - break; - } - } - - return err; -} - - -/** - * Do error check on parameters and initialize the given _EGLSurface object. - * \return EGL_TRUE if no errors, EGL_FALSE otherwise. - */ -EGLBoolean -_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, - _EGLConfig *conf, const EGLint *attrib_list) -{ - const char *func; - EGLint renderBuffer = EGL_BACK_BUFFER; - EGLint swapBehavior = EGL_BUFFER_PRESERVED; - EGLint err; - - printf("%s\n",__FUNCTION__); - - switch (type) { - case EGL_WINDOW_BIT: - func = "eglCreateWindowSurface"; - swapBehavior = EGL_BUFFER_DESTROYED; - break; - case EGL_PIXMAP_BIT: - func = "eglCreatePixmapSurface"; - renderBuffer = EGL_SINGLE_BUFFER; - break; - case EGL_PBUFFER_BIT: - func = "eglCreatePBufferSurface"; - break; -#ifdef EGL_MESA_screen_surface - case EGL_SCREEN_BIT_MESA: - func = "eglCreateScreenSurface"; - renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ - break; -#endif - default: - _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); - return EGL_FALSE; - } - - if ((conf->SurfaceType & type) == 0) { - /* The config can't be used to create a surface of this type */ - _eglError(EGL_BAD_CONFIG, func); - return EGL_FALSE; - } - - _eglInitResource(&surf->Resource, sizeof(*surf), dpy); - surf->Type = type; - surf->Config = conf; - - surf->Width = 0; - surf->Height = 0; - surf->TextureFormat = EGL_NO_TEXTURE; - surf->TextureTarget = EGL_NO_TEXTURE; - surf->MipmapTexture = EGL_FALSE; - surf->LargestPbuffer = EGL_FALSE; - surf->RenderBuffer = renderBuffer; - surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE; - surf->VGColorspace = EGL_VG_COLORSPACE_sRGB; - - surf->MipmapLevel = 0; - surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT; - surf->SwapBehavior = swapBehavior; - - surf->HorizontalResolution = EGL_UNKNOWN; - surf->VerticalResolution = EGL_UNKNOWN; - surf->AspectRatio = EGL_UNKNOWN; - - surf->PostSubBufferSupportedNV = EGL_FALSE; - - /* the default swap interval is 1 */ - _eglClampSwapInterval(surf, 1); - - err = _eglParseSurfaceAttribList(surf, attrib_list); - if (err != EGL_SUCCESS) - return _eglError(err, func); - - return EGL_TRUE; -} - - -EGLBoolean -_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, - EGLint attribute, EGLint *value) -{ - switch (attribute) { - case EGL_WIDTH: - *value = surface->Width; - break; - case EGL_HEIGHT: - *value = surface->Height; - break; - case EGL_CONFIG_ID: - *value = surface->Config->ConfigID; - break; - case EGL_LARGEST_PBUFFER: - *value = surface->LargestPbuffer; - break; - case EGL_TEXTURE_FORMAT: - /* texture attributes: only for pbuffers, no error otherwise */ - if (surface->Type == EGL_PBUFFER_BIT) - *value = surface->TextureFormat; - break; - case EGL_TEXTURE_TARGET: - if (surface->Type == EGL_PBUFFER_BIT) - *value = surface->TextureTarget; - break; - case EGL_MIPMAP_TEXTURE: - if (surface->Type == EGL_PBUFFER_BIT) - *value = surface->MipmapTexture; - break; - case EGL_MIPMAP_LEVEL: - if (surface->Type == EGL_PBUFFER_BIT) - *value = surface->MipmapLevel; - break; - case EGL_SWAP_BEHAVIOR: - *value = surface->SwapBehavior; - break; - case EGL_RENDER_BUFFER: - *value = surface->RenderBuffer; - break; - case EGL_PIXEL_ASPECT_RATIO: - *value = surface->AspectRatio; - break; - case EGL_HORIZONTAL_RESOLUTION: - *value = surface->HorizontalResolution; - break; - case EGL_VERTICAL_RESOLUTION: - *value = surface->VerticalResolution; - break; - case EGL_MULTISAMPLE_RESOLVE: - *value = surface->MultisampleResolve; - break; - case EGL_VG_ALPHA_FORMAT: - *value = surface->VGAlphaFormat; - break; - case EGL_VG_COLORSPACE: - *value = surface->VGColorspace; - break; - case EGL_POST_SUB_BUFFER_SUPPORTED_NV: - *value = surface->PostSubBufferSupportedNV; - break; - case EGL_BUFFER_AGE_EXT: - if (!dpy->Extensions.EXT_buffer_age) { - _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); - return EGL_FALSE; - } - *value = drv->API.QueryBufferAge(drv, dpy, surface); - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); - return EGL_FALSE; - } - - return EGL_TRUE; -} - - -/** - * Default fallback routine - drivers might override this. - */ -EGLBoolean -_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, - EGLint attribute, EGLint value) -{ - EGLint confval; - EGLint err = EGL_SUCCESS; - EGLint all_es_bits = EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENGL_ES3_BIT_KHR; - - switch (attribute) { - case EGL_MIPMAP_LEVEL: - confval = surface->Config->RenderableType; - if (!(confval & all_es_bits)) { - err = EGL_BAD_PARAMETER; - break; - } - surface->MipmapLevel = value; - break; - case EGL_MULTISAMPLE_RESOLVE: - switch (value) { - case EGL_MULTISAMPLE_RESOLVE_DEFAULT: - break; - case EGL_MULTISAMPLE_RESOLVE_BOX: - confval = surface->Config->SurfaceType; - if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) - err = EGL_BAD_MATCH; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surface->MultisampleResolve = value; - break; - case EGL_SWAP_BEHAVIOR: - switch (value) { - case EGL_BUFFER_DESTROYED: - break; - case EGL_BUFFER_PRESERVED: - confval = surface->Config->SurfaceType; - if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) - err = EGL_BAD_MATCH; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - if (err != EGL_SUCCESS) - break; - surface->SwapBehavior = value; - break; - default: - err = EGL_BAD_ATTRIBUTE; - break; - } - - if (err != EGL_SUCCESS) - return _eglError(err, "eglSurfaceAttrib"); - return EGL_TRUE; -} - - -EGLBoolean -_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, - EGLint buffer) -{ - EGLint texture_type = EGL_PBUFFER_BIT; - - /* Just do basic error checking and return success/fail. - * Drivers must implement the real stuff. - */ - - if (dpy->Extensions.NOK_texture_from_pixmap) - texture_type |= EGL_PIXMAP_BIT; - - if (!(surface->Type & texture_type)) { - _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); - return EGL_FALSE; - } - - if (surface->TextureFormat == EGL_NO_TEXTURE) { - _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - return EGL_FALSE; - } - - if (surface->TextureTarget == EGL_NO_TEXTURE) { - _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - return EGL_FALSE; - } - - if (buffer != EGL_BACK_BUFFER) { - _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); - return EGL_FALSE; - } - - surface->BoundToTexture = EGL_TRUE; - - return EGL_TRUE; -} - - -EGLBoolean -_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - EGLint interval) -{ - _eglClampSwapInterval(surf, interval); - return EGL_TRUE; -} diff --git a/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.h.bak b/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.h.bak deleted file mode 100644 index 538710b17a..0000000000 --- a/contrib/sdk/sources/Mesa/src/egl/main/eglsurface.h.bak +++ /dev/null @@ -1,175 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009-2010 Chia-I Wu - * Copyright 2010 LunarG, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef EGLSURFACE_INCLUDED -#define EGLSURFACE_INCLUDED - - -#include "egltypedefs.h" -#include "egldisplay.h" - - -/** - * "Base" class for device driver surfaces. - */ -struct _egl_surface -{ - /* A surface is a display resource */ - _EGLResource Resource; - - /* The context that is currently bound to the surface */ - _EGLContext *CurrentContext; - - _EGLConfig *Config; - - EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */ - - /* attributes set by attribute list */ - EGLint Width, Height; - EGLenum TextureFormat; - EGLenum TextureTarget; - EGLBoolean MipmapTexture; - EGLBoolean LargestPbuffer; - EGLenum RenderBuffer; - EGLenum VGAlphaFormat; - EGLenum VGColorspace; - - /* attributes set by eglSurfaceAttrib */ - EGLint MipmapLevel; - EGLenum MultisampleResolve; - EGLenum SwapBehavior; - - EGLint HorizontalResolution, VerticalResolution; - EGLint AspectRatio; - - EGLint SwapInterval; - - /* True if the surface is bound to an OpenGL ES texture */ - EGLBoolean BoundToTexture; - - EGLBoolean PostSubBufferSupportedNV; -}; - - -PUBLIC EGLBoolean -_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, - _EGLConfig *config, const EGLint *attrib_list); - - -extern EGLBoolean -_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value); - - -extern EGLBoolean -_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value); - - -PUBLIC extern EGLBoolean -_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer); - - -extern EGLBoolean -_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval); - - -/** - * Increment reference count for the surface. - */ -static INLINE _EGLSurface * -_eglGetSurface(_EGLSurface *surf) -{ - if (surf) - _eglGetResource(&surf->Resource); - return surf; -} - - -/** - * Decrement reference count for the surface. - */ -static INLINE EGLBoolean -_eglPutSurface(_EGLSurface *surf) -{ - return (surf) ? _eglPutResource(&surf->Resource) : EGL_FALSE; -} - - -/** - * Link a surface to its display and return the handle of the link. - * The handle can be passed to client directly. - */ -static INLINE EGLSurface -_eglLinkSurface(_EGLSurface *surf) -{ - printf("%s surface: %p\n", __FUNCTION__, surf); - - _eglLinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE); - return (EGLSurface) surf; -} - - -/** - * Unlink a linked surface from its display. - * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. - */ -static INLINE void -_eglUnlinkSurface(_EGLSurface *surf) -{ - _eglUnlinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE); -} - - -/** - * Lookup a handle to find the linked surface. - * Return NULL if the handle has no corresponding linked surface. - */ -static INLINE _EGLSurface * -_eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy) -{ - _EGLSurface *surf = (_EGLSurface *) surface; - if (!dpy || !_eglCheckResource((void *) surf, _EGL_RESOURCE_SURFACE, dpy)) - surf = NULL; - return surf; -} - - -/** - * Return the handle of a linked surface, or EGL_NO_SURFACE. - */ -static INLINE EGLSurface -_eglGetSurfaceHandle(_EGLSurface *surf) -{ - _EGLResource *res = (_EGLResource *) surf; - return (res && _eglIsResourceLinked(res)) ? - (EGLSurface) surf : EGL_NO_SURFACE; -} - - -#endif /* EGLSURFACE_INCLUDED */ diff --git a/contrib/sdk/sources/Mesa/src/gbm/backends/dri/gbm_dri.c.bak b/contrib/sdk/sources/Mesa/src/gbm/backends/dri/gbm_dri.c.bak deleted file mode 100644 index 095bc5590f..0000000000 --- a/contrib/sdk/sources/Mesa/src/gbm/backends/dri/gbm_dri.c.bak +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke - */ - -#include -#include -#include -#include -#include -#include - -#include -//#include -#include -//#include -#include - -#include /* dri_interface needs GL types */ -#include - -#include "gbm_driint.h" - -#include "gbmint.h" - -/* For importing wl_buffer */ -#if HAVE_WAYLAND_PLATFORM -#include "../../../egl/wayland/wayland-drm/wayland-drm.h" -#endif - -void *load_library(const char *name); -void *get_proc_address(void *lib, char *proc_name); - - -static __DRIimage * -dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data) -{ - struct gbm_dri_device *dri = data; - - if (dri->lookup_image == NULL) - return NULL; - - return dri->lookup_image(screen, image, dri->lookup_user_data); -} - -static __DRIbuffer * -dri_get_buffers(__DRIdrawable * driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *data) -{ - struct gbm_dri_surface *surf = data; - struct gbm_dri_device *dri = gbm_dri_device(surf->base.gbm); - - if (dri->get_buffers == NULL) - return NULL; - - return dri->get_buffers(driDrawable, width, height, attachments, - count, out_count, surf->dri_private); -} - -static void -dri_flush_front_buffer(__DRIdrawable * driDrawable, void *data) -{ - struct gbm_dri_surface *surf = data; - struct gbm_dri_device *dri = gbm_dri_device(surf->base.gbm); - - if (dri->flush_front_buffer != NULL) - dri->flush_front_buffer(driDrawable, surf->dri_private); -} - -static __DRIbuffer * -dri_get_buffers_with_format(__DRIdrawable * driDrawable, - int *width, int *height, - unsigned int *attachments, int count, - int *out_count, void *data) -{ - struct gbm_dri_surface *surf = data; - struct gbm_dri_device *dri = gbm_dri_device(surf->base.gbm); - - if (dri->get_buffers_with_format == NULL) - return NULL; - - return - dri->get_buffers_with_format(driDrawable, width, height, attachments, - count, out_count, surf->dri_private); -} - -static const __DRIuseInvalidateExtension use_invalidate = { - { __DRI_USE_INVALIDATE, 1 } -}; - -static const __DRIimageLookupExtension image_lookup_extension = { - { __DRI_IMAGE_LOOKUP, 1 }, - dri_lookup_egl_image -}; - -const __DRIdri2LoaderExtension dri2_loader_extension = { - { __DRI_DRI2_LOADER, 3 }, - dri_get_buffers, - dri_flush_front_buffer, - dri_get_buffers_with_format, -}; - -struct dri_extension_match { - const char *name; - int version; - int offset; -}; - -static struct dri_extension_match dri_core_extensions[] = { - { __DRI2_FLUSH, 1, offsetof(struct gbm_dri_device, flush) }, - { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) }, - { NULL, 0, 0 } -}; - -static struct dri_extension_match gbm_dri_device_extensions[] = { - { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) }, - { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) }, - { NULL, 0, 0 } -}; - -static int -dri_bind_extensions(struct gbm_dri_device *dri, - struct dri_extension_match *matches, - const __DRIextension **extensions) -{ - int i, j, ret = 0; - void *field; - - for (i = 0; extensions[i]; i++) { - for (j = 0; matches[j].name; j++) { - if (strcmp(extensions[i]->name, matches[j].name) == 0 && - extensions[i]->version >= matches[j].version) { - field = ((char *) dri + matches[j].offset); - *(const __DRIextension **) field = extensions[i]; - } - } - } - - for (j = 0; matches[j].name; j++) { - field = ((char *) dri + matches[j].offset); - if (*(const __DRIextension **) field == NULL) { - ret = -1; - } - } - - return ret; -} - -static int -dri_load_driver(struct gbm_dri_device *dri) -{ - const __DRIextension **extensions; -// char path[PATH_MAX], *search_paths, *p, *next, *end; - char *search_paths; - - search_paths = NULL; - -#if 0 - - if (geteuid() == getuid()) { - /* don't allow setuid apps to use GBM_DRIVERS_PATH */ - search_paths = getenv("GBM_DRIVERS_PATH"); - } - if (search_paths == NULL) - search_paths = DEFAULT_DRIVER_DIR; - - dri->driver = NULL; - end = search_paths + strlen(search_paths); - for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) { - int len; - next = strchr(p, ':'); - if (next == NULL) - next = end; - - len = next - p; -#if GLX_USE_TLS - snprintf(path, sizeof path, - "%.*s/tls/%s_dri.so", len, p, dri->base.driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); -#endif - if (dri->driver == NULL) { - snprintf(path, sizeof path, - "%.*s/%s_dri.so", len, p, dri->base.driver_name); - dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (dri->driver == NULL) - fprintf(stderr, "failed to open %s: %s\n", path, dlerror()); - } - } -#endif - - dri->driver = load_library("libGL.dll"); - - if (dri->driver == NULL) { - fprintf(stderr, "gbm: failed to open any driver (search paths %s)", - search_paths); - return -1; - } - - extensions = get_proc_address(dri->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - fprintf(stderr, "gbm: driver exports no extensions\n"); -// dlclose(dri->driver); - return -1; - } - - - if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) { -// dlclose(dri->driver); - fprintf(stderr, "failed to bind extensions\n"); - return -1; - } - - return 0; -} - -static int -dri_screen_create(struct gbm_dri_device *dri) -{ - const __DRIextension **extensions; - int ret = 0; - - dri->base.driver_name = strdup("drm"); //dri_fd_get_driver_name(dri->base.base.fd); - if (dri->base.driver_name == NULL) - return -1; - - ret = dri_load_driver(dri); - if (ret) { - fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name); - return ret; - }; - - dri->extensions[0] = &image_lookup_extension.base; - dri->extensions[1] = &use_invalidate.base; - dri->extensions[2] = &dri2_loader_extension.base; - dri->extensions[3] = NULL; - - if (dri->dri2 == NULL) - return -1; - - dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd, - dri->extensions, - &dri->driver_configs, dri); - if (dri->screen == NULL) - return -1; - - extensions = dri->core->getExtensions(dri->screen); - if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) { - ret = -1; - goto free_screen; - } - - dri->lookup_image = NULL; - dri->lookup_user_data = NULL; - - return 0; - -free_screen: - dri->core->destroyScreen(dri->screen); - - return ret; -} - -static int -gbm_dri_is_format_supported(struct gbm_device *gbm, - uint32_t format, - uint32_t usage) -{ - switch (format) { - case GBM_BO_FORMAT_XRGB8888: - case GBM_FORMAT_XRGB8888: - break; - case GBM_BO_FORMAT_ARGB8888: - case GBM_FORMAT_ARGB8888: - if (usage & GBM_BO_USE_SCANOUT) - return 0; - break; - default: - return 0; - } - - if (usage & GBM_BO_USE_CURSOR_64X64 && - usage & GBM_BO_USE_RENDERING) - return 0; - - return 1; -} - -static int -gbm_dri_bo_write(struct gbm_bo *_bo, const void *buf, size_t count) -{ - struct gbm_dri_bo *bo = gbm_dri_bo(_bo); - - if (bo->image != NULL) - return -1; - - memcpy(bo->map, buf, count); - - return 0; -} - -static void -gbm_dri_bo_destroy(struct gbm_bo *_bo) -{ - struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); - struct gbm_dri_bo *bo = gbm_dri_bo(_bo); -// struct drm_mode_destroy_dumb arg; - - if (bo->image != NULL) { - dri->image->destroyImage(bo->image); - } else { -// munmap(bo->map, bo->size); -// memset(&arg, 0, sizeof(arg)); -// arg.handle = bo->handle; -// drmIoctl(dri->base.base.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); - } - - free(bo); -} - -static uint32_t -gbm_dri_to_gbm_format(uint32_t dri_format) -{ - uint32_t ret = 0; - - switch (dri_format) { - case __DRI_IMAGE_FORMAT_RGB565: - ret = GBM_FORMAT_RGB565; - break; - case __DRI_IMAGE_FORMAT_XRGB8888: - ret = GBM_FORMAT_XRGB8888; - break; - case __DRI_IMAGE_FORMAT_ARGB8888: - ret = GBM_FORMAT_ARGB8888; - break; - case __DRI_IMAGE_FORMAT_ABGR8888: - ret = GBM_FORMAT_ABGR8888; - break; - default: - ret = 0; - break; - } - - return ret; -} - -static struct gbm_bo * -gbm_dri_bo_import(struct gbm_device *gbm, - uint32_t type, void *buffer, uint32_t usage) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - struct gbm_dri_bo *bo; - __DRIimage *image; - unsigned dri_use = 0; - int gbm_format; - - /* Required for query image WIDTH & HEIGHT */ - if (dri->image->base.version < 4) - return NULL; - - switch (type) { -#if HAVE_WAYLAND_PLATFORM - case GBM_BO_IMPORT_WL_BUFFER: - { - struct wl_drm_buffer *wb = (struct wl_drm_buffer *) buffer; - - if (!wayland_buffer_is_drm(buffer)) - return NULL; - - image = wb->driver_buffer; - - switch (wb->format) { - case WL_DRM_FORMAT_XRGB8888: - gbm_format = GBM_FORMAT_XRGB8888; - break; - case WL_DRM_FORMAT_ARGB8888: - gbm_format = GBM_FORMAT_ARGB8888; - break; - case WL_DRM_FORMAT_YUYV: - gbm_format = GBM_FORMAT_YUYV; - break; - default: - return NULL; - } - break; - } -#endif - - case GBM_BO_IMPORT_EGL_IMAGE: - { - int dri_format; - if (dri->lookup_image == NULL) - return NULL; - - image = dri->lookup_image(dri->screen, buffer, dri->lookup_user_data); - dri->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &dri_format); - gbm_format = gbm_dri_to_gbm_format(dri_format); - if (gbm_format == 0) - return NULL; - break; - } - - default: - return NULL; - } - - - bo = calloc(1, sizeof *bo); - if (bo == NULL) - return NULL; - - bo->image = dri->image->dupImage(image, NULL); - - if (usage & GBM_BO_USE_SCANOUT) - dri_use |= __DRI_IMAGE_USE_SCANOUT; - if (usage & GBM_BO_USE_CURSOR_64X64) - dri_use |= __DRI_IMAGE_USE_CURSOR; - if (dri->image->base.version >= 2 && - !dri->image->validateUsage(bo->image, dri_use)) { - free(bo); - return NULL; - } - - bo->base.base.gbm = gbm; - bo->base.base.format = gbm_format; - - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_WIDTH, - (int*)&bo->base.base.width); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HEIGHT, - (int*)&bo->base.base.height); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int*)&bo->base.base.stride); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.base.handle.s32); - - return &bo->base.base; -} - -#if 0 -static struct gbm_bo * -create_dumb(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - struct drm_mode_create_dumb create_arg; - struct drm_mode_map_dumb map_arg; - struct gbm_dri_bo *bo; - struct drm_mode_destroy_dumb destroy_arg; - int ret; - - if (!(usage & GBM_BO_USE_CURSOR_64X64)) - return NULL; - if (format != GBM_FORMAT_ARGB8888) - return NULL; - - bo = calloc(1, sizeof *bo); - if (bo == NULL) - return NULL; - - create_arg.bpp = 32; - create_arg.width = width; - create_arg.height = height; - - ret = drmIoctl(dri->base.base.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg); - if (ret) - goto free_bo; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - bo->base.base.stride = create_arg.pitch; - bo->base.base.format = format; - bo->base.base.handle.u32 = create_arg.handle; - bo->handle = create_arg.handle; - bo->size = create_arg.size; - - memset(&map_arg, 0, sizeof(map_arg)); - map_arg.handle = bo->handle; - - ret = drmIoctl(dri->base.base.fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg); - if (ret) - goto destroy_dumb; - - bo->map = mmap(0, bo->size, PROT_WRITE, - MAP_SHARED, dri->base.base.fd, map_arg.offset); - if (bo->map == MAP_FAILED) - goto destroy_dumb; - - return &bo->base.base; - -destroy_dumb: - memset(&destroy_arg, 0, sizeof destroy_arg); - destroy_arg.handle = create_arg.handle; - drmIoctl(dri->base.base.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); -free_bo: - free(bo); - - return NULL; -} -#endif - -static struct gbm_bo * -gbm_dri_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - struct gbm_dri_bo *bo; - int dri_format; - unsigned dri_use = 0; - -// if (usage & GBM_BO_USE_WRITE) -// return create_dumb(gbm, width, height, format, usage); - - bo = calloc(1, sizeof *bo); - if (bo == NULL) - return NULL; - - bo->base.base.gbm = gbm; - bo->base.base.width = width; - bo->base.base.height = height; - bo->base.base.format = format; - - switch (format) { - case GBM_FORMAT_RGB565: - dri_format =__DRI_IMAGE_FORMAT_RGB565; - break; - case GBM_FORMAT_XRGB8888: - case GBM_BO_FORMAT_XRGB8888: - dri_format = __DRI_IMAGE_FORMAT_XRGB8888; - break; - case GBM_FORMAT_ARGB8888: - case GBM_BO_FORMAT_ARGB8888: - dri_format = __DRI_IMAGE_FORMAT_ARGB8888; - break; - case GBM_FORMAT_ABGR8888: - dri_format = __DRI_IMAGE_FORMAT_ABGR8888; - break; - default: - return NULL; - } - - if (usage & GBM_BO_USE_SCANOUT) - dri_use |= __DRI_IMAGE_USE_SCANOUT; - if (usage & GBM_BO_USE_CURSOR_64X64) - dri_use |= __DRI_IMAGE_USE_CURSOR; - - /* Gallium drivers requires shared in order to get the handle/stride */ - dri_use |= __DRI_IMAGE_USE_SHARE; - - bo->image = - dri->image->createImage(dri->screen, - width, height, - dri_format, dri_use, - bo); - if (bo->image == NULL) - return NULL; - - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.base.handle.s32); - dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int *) &bo->base.base.stride); - - printf("gbm_dri_bo_create bo: %p handle %d" - " width: %d height: %d pitch: %d format %d\n",bo, bo->base.base.handle.s32, - bo->base.base.width, bo->base.base.height, - (int)bo->base.base.stride,bo->base.base.format); - - return &bo->base.base; -} - -static struct gbm_surface * -gbm_dri_surface_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) -{ - struct gbm_dri_surface *surf; - - surf = calloc(1, sizeof *surf); - if (surf == NULL) - return NULL; - - surf->base.gbm = gbm; - surf->base.width = width; - surf->base.height = height; - surf->base.format = format; - surf->base.flags = flags; - - return &surf->base; -} - -static void -gbm_dri_surface_destroy(struct gbm_surface *_surf) -{ - struct gbm_dri_surface *surf = gbm_dri_surface(_surf); - - free(surf); -} - -static void -dri_destroy(struct gbm_device *gbm) -{ - struct gbm_dri_device *dri = gbm_dri_device(gbm); - - dri->core->destroyScreen(dri->screen); - free(dri->driver_configs); -// dlclose(dri->driver); - free(dri->base.driver_name); - - free(dri); -} - -static struct gbm_device * -dri_device_create(int fd) -{ - struct gbm_dri_device *dri; - int ret; - - dri = calloc(1, sizeof *dri); - - dri->base.base.fd = fd; - dri->base.base.bo_create = gbm_dri_bo_create; - dri->base.base.bo_import = gbm_dri_bo_import; - dri->base.base.is_format_supported = gbm_dri_is_format_supported; - dri->base.base.bo_write = gbm_dri_bo_write; - dri->base.base.bo_destroy = gbm_dri_bo_destroy; - dri->base.base.destroy = dri_destroy; - dri->base.base.surface_create = gbm_dri_surface_create; - dri->base.base.surface_destroy = gbm_dri_surface_destroy; - - dri->base.type = GBM_DRM_DRIVER_TYPE_DRI; - dri->base.base.name = "drm"; - - ret = dri_screen_create(dri); - if (ret) - goto err_dri; - - return &dri->base.base; - -err_dri: - free(dri); - - return NULL; -} - -struct gbm_backend gbm_dri_backend = { - .backend_name = "dri", - .create_device = dri_device_create, -}; diff --git a/contrib/sdk/sources/Mesa/src/gbm/main/gbm.c.bak b/contrib/sdk/sources/Mesa/src/gbm/main/gbm.c.bak deleted file mode 100644 index 6efca8571d..0000000000 --- a/contrib/sdk/sources/Mesa/src/gbm/main/gbm.c.bak +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Benjamin Franzke - */ - -#define _BSD_SOURCE - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gbm.h" -#include "gbmint.h" -#include "common.h" -#include "backend.h" - -#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) - -struct gbm_device *devices[16]; - -static int device_num = 0; - -/** Returns the file description for the gbm device - * - * \return The fd that the struct gbm_device was created with - */ -GBM_EXPORT int -gbm_device_get_fd(struct gbm_device *gbm) -{ - return gbm->fd; -} - -/* FIXME: maybe superfluous, use udev subclass from the fd? */ -/** Get the backend name for the given gbm device - * - * \return The backend name string - this belongs to the device and must not - * be freed - */ -GBM_EXPORT const char * -gbm_device_get_backend_name(struct gbm_device *gbm) -{ - return gbm->name; -} - -/** Test if a format is supported for a given set of usage flags. - * - * \param gbm The created buffer manager - * \param format The format to test - * \param usage A bitmask of the usages to test the format against - * \return 1 if the format is supported otherwise 0 - * - * \sa enum gbm_bo_flags for the list of flags that the format can be - * tested against - * - * \sa enum gbm_bo_format for the list of formats - */ -int -gbm_device_is_format_supported(struct gbm_device *gbm, - uint32_t format, uint32_t usage) -{ - return gbm->is_format_supported(gbm, format, usage); -} - -/** Destroy the gbm device and free all resources associated with it. - * - * \param gbm The device created using gbm_create_device() - */ -GBM_EXPORT void -gbm_device_destroy(struct gbm_device *gbm) -{ - gbm->refcount--; - if (gbm->refcount == 0) - gbm->destroy(gbm); -} - -#if 0 -GBM_EXPORT struct gbm_device * -_gbm_mesa_get_device(int fd) -{ - struct gbm_device *gbm = NULL; - struct stat buf; - dev_t dev; - int i; - - for (i = 0; i < device_num; ++i) { - dev = devices[i]->stat.st_rdev; - if (major(dev) == major(buf.st_rdev) && - minor(dev) == minor(buf.st_rdev)) { - gbm = devices[i]; - gbm->refcount++; - break; - } - } - - return gbm; -} -#endif - -/** Create a gbm device for allocating buffers - * - * The file descriptor passed in is used by the backend to communicate with - * platform for allocating the memory. For allocations using DRI this would be - * the file descriptor returned when opening a device such as \c - * /dev/dri/card0 - * - * \param fd The file descriptor for an backend specific device - * \return The newly created struct gbm_device. The resources associated with - * the device should be freed with gbm_device_destroy() when it is no longer - * needed. If the creation of the device failed NULL will be returned. - */ -GBM_EXPORT struct gbm_device * -gbm_create_device(int fd) -{ - struct gbm_device *gbm = NULL; - struct stat buf; - - if (fd == 0) { - fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd); - return NULL; - } - - if (device_num == 0) - memset(devices, 0, sizeof devices); - - gbm = _gbm_create_device(fd); - if (gbm == NULL) - return NULL; - - gbm->dummy = gbm_create_device; - gbm->stat = buf; - gbm->refcount = 1; - - if (device_num < ARRAY_SIZE(devices)-1) - devices[device_num++] = gbm; - - return gbm; -} - -/** Get the width of the buffer object - * - * \param bo The buffer object - * \return The width of the allocated buffer object - * - */ -GBM_EXPORT unsigned int -gbm_bo_get_width(struct gbm_bo *bo) -{ - return bo->width; -} - -/** Get the height of the buffer object - * - * \param bo The buffer object - * \return The height of the allocated buffer object - */ -GBM_EXPORT unsigned int -gbm_bo_get_height(struct gbm_bo *bo) -{ - return bo->height; -} - -/** Get the stride of the buffer object - * - * This is calculated by the backend when it does the allocation in - * gbm_bo_create() - * - * \param bo The buffer object - * \return The stride of the allocated buffer object in bytes - */ -GBM_EXPORT uint32_t -gbm_bo_get_stride(struct gbm_bo *bo) -{ - return bo->stride; -} - -/** Get the format of the buffer object - * - * The format of the pixels in the buffer. - * - * \param bo The buffer object - * \return The format of buffer object, on of the GBM_FORMAT_* codes - */ -GBM_EXPORT uint32_t -gbm_bo_get_format(struct gbm_bo *bo) -{ - return bo->format; -} - -/** Get the handle of the buffer object - * - * This is stored in the platform generic union gbm_bo_handle type. However - * the format of this handle is platform specific. - * - * \param bo The buffer object - * \return Returns the handle of the allocated buffer object - */ -GBM_EXPORT union gbm_bo_handle -gbm_bo_get_handle(struct gbm_bo *bo) -{ - return bo->handle; -} - -/** Write data into the buffer object - * - * If the buffer object was created with the GBM_BO_USE_WRITE flag, - * this function can used to write data into the buffer object. The - * data is copied directly into the object and it's the responsiblity - * of the caller to make sure the data represents valid pixel data, - * according to the width, height, stride and format of the buffer object. - * - * \param bo The buffer object - * \param buf The data to write - * \param count The number of bytes to write - * \return Returns -1 on error, 0 otherwise - */ -GBM_EXPORT int -gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) -{ - return bo->gbm->bo_write(bo, buf, count); -} - -/** Get the gbm device used to create the buffer object - * - * \param bo The buffer object - * \return Returns the gbm device with which the buffer object was created - */ -GBM_EXPORT struct gbm_device * -gbm_bo_get_device(struct gbm_bo *bo) -{ - return bo->gbm; -} - -/** Set the user data associated with a buffer object - * - * \param bo The buffer object - * \param data The data to associate to the buffer object - * \param destroy_user_data A callback (which may be %NULL) that will be - * called prior to the buffer destruction - */ -GBM_EXPORT void -gbm_bo_set_user_data(struct gbm_bo *bo, void *data, - void (*destroy_user_data)(struct gbm_bo *, void *)) -{ - bo->user_data = data; - bo->destroy_user_data = destroy_user_data; -} - -/** Get the user data associated with a buffer object - * - * \param bo The buffer object - * \return Returns the user data associated with the buffer object or %NULL - * if no data was associated with it - * - * \sa gbm_bo_set_user_data() - */ -GBM_EXPORT void * -gbm_bo_get_user_data(struct gbm_bo *bo) -{ - return bo->user_data; -} - -/** - * Destroys the given buffer object and frees all resources associated with - * it. - * - * \param bo The buffer object - */ -GBM_EXPORT void -gbm_bo_destroy(struct gbm_bo *bo) -{ - if (bo->destroy_user_data) - bo->destroy_user_data(bo, bo->user_data); - - bo->gbm->bo_destroy(bo); -} - -/** - * Allocate a buffer object for the given dimensions - * - * \param gbm The gbm device returned from gbm_create_device() - * \param width The width for the buffer - * \param height The height for the buffer - * \param format The format to use for the buffer - * \param usage The union of the usage flags for this buffer - * - * \return A newly allocated buffer that should be freed with gbm_bo_destroy() - * when no longer needed. If an error occurs during allocation %NULL will be - * returned. - * - * \sa enum gbm_bo_format for the list of formats - * \sa enum gbm_bo_flags for the list of usage flags - */ -GBM_EXPORT struct gbm_bo * -gbm_bo_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) -{ - printf("gbm_bo_create w: %d h: %d format %d usage %x\n", - width, height, format, usage); - - if (width == 0 || height == 0) - return NULL; - - if (usage & GBM_BO_USE_CURSOR_64X64 && - (width != 64 || height != 64)) - return NULL; - - return gbm->bo_create(gbm, width, height, format, usage); -} - -/** - * Create a gbm buffer object from an foreign object - * - * This function imports a foreign object and creates a new gbm bo for it. - * This enabled using the foreign object with a display API such as KMS. - * Currently two types of foreign objects are supported, indicated by the type - * argument: - * - * GBM_BO_IMPORT_WL_BUFFER - * GBM_BO_IMPORT_EGL_IMAGE - * - * The the gbm bo shares the underlying pixels but its life-time is - * independent of the foreign object. - * - * \param gbm The gbm device returned from gbm_create_device() - * \param gbm The type of object we're importing - * \param gbm Pointer to the external object - * \param usage The union of the usage flags for this buffer - * - * \return A newly allocated buffer object that should be freed with - * gbm_bo_destroy() when no longer needed. - * - * \sa enum gbm_bo_flags for the list of usage flags - */ -GBM_EXPORT struct gbm_bo * -gbm_bo_import(struct gbm_device *gbm, - uint32_t type, void *buffer, uint32_t usage) -{ - return gbm->bo_import(gbm, type, buffer, usage); -} - -/** - * Allocate a surface object - * - * \param gbm The gbm device returned from gbm_create_device() - * \param width The width for the surface - * \param height The height for the surface - * \param format The format to use for the surface - * - * \return A newly allocated surface that should be freed with - * gbm_surface_destroy() when no longer needed. If an error occurs - * during allocation %NULL will be returned. - * - * \sa enum gbm_bo_format for the list of formats - */ -GBM_EXPORT struct gbm_surface * -gbm_surface_create(struct gbm_device *gbm, - uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) -{ - return gbm->surface_create(gbm, width, height, format, flags); -} - -/** - * Destroys the given surface and frees all resources associated with - * it. - * - * All buffers locked with gbm_surface_lock_front_buffer() should be - * released prior to calling this function. - * - * \param surf The surface - */ -GBM_EXPORT void -gbm_surface_destroy(struct gbm_surface *surf) -{ - surf->gbm->surface_destroy(surf); -} - -/** - * Lock the surface's current front buffer - * - * Lock rendering to the surface's current front buffer until it is - * released with gbm_surface_release_buffer(). - * - * This function must be called exactly once after calling - * eglSwapBuffers. Calling it before any eglSwapBuffer has happened - * on the surface or two or more times after eglSwapBuffers is an - * error. A new bo representing the new front buffer is returned. On - * multiple invocations, all the returned bos must be released in - * order to release the actual surface buffer. - * - * \param surf The surface - * - * \return A buffer object that should be released with - * gbm_surface_release_buffer() when no longer needed. The implementation - * is free to reuse buffers released with gbm_surface_release_buffer() so - * this bo should not be destroyed using gbm_bo_destroy(). If an error - * occurs this function returns %NULL. - */ -GBM_EXPORT struct gbm_bo * -gbm_surface_lock_front_buffer(struct gbm_surface *surf) -{ - return surf->gbm->surface_lock_front_buffer(surf); -} - -/** - * Release a locked buffer obtained with gbm_surface_lock_front_buffer() - * - * Returns the underlying buffer to the gbm surface. Releasing a bo - * will typically make gbm_surface_has_free_buffer() return 1 and thus - * allow rendering the next frame, but not always. The implementation - * may choose to destroy the bo immediately or reuse it, in which case - * the user data associated with it is unchanged. - * - * \param surf The surface - * \param bo The buffer object - */ -GBM_EXPORT void -gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) -{ - surf->gbm->surface_release_buffer(surf, bo); -} - -/** - * Return whether or not a surface has free (non-locked) buffers - * - * Before starting a new frame, the surface must have a buffer - * available for rendering. Initially, a gbm surface will have a free - * buffer, but after one of more buffers have been locked (\sa - * gbm_surface_lock_front_buffer()), the application must check for a - * free buffer before rendering. - * - * If a surface doesn't have a free buffer, the application must - * return a buffer to the surface using gbm_surface_release_buffer() - * and after that, the application can query for free buffers again. - * - * \param surf The surface - * \return 1 if the surface has free buffers, 0 otherwise - */ -GBM_EXPORT int -gbm_surface_has_free_buffers(struct gbm_surface *surf) -{ - return surf->gbm->surface_has_free_buffers(surf); -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/drivers/common/meta.c.bak b/contrib/sdk/sources/Mesa/src/mesa/drivers/common/meta.c.bak deleted file mode 100644 index dee0b73bc9..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/drivers/common/meta.c.bak +++ /dev/null @@ -1,4289 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * Meta operations. Some GL operations can be expressed in terms of - * other GL operations. For example, glBlitFramebuffer() can be done - * with texture mapping and glClear() can be done with polygon rendering. - * - * \author Brian Paul - */ - - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/imports.h" -#include "main/arbprogram.h" -#include "main/arrayobj.h" -#include "main/blend.h" -#include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/colortab.h" -#include "main/condrender.h" -#include "main/depth.h" -#include "main/enable.h" -#include "main/fbobject.h" -#include "main/feedback.h" -#include "main/formats.h" -#include "main/glformats.h" -#include "main/image.h" -#include "main/macros.h" -#include "main/matrix.h" -#include "main/mipmap.h" -#include "main/pixel.h" -#include "main/pbo.h" -#include "main/polygon.h" -#include "main/queryobj.h" -#include "main/readpix.h" -#include "main/scissor.h" -#include "main/shaderapi.h" -#include "main/shaderobj.h" -#include "main/state.h" -#include "main/stencil.h" -#include "main/texobj.h" -#include "main/texenv.h" -#include "main/texgetimage.h" -#include "main/teximage.h" -#include "main/texparam.h" -#include "main/texstate.h" -#include "main/transformfeedback.h" -#include "main/uniforms.h" -#include "main/varray.h" -#include "main/viewport.h" -#include "main/samplerobj.h" -#include "program/program.h" -#include "swrast/swrast.h" -#include "drivers/common/meta.h" -#include "main/enums.h" -#include "main/glformats.h" -#include "../glsl/ralloc.h" - -/** Return offset in bytes of the field within a vertex struct */ -#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD)) - -/** - * State which we may save/restore across meta ops. - * XXX this may be incomplete... - */ -struct save_state -{ - GLbitfield SavedState; /**< bitmask of MESA_META_* flags */ - - /** MESA_META_CLEAR (and others?) */ - struct gl_query_object *CurrentOcclusionObject; - - /** MESA_META_ALPHA_TEST */ - GLboolean AlphaEnabled; - GLenum AlphaFunc; - GLclampf AlphaRef; - - /** MESA_META_BLEND */ - GLbitfield BlendEnabled; - GLboolean ColorLogicOpEnabled; - - /** MESA_META_COLOR_MASK */ - GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; - - /** MESA_META_DEPTH_TEST */ - struct gl_depthbuffer_attrib Depth; - - /** MESA_META_FOG */ - GLboolean Fog; - - /** MESA_META_PIXEL_STORE */ - struct gl_pixelstore_attrib Pack, Unpack; - - /** MESA_META_PIXEL_TRANSFER */ - GLfloat RedBias, RedScale; - GLfloat GreenBias, GreenScale; - GLfloat BlueBias, BlueScale; - GLfloat AlphaBias, AlphaScale; - GLfloat DepthBias, DepthScale; - GLboolean MapColorFlag; - - /** MESA_META_RASTERIZATION */ - GLenum FrontPolygonMode, BackPolygonMode; - GLboolean PolygonOffset; - GLboolean PolygonSmooth; - GLboolean PolygonStipple; - GLboolean PolygonCull; - - /** MESA_META_SCISSOR */ - struct gl_scissor_attrib Scissor; - - /** MESA_META_SHADER */ - GLboolean VertexProgramEnabled; - struct gl_vertex_program *VertexProgram; - GLboolean FragmentProgramEnabled; - struct gl_fragment_program *FragmentProgram; - GLboolean ATIFragmentShaderEnabled; - struct gl_shader_program *VertexShader; - struct gl_shader_program *GeometryShader; - struct gl_shader_program *FragmentShader; - struct gl_shader_program *ActiveShader; - - /** MESA_META_STENCIL_TEST */ - struct gl_stencil_attrib Stencil; - - /** MESA_META_TRANSFORM */ - GLenum MatrixMode; - GLfloat ModelviewMatrix[16]; - GLfloat ProjectionMatrix[16]; - GLfloat TextureMatrix[16]; - - /** MESA_META_CLIP */ - GLbitfield ClipPlanesEnabled; - - /** MESA_META_TEXTURE */ - GLuint ActiveUnit; - GLuint ClientActiveUnit; - /** for unit[0] only */ - struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS]; - /** mask of TEXTURE_2D_BIT, etc */ - GLbitfield TexEnabled[MAX_TEXTURE_UNITS]; - GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS]; - GLuint EnvMode; /* unit[0] only */ - - /** MESA_META_VERTEX */ - struct gl_array_object *ArrayObj; - struct gl_buffer_object *ArrayBufferObj; - - /** MESA_META_VIEWPORT */ - GLint ViewportX, ViewportY, ViewportW, ViewportH; - GLclampd DepthNear, DepthFar; - - /** MESA_META_CLAMP_FRAGMENT_COLOR */ - GLenum ClampFragmentColor; - - /** MESA_META_CLAMP_VERTEX_COLOR */ - GLenum ClampVertexColor; - - /** MESA_META_CONDITIONAL_RENDER */ - struct gl_query_object *CondRenderQuery; - GLenum CondRenderMode; - - /** MESA_META_SELECT_FEEDBACK */ - GLenum RenderMode; - struct gl_selection Select; - struct gl_feedback Feedback; - - /** MESA_META_MULTISAMPLE */ - GLboolean MultisampleEnabled; - - /** MESA_META_FRAMEBUFFER_SRGB */ - GLboolean sRGBEnabled; - - /** Miscellaneous (always disabled) */ - GLboolean Lighting; - GLboolean RasterDiscard; - GLboolean TransformFeedbackNeedsResume; -}; - -/** - * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc. - * This is currently shared by all the meta ops. But we could create a - * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc. - */ -struct temp_texture -{ - GLuint TexObj; - GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */ - GLsizei MinSize; /**< Min texture size to allocate */ - GLsizei MaxSize; /**< Max possible texture size */ - GLboolean NPOT; /**< Non-power of two size OK? */ - GLsizei Width, Height; /**< Current texture size */ - GLenum IntFormat; - GLfloat Sright, Ttop; /**< right, top texcoords */ -}; - - -/** - * State for glBlitFramebufer() - */ -struct blit_state -{ - GLuint ArrayObj; - GLuint VBO; - GLuint DepthFP; - GLuint ShaderProg; - GLuint RectShaderProg; - struct temp_texture depthTex; -}; - - -/** - * State for glClear() - */ -struct clear_state -{ - GLuint ArrayObj; - GLuint VBO; - GLuint ShaderProg; - GLint ColorLocation; - - GLuint IntegerShaderProg; - GLint IntegerColorLocation; -}; - - -/** - * State for glCopyPixels() - */ -struct copypix_state -{ - GLuint ArrayObj; - GLuint VBO; -}; - - -/** - * State for glDrawPixels() - */ -struct drawpix_state -{ - GLuint ArrayObj; - - GLuint StencilFP; /**< Fragment program for drawing stencil images */ - GLuint DepthFP; /**< Fragment program for drawing depth images */ -}; - - -/** - * State for glBitmap() - */ -struct bitmap_state -{ - GLuint ArrayObj; - GLuint VBO; - struct temp_texture Tex; /**< separate texture from other meta ops */ -}; - -/** - * State for GLSL texture sampler which is used to generate fragment - * shader in _mesa_meta_generate_mipmap(). - */ -struct glsl_sampler { - const char *type; - const char *func; - const char *texcoords; - GLuint shader_prog; -}; - -/** - * State for _mesa_meta_generate_mipmap() - */ -struct gen_mipmap_state -{ - GLuint ArrayObj; - GLuint VBO; - GLuint FBO; - GLuint Sampler; - GLuint ShaderProg; - struct glsl_sampler sampler_1d; - struct glsl_sampler sampler_2d; - struct glsl_sampler sampler_3d; - struct glsl_sampler sampler_cubemap; - struct glsl_sampler sampler_1d_array; - struct glsl_sampler sampler_2d_array; -}; - -/** - * State for texture decompression - */ -struct decompress_state -{ - GLuint ArrayObj; - GLuint VBO, FBO, RBO, Sampler; - GLint Width, Height; -}; - -/** - * State for glDrawTex() - */ -struct drawtex_state -{ - GLuint ArrayObj; - GLuint VBO; -}; - -#define MAX_META_OPS_DEPTH 8 -/** - * All per-context meta state. - */ -struct gl_meta_state -{ - /** Stack of state saved during meta-ops */ - struct save_state Save[MAX_META_OPS_DEPTH]; - /** Save stack depth */ - GLuint SaveStackDepth; - - struct temp_texture TempTex; - - struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */ - struct clear_state Clear; /**< For _mesa_meta_Clear() */ - struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */ - struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */ - struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */ - struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */ - struct decompress_state Decompress; /**< For texture decompression */ - struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ -}; - -static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); -static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex); -static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear); -static void meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap); - -static GLuint -compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source) -{ - GLuint shader; - GLint ok, size; - GLchar *info; - - shader = _mesa_CreateShaderObjectARB(target); - _mesa_ShaderSource(shader, 1, &source, NULL); - _mesa_CompileShader(shader); - - _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok); - if (ok) - return shader; - - _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); - if (size == 0) { - _mesa_DeleteObjectARB(shader); - return 0; - } - - info = malloc(size); - if (!info) { - _mesa_DeleteObjectARB(shader); - return 0; - } - - _mesa_GetProgramInfoLog(shader, size, NULL, info); - _mesa_problem(ctx, - "meta program compile failed:\n%s\n" - "source:\n%s\n", - info, source); - - free(info); - _mesa_DeleteObjectARB(shader); - - return 0; -} - -static GLuint -link_program_with_debug(struct gl_context *ctx, GLuint program) -{ - GLint ok, size; - GLchar *info; - - _mesa_LinkProgram(program); - - _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok); - if (ok) - return program; - - _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size); - if (size == 0) - return 0; - - info = malloc(size); - if (!info) - return 0; - - _mesa_GetProgramInfoLog(program, size, NULL, info); - _mesa_problem(ctx, "meta program link failed:\n%s", info); - - free(info); - - return 0; -} - -/** - * Initialize meta-ops for a context. - * To be called once during context creation. - */ -void -_mesa_meta_init(struct gl_context *ctx) -{ - ASSERT(!ctx->Meta); - - ctx->Meta = CALLOC_STRUCT(gl_meta_state); -} - - -/** - * Free context meta-op state. - * To be called once during context destruction. - */ -void -_mesa_meta_free(struct gl_context *ctx) -{ - GET_CURRENT_CONTEXT(old_context); - _mesa_make_current(ctx, NULL, NULL); - meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); - meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); - meta_glsl_generate_mipmap_cleanup(ctx, &ctx->Meta->Mipmap); - cleanup_temp_texture(ctx, &ctx->Meta->TempTex); - if (old_context) - _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); - else - _mesa_make_current(NULL, NULL, NULL); - free(ctx->Meta); - ctx->Meta = NULL; -} - - -/** - * Enter meta state. This is like a light-weight version of glPushAttrib - * but it also resets most GL state back to default values. - * - * \param state bitmask of MESA_META_* flags indicating which attribute groups - * to save and reset to their defaults - */ -void -_mesa_meta_begin(struct gl_context *ctx, GLbitfield state) -{ - struct save_state *save; - - /* hope MAX_META_OPS_DEPTH is large enough */ - assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH); - - save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++]; - memset(save, 0, sizeof(*save)); - save->SavedState = state; - - /* Pausing transform feedback needs to be done early, or else we won't be - * able to change other state. - */ - save->TransformFeedbackNeedsResume = - _mesa_is_xfb_active_and_unpaused(ctx); - if (save->TransformFeedbackNeedsResume) - _mesa_PauseTransformFeedback(); - - /* After saving the current occlusion object, call EndQuery so that no - * occlusion querying will be active during the meta-operation. - */ - if (state & MESA_META_OCCLUSION_QUERY) { - save->CurrentOcclusionObject = ctx->Query.CurrentOcclusionObject; - if (save->CurrentOcclusionObject) - _mesa_EndQuery(save->CurrentOcclusionObject->Target); - } - - if (state & MESA_META_ALPHA_TEST) { - save->AlphaEnabled = ctx->Color.AlphaEnabled; - save->AlphaFunc = ctx->Color.AlphaFunc; - save->AlphaRef = ctx->Color.AlphaRef; - if (ctx->Color.AlphaEnabled) - _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE); - } - - if (state & MESA_META_BLEND) { - save->BlendEnabled = ctx->Color.BlendEnabled; - if (ctx->Color.BlendEnabled) { - if (ctx->Extensions.EXT_draw_buffers2) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE); - } - } - else { - _mesa_set_enable(ctx, GL_BLEND, GL_FALSE); - } - } - save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; - if (ctx->Color.ColorLogicOpEnabled) - _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); - } - - if (state & MESA_META_COLOR_MASK) { - memcpy(save->ColorMask, ctx->Color.ColorMask, - sizeof(ctx->Color.ColorMask)); - if (!ctx->Color.ColorMask[0][0] || - !ctx->Color.ColorMask[0][1] || - !ctx->Color.ColorMask[0][2] || - !ctx->Color.ColorMask[0][3]) - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - - if (state & MESA_META_DEPTH_TEST) { - save->Depth = ctx->Depth; /* struct copy */ - if (ctx->Depth.Test) - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); - } - - if ((state & MESA_META_FOG) - && ctx->API != API_OPENGL_CORE - && ctx->API != API_OPENGLES2) { - save->Fog = ctx->Fog.Enabled; - if (ctx->Fog.Enabled) - _mesa_set_enable(ctx, GL_FOG, GL_FALSE); - } - - if (state & MESA_META_PIXEL_STORE) { - save->Pack = ctx->Pack; - save->Unpack = ctx->Unpack; - ctx->Pack = ctx->DefaultPacking; - ctx->Unpack = ctx->DefaultPacking; - } - - if (state & MESA_META_PIXEL_TRANSFER) { - save->RedScale = ctx->Pixel.RedScale; - save->RedBias = ctx->Pixel.RedBias; - save->GreenScale = ctx->Pixel.GreenScale; - save->GreenBias = ctx->Pixel.GreenBias; - save->BlueScale = ctx->Pixel.BlueScale; - save->BlueBias = ctx->Pixel.BlueBias; - save->AlphaScale = ctx->Pixel.AlphaScale; - save->AlphaBias = ctx->Pixel.AlphaBias; - save->MapColorFlag = ctx->Pixel.MapColorFlag; - ctx->Pixel.RedScale = 1.0F; - ctx->Pixel.RedBias = 0.0F; - ctx->Pixel.GreenScale = 1.0F; - ctx->Pixel.GreenBias = 0.0F; - ctx->Pixel.BlueScale = 1.0F; - ctx->Pixel.BlueBias = 0.0F; - ctx->Pixel.AlphaScale = 1.0F; - ctx->Pixel.AlphaBias = 0.0F; - ctx->Pixel.MapColorFlag = GL_FALSE; - /* XXX more state */ - ctx->NewState |=_NEW_PIXEL; - } - - if (state & MESA_META_RASTERIZATION) { - save->FrontPolygonMode = ctx->Polygon.FrontMode; - save->BackPolygonMode = ctx->Polygon.BackMode; - save->PolygonOffset = ctx->Polygon.OffsetFill; - save->PolygonSmooth = ctx->Polygon.SmoothFlag; - save->PolygonStipple = ctx->Polygon.StippleFlag; - save->PolygonCull = ctx->Polygon.CullFlag; - _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); - _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE); - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE); - _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE); - } - _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE); - } - - if (state & MESA_META_SCISSOR) { - save->Scissor = ctx->Scissor; /* struct copy */ - _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE); - } - - if (state & MESA_META_SHADER) { - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_vertex_program) { - save->VertexProgramEnabled = ctx->VertexProgram.Enabled; - _mesa_reference_vertprog(ctx, &save->VertexProgram, - ctx->VertexProgram.Current); - _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE); - } - - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_fragment_program) { - save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled; - _mesa_reference_fragprog(ctx, &save->FragmentProgram, - ctx->FragmentProgram.Current); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); - } - - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ATI_fragment_shader) { - save->ATIFragmentShaderEnabled = ctx->ATIFragmentShader.Enabled; - _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, GL_FALSE); - } - - _mesa_reference_shader_program(ctx, &save->VertexShader, - ctx->Shader.CurrentVertexProgram); - _mesa_reference_shader_program(ctx, &save->GeometryShader, - ctx->Shader.CurrentGeometryProgram); - _mesa_reference_shader_program(ctx, &save->FragmentShader, - ctx->Shader.CurrentFragmentProgram); - _mesa_reference_shader_program(ctx, &save->ActiveShader, - ctx->Shader.ActiveProgram); - - _mesa_UseProgram(0); - } - - if (state & MESA_META_STENCIL_TEST) { - save->Stencil = ctx->Stencil; /* struct copy */ - if (ctx->Stencil.Enabled) - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE); - /* NOTE: other stencil state not reset */ - } - - if (state & MESA_META_TEXTURE) { - GLuint u, tgt; - - save->ActiveUnit = ctx->Texture.CurrentUnit; - save->ClientActiveUnit = ctx->Array.ActiveTexture; - save->EnvMode = ctx->Texture.Unit[0].EnvMode; - - /* Disable all texture units */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled; - save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled; - if (ctx->Texture.Unit[u].Enabled || - ctx->Texture.Unit[u].TexGenEnabled) { - _mesa_ActiveTexture(GL_TEXTURE0 + u); - _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE); - if (ctx->Extensions.ARB_texture_cube_map) - _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); - if (_mesa_is_gles(ctx) && - ctx->Extensions.OES_EGL_image_external) - _mesa_set_enable(ctx, GL_TEXTURE_EXTERNAL_OES, GL_FALSE); - - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE); - if (ctx->Extensions.NV_texture_rectangle) - _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); - } else { - _mesa_set_enable(ctx, GL_TEXTURE_GEN_STR_OES, GL_FALSE); - } - } - } - } - - /* save current texture objects for unit[0] only */ - for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { - _mesa_reference_texobj(&save->CurrentTexture[tgt], - ctx->Texture.Unit[0].CurrentTex[tgt]); - } - - /* set defaults for unit[0] */ - _mesa_ActiveTexture(GL_TEXTURE0); - _mesa_ClientActiveTexture(GL_TEXTURE0); - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } - } - - if (state & MESA_META_TRANSFORM) { - GLuint activeTexture = ctx->Texture.CurrentUnit; - memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m, - 16 * sizeof(GLfloat)); - memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m, - 16 * sizeof(GLfloat)); - memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m, - 16 * sizeof(GLfloat)); - save->MatrixMode = ctx->Transform.MatrixMode; - /* set 1:1 vertex:pixel coordinate transform */ - _mesa_ActiveTexture(GL_TEXTURE0); - _mesa_MatrixMode(GL_TEXTURE); - _mesa_LoadIdentity(); - _mesa_ActiveTexture(GL_TEXTURE0 + activeTexture); - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_LoadIdentity(); - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - - /* glOrtho with width = 0 or height = 0 generates GL_INVALID_VALUE. - * This can occur when there is no draw buffer. - */ - if (ctx->DrawBuffer->Width != 0 && ctx->DrawBuffer->Height != 0) - _mesa_Ortho(0.0, ctx->DrawBuffer->Width, - 0.0, ctx->DrawBuffer->Height, - -1.0, 1.0); - } - - if (state & MESA_META_CLIP) { - save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled; - if (ctx->Transform.ClipPlanesEnabled) { - GLuint i; - for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { - _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); - } - } - } - - if (state & MESA_META_VERTEX) { - /* save vertex array object state */ - _mesa_reference_array_object(ctx, &save->ArrayObj, - ctx->Array.ArrayObj); - _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, - ctx->Array.ArrayBufferObj); - /* set some default state? */ - } - - if (state & MESA_META_VIEWPORT) { - /* save viewport state */ - save->ViewportX = ctx->Viewport.X; - save->ViewportY = ctx->Viewport.Y; - save->ViewportW = ctx->Viewport.Width; - save->ViewportH = ctx->Viewport.Height; - /* set viewport to match window size */ - if (ctx->Viewport.X != 0 || - ctx->Viewport.Y != 0 || - ctx->Viewport.Width != ctx->DrawBuffer->Width || - ctx->Viewport.Height != ctx->DrawBuffer->Height) { - _mesa_set_viewport(ctx, 0, 0, - ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); - } - /* save depth range state */ - save->DepthNear = ctx->Viewport.Near; - save->DepthFar = ctx->Viewport.Far; - /* set depth range to default */ - _mesa_DepthRange(0.0, 1.0); - } - - if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { - save->ClampFragmentColor = ctx->Color.ClampFragmentColor; - - /* Generally in here we want to do clamping according to whether - * it's for the pixel path (ClampFragmentColor is GL_TRUE), - * regardless of the internal implementation of the metaops. - */ - if (ctx->Color.ClampFragmentColor != GL_TRUE && - ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); - } - - if (state & MESA_META_CLAMP_VERTEX_COLOR) { - save->ClampVertexColor = ctx->Light.ClampVertexColor; - - /* Generally in here we never want vertex color clamping -- - * result clamping is only dependent on fragment clamping. - */ - if (ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE); - } - - if (state & MESA_META_CONDITIONAL_RENDER) { - save->CondRenderQuery = ctx->Query.CondRenderQuery; - save->CondRenderMode = ctx->Query.CondRenderMode; - - if (ctx->Query.CondRenderQuery) - _mesa_EndConditionalRender(); - } - - if (state & MESA_META_SELECT_FEEDBACK) { - save->RenderMode = ctx->RenderMode; - if (ctx->RenderMode == GL_SELECT) { - save->Select = ctx->Select; /* struct copy */ - _mesa_RenderMode(GL_RENDER); - } else if (ctx->RenderMode == GL_FEEDBACK) { - save->Feedback = ctx->Feedback; /* struct copy */ - _mesa_RenderMode(GL_RENDER); - } - } - - if (state & MESA_META_MULTISAMPLE) { - save->MultisampleEnabled = ctx->Multisample.Enabled; - if (ctx->Multisample.Enabled) - _mesa_set_multisample(ctx, GL_FALSE); - } - - if (state & MESA_META_FRAMEBUFFER_SRGB) { - save->sRGBEnabled = ctx->Color.sRGBEnabled; - if (ctx->Color.sRGBEnabled) - _mesa_set_framebuffer_srgb(ctx, GL_FALSE); - } - - /* misc */ - { - save->Lighting = ctx->Light.Enabled; - if (ctx->Light.Enabled) - _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE); - save->RasterDiscard = ctx->RasterDiscard; - if (ctx->RasterDiscard) - _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE); - } -} - - -/** - * Leave meta state. This is like a light-weight version of glPopAttrib(). - */ -void -_mesa_meta_end(struct gl_context *ctx) -{ - struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1]; - const GLbitfield state = save->SavedState; - - /* After starting a new occlusion query, initialize the results to the - * values saved previously. The driver will then continue to increment - * these values. - */ - if (state & MESA_META_OCCLUSION_QUERY) { - if (save->CurrentOcclusionObject) { - _mesa_BeginQuery(save->CurrentOcclusionObject->Target, - save->CurrentOcclusionObject->Id); - ctx->Query.CurrentOcclusionObject->Result = save->CurrentOcclusionObject->Result; - } - } - - if (state & MESA_META_ALPHA_TEST) { - if (ctx->Color.AlphaEnabled != save->AlphaEnabled) - _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); - _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef); - } - - if (state & MESA_META_BLEND) { - if (ctx->Color.BlendEnabled != save->BlendEnabled) { - if (ctx->Extensions.EXT_draw_buffers2) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1); - } - } - else { - _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1)); - } - } - if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) - _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); - } - - if (state & MESA_META_COLOR_MASK) { - GLuint i; - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) { - if (i == 0) { - _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1], - save->ColorMask[i][2], save->ColorMask[i][3]); - } - else { - _mesa_ColorMaski(i, - save->ColorMask[i][0], - save->ColorMask[i][1], - save->ColorMask[i][2], - save->ColorMask[i][3]); - } - } - } - } - - if (state & MESA_META_DEPTH_TEST) { - if (ctx->Depth.Test != save->Depth.Test) - _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); - _mesa_DepthFunc(save->Depth.Func); - _mesa_DepthMask(save->Depth.Mask); - } - - if ((state & MESA_META_FOG) - && ctx->API != API_OPENGL_CORE - && ctx->API != API_OPENGLES2) { - _mesa_set_enable(ctx, GL_FOG, save->Fog); - } - - if (state & MESA_META_PIXEL_STORE) { - ctx->Pack = save->Pack; - ctx->Unpack = save->Unpack; - } - - if (state & MESA_META_PIXEL_TRANSFER) { - ctx->Pixel.RedScale = save->RedScale; - ctx->Pixel.RedBias = save->RedBias; - ctx->Pixel.GreenScale = save->GreenScale; - ctx->Pixel.GreenBias = save->GreenBias; - ctx->Pixel.BlueScale = save->BlueScale; - ctx->Pixel.BlueBias = save->BlueBias; - ctx->Pixel.AlphaScale = save->AlphaScale; - ctx->Pixel.AlphaBias = save->AlphaBias; - ctx->Pixel.MapColorFlag = save->MapColorFlag; - /* XXX more state */ - ctx->NewState |=_NEW_PIXEL; - } - - if (state & MESA_META_RASTERIZATION) { - /* Core context requires that front and back mode be the same. - */ - if (ctx->API == API_OPENGL_CORE) { - _mesa_PolygonMode(GL_FRONT_AND_BACK, save->FrontPolygonMode); - } else { - _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); - _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); - } - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); - _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); - } - _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); - _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); - } - - if (state & MESA_META_SCISSOR) { - _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); - _mesa_Scissor(save->Scissor.X, save->Scissor.Y, - save->Scissor.Width, save->Scissor.Height); - } - - if (state & MESA_META_SHADER) { - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_vertex_program) { - _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, - save->VertexProgramEnabled); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - save->VertexProgram); - _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL); - } - - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_fragment_program) { - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - save->FragmentProgramEnabled); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - save->FragmentProgram); - _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL); - } - - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ATI_fragment_shader) { - _mesa_set_enable(ctx, GL_FRAGMENT_SHADER_ATI, - save->ATIFragmentShaderEnabled); - } - - if (ctx->Extensions.ARB_vertex_shader) - _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); - - if (ctx->Extensions.ARB_geometry_shader4) - _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, - save->GeometryShader); - - if (ctx->Extensions.ARB_fragment_shader) - _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, - save->FragmentShader); - - _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, - save->ActiveShader); - - _mesa_reference_shader_program(ctx, &save->VertexShader, NULL); - _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL); - _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL); - _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL); - } - - if (state & MESA_META_STENCIL_TEST) { - const struct gl_stencil_attrib *stencil = &save->Stencil; - - _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); - _mesa_ClearStencil(stencil->Clear); - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_stencil_two_side) { - _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, - stencil->TestTwoSide); - _mesa_ActiveStencilFaceEXT(stencil->ActiveFace - ? GL_BACK : GL_FRONT); - } - /* front state */ - _mesa_StencilFuncSeparate(GL_FRONT, - stencil->Function[0], - stencil->Ref[0], - stencil->ValueMask[0]); - _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); - _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], - stencil->ZFailFunc[0], - stencil->ZPassFunc[0]); - /* back state */ - _mesa_StencilFuncSeparate(GL_BACK, - stencil->Function[1], - stencil->Ref[1], - stencil->ValueMask[1]); - _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); - _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], - stencil->ZFailFunc[1], - stencil->ZPassFunc[1]); - } - - if (state & MESA_META_TEXTURE) { - GLuint u, tgt; - - ASSERT(ctx->Texture.CurrentUnit == 0); - - /* restore texenv for unit[0] */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); - } - - /* restore texture objects for unit[0] only */ - for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { - if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt], - save->CurrentTexture[tgt]); - } - _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL); - } - - /* Restore fixed function texture enables, texgen */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u].Enabled != save->TexEnabled[u]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - ctx->Texture.Unit[u].Enabled = save->TexEnabled[u]; - } - - if (ctx->Texture.Unit[u].TexGenEnabled != save->TexGenEnabled[u]) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - ctx->Texture.Unit[u].TexGenEnabled = save->TexGenEnabled[u]; - } - } - } - - /* restore current unit state */ - _mesa_ActiveTexture(GL_TEXTURE0 + save->ActiveUnit); - _mesa_ClientActiveTexture(GL_TEXTURE0 + save->ClientActiveUnit); - } - - if (state & MESA_META_TRANSFORM) { - GLuint activeTexture = ctx->Texture.CurrentUnit; - _mesa_ActiveTexture(GL_TEXTURE0); - _mesa_MatrixMode(GL_TEXTURE); - _mesa_LoadMatrixf(save->TextureMatrix); - _mesa_ActiveTexture(GL_TEXTURE0 + activeTexture); - - _mesa_MatrixMode(GL_MODELVIEW); - _mesa_LoadMatrixf(save->ModelviewMatrix); - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadMatrixf(save->ProjectionMatrix); - - _mesa_MatrixMode(save->MatrixMode); - } - - if (state & MESA_META_CLIP) { - if (save->ClipPlanesEnabled) { - GLuint i; - for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { - if (save->ClipPlanesEnabled & (1 << i)) { - _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); - } - } - } - } - - if (state & MESA_META_VERTEX) { - /* restore vertex buffer object */ - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name); - _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL); - - /* restore vertex array object */ - _mesa_BindVertexArray(save->ArrayObj->Name); - _mesa_reference_array_object(ctx, &save->ArrayObj, NULL); - } - - if (state & MESA_META_VIEWPORT) { - if (save->ViewportX != ctx->Viewport.X || - save->ViewportY != ctx->Viewport.Y || - save->ViewportW != ctx->Viewport.Width || - save->ViewportH != ctx->Viewport.Height) { - _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, - save->ViewportW, save->ViewportH); - } - _mesa_DepthRange(save->DepthNear, save->DepthFar); - } - - if (state & MESA_META_CLAMP_FRAGMENT_COLOR && - ctx->Extensions.ARB_color_buffer_float) { - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); - } - - if (state & MESA_META_CLAMP_VERTEX_COLOR && - ctx->Extensions.ARB_color_buffer_float) { - _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); - } - - if (state & MESA_META_CONDITIONAL_RENDER) { - if (save->CondRenderQuery) - _mesa_BeginConditionalRender(save->CondRenderQuery->Id, - save->CondRenderMode); - } - - if (state & MESA_META_SELECT_FEEDBACK) { - if (save->RenderMode == GL_SELECT) { - _mesa_RenderMode(GL_SELECT); - ctx->Select = save->Select; - } else if (save->RenderMode == GL_FEEDBACK) { - _mesa_RenderMode(GL_FEEDBACK); - ctx->Feedback = save->Feedback; - } - } - - if (state & MESA_META_MULTISAMPLE) { - if (ctx->Multisample.Enabled != save->MultisampleEnabled) - _mesa_set_multisample(ctx, save->MultisampleEnabled); - } - - if (state & MESA_META_FRAMEBUFFER_SRGB) { - if (ctx->Color.sRGBEnabled != save->sRGBEnabled) - _mesa_set_framebuffer_srgb(ctx, save->sRGBEnabled); - } - - /* misc */ - if (save->Lighting) { - _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); - } - if (save->RasterDiscard) { - _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE); - } - if (save->TransformFeedbackNeedsResume) - _mesa_ResumeTransformFeedback(); - - ctx->Meta->SaveStackDepth--; -} - - -/** - * Determine whether Mesa is currently in a meta state. - */ -GLboolean -_mesa_meta_in_progress(struct gl_context *ctx) -{ - return ctx->Meta->SaveStackDepth != 0; -} - - -/** - * Convert Z from a normalized value in the range [0, 1] to an object-space - * Z coordinate in [-1, +1] so that drawing at the new Z position with the - * default/identity ortho projection results in the original Z value. - * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z - * value comes from the clear value or raster position. - */ -static INLINE GLfloat -invert_z(GLfloat normZ) -{ - GLfloat objZ = 1.0f - 2.0f * normZ; - return objZ; -} - - -/** - * One-time init for a temp_texture object. - * Choose tex target, compute max tex size, etc. - */ -static void -init_temp_texture(struct gl_context *ctx, struct temp_texture *tex) -{ - /* prefer texture rectangle */ - if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle) { - tex->Target = GL_TEXTURE_RECTANGLE; - tex->MaxSize = ctx->Const.MaxTextureRectSize; - tex->NPOT = GL_TRUE; - } - else { - /* use 2D texture, NPOT if possible */ - tex->Target = GL_TEXTURE_2D; - tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1); - tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two; - } - tex->MinSize = 16; /* 16 x 16 at least */ - assert(tex->MaxSize > 0); - - _mesa_GenTextures(1, &tex->TexObj); -} - -static void -cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) -{ - if (!tex->TexObj) - return; - _mesa_DeleteTextures(1, &tex->TexObj); - tex->TexObj = 0; -} - - -/** - * Return pointer to temp_texture info for non-bitmap ops. - * This does some one-time init if needed. - */ -static struct temp_texture * -get_temp_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->TempTex; - - if (!tex->TexObj) { - init_temp_texture(ctx, tex); - } - - return tex; -} - - -/** - * Return pointer to temp_texture info for _mesa_meta_bitmap(). - * We use a separate texture for bitmaps to reduce texture - * allocation/deallocation. - */ -static struct temp_texture * -get_bitmap_temp_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->Bitmap.Tex; - - if (!tex->TexObj) { - init_temp_texture(ctx, tex); - } - - return tex; -} - -/** - * Return pointer to depth temp_texture. - * This does some one-time init if needed. - */ -static struct temp_texture * -get_temp_depth_texture(struct gl_context *ctx) -{ - struct temp_texture *tex = &ctx->Meta->Blit.depthTex; - - if (!tex->TexObj) { - init_temp_texture(ctx, tex); - } - - return tex; -} - -/** - * Compute the width/height of texture needed to draw an image of the - * given size. Return a flag indicating whether the current texture - * can be re-used (glTexSubImage2D) or if a new texture needs to be - * allocated (glTexImage2D). - * Also, compute s/t texcoords for drawing. - * - * \return GL_TRUE if new texture is needed, GL_FALSE otherwise - */ -static GLboolean -alloc_texture(struct temp_texture *tex, - GLsizei width, GLsizei height, GLenum intFormat) -{ - GLboolean newTex = GL_FALSE; - - ASSERT(width <= tex->MaxSize); - ASSERT(height <= tex->MaxSize); - - if (width > tex->Width || - height > tex->Height || - intFormat != tex->IntFormat) { - /* alloc new texture (larger or different format) */ - - if (tex->NPOT) { - /* use non-power of two size */ - tex->Width = MAX2(tex->MinSize, width); - tex->Height = MAX2(tex->MinSize, height); - } - else { - /* find power of two size */ - GLsizei w, h; - w = h = tex->MinSize; - while (w < width) - w *= 2; - while (h < height) - h *= 2; - tex->Width = w; - tex->Height = h; - } - - tex->IntFormat = intFormat; - - newTex = GL_TRUE; - } - - /* compute texcoords */ - if (tex->Target == GL_TEXTURE_RECTANGLE) { - tex->Sright = (GLfloat) width; - tex->Ttop = (GLfloat) height; - } - else { - tex->Sright = (GLfloat) width / tex->Width; - tex->Ttop = (GLfloat) height / tex->Height; - } - - return newTex; -} - - -/** - * Setup/load texture for glCopyPixels or glBlitFramebuffer. - */ -static void -setup_copypix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLboolean newTex, - GLint srcX, GLint srcY, - GLsizei width, GLsizei height, GLenum intFormat, - GLenum filter) -{ - _mesa_BindTexture(tex->Target, tex->TexObj); - _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter); - _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter); - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - /* copy framebuffer image to texture */ - if (newTex) { - /* create new tex image */ - if (tex->Width == width && tex->Height == height) { - /* create new tex with framebuffer data */ - _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat, - srcX, srcY, width, height, 0); - } - else { - /* create empty texture */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, - intFormat, GL_UNSIGNED_BYTE, NULL); - /* load image */ - _mesa_CopyTexSubImage2D(tex->Target, 0, - 0, 0, srcX, srcY, width, height); - } - } - else { - /* replace existing tex image */ - _mesa_CopyTexSubImage2D(tex->Target, 0, - 0, 0, srcX, srcY, width, height); - } -} - - -/** - * Setup/load texture for glDrawPixels. - */ -static void -setup_drawpix_texture(struct gl_context *ctx, - struct temp_texture *tex, - GLboolean newTex, - GLenum texIntFormat, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels) -{ - _mesa_BindTexture(tex->Target, tex->TexObj); - _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - /* copy pixel data to texture */ - if (newTex) { - /* create new tex image */ - if (tex->Width == width && tex->Height == height) { - /* create new tex and load image data */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, format, type, pixels); - } - else { - struct gl_buffer_object *save_unpack_obj = NULL; - - _mesa_reference_buffer_object(ctx, &save_unpack_obj, - ctx->Unpack.BufferObj); - _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); - /* create empty texture */ - _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, - tex->Width, tex->Height, 0, format, type, NULL); - if (save_unpack_obj != NULL) - _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, - save_unpack_obj->Name); - /* load image */ - _mesa_TexSubImage2D(tex->Target, 0, - 0, 0, width, height, format, type, pixels); - } - } - else { - /* replace existing tex image */ - _mesa_TexSubImage2D(tex->Target, 0, - 0, 0, width, height, format, type, pixels); - } -} - - - -/** - * One-time init for drawing depth pixels. - */ -static void -init_blit_depth_pixels(struct gl_context *ctx) -{ - static const char *program = - "!!ARBfp1.0\n" - "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" - "END \n"; - char program2[200]; - struct blit_state *blit = &ctx->Meta->Blit; - struct temp_texture *tex = get_temp_texture(ctx); - const char *texTarget; - - assert(blit->DepthFP == 0); - - /* replace %s with "RECT" or "2D" */ - assert(strlen(program) + 4 < sizeof(program2)); - if (tex->Target == GL_TEXTURE_RECTANGLE) - texTarget = "RECT"; - else - texTarget = "2D"; - _mesa_snprintf(program2, sizeof(program2), program, texTarget); - - _mesa_GenProgramsARB(1, &blit->DepthFP); - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program2), (const GLubyte *) program2); -} - -static void -setup_ff_blit_framebuffer(struct gl_context *ctx, - struct blit_state *blit) -{ - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - - if (blit->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &blit->ArrayObj); - _mesa_BindVertexArray(blit->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &blit->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - /* setup projection matrix */ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - -} - -static void -setup_glsl_blit_framebuffer(struct gl_context *ctx, - struct blit_state *blit, - GLenum target) -{ - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - const char *vs_source; - char *fs_source; - GLuint vs, fs; - void *mem_ctx; - GLuint ShaderProg; - GLboolean texture_2d = (target == GL_TEXTURE_2D); - - /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */ - assert(_mesa_is_desktop_gl(ctx) || texture_2d); - - /* Check if already initialized */ - if (blit->ArrayObj == 0) { - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &blit->ArrayObj); - _mesa_BindVertexArray(blit->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &blit->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(x)); - _mesa_VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(s)); - } - - /* Generate a relevant fragment shader program for the texture target */ - if ((target == GL_TEXTURE_2D && blit->ShaderProg != 0) || - (target == GL_TEXTURE_RECTANGLE && blit->RectShaderProg != 0)) { - return; - } - - mem_ctx = ralloc_context(NULL); - - if (ctx->Const.GLSLVersion < 130) { - vs_source = - "attribute vec2 position;\n" - "attribute vec2 textureCoords;\n" - "varying vec2 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n"; - - fs_source = ralloc_asprintf(mem_ctx, - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "varying vec2 texCoords;\n" - "void main()\n" - "{\n" - " gl_FragColor = %s(texSampler, texCoords);\n" - " gl_FragDepth = gl_FragColor.r;\n" - "}\n", - texture_2d ? "sampler2D" : "sampler2DRect", - texture_2d ? "texture2D" : "texture2DRect"); - } - else { - vs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "in vec2 position;\n" - "in vec2 textureCoords;\n" - "out vec2 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - fs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "in vec2 texCoords;\n" - "out vec4 out_color;\n" - "\n" - "void main()\n" - "{\n" - " out_color = %s(texSampler, texCoords);\n" - " gl_FragDepth = out_color.r;\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es", - texture_2d ? "sampler2D" : "sampler2DRect", - texture_2d ? "texture" : "texture2DRect"); - } - - vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); - fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); - - ShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(ShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(ShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(ShaderProg, 0, "position"); - _mesa_BindAttribLocation(ShaderProg, 1, "texcoords"); - _mesa_EnableVertexAttribArray(0); - _mesa_EnableVertexAttribArray(1); - link_program_with_debug(ctx, ShaderProg); - ralloc_free(mem_ctx); - if (texture_2d) - blit->ShaderProg = ShaderProg; - else - blit->RectShaderProg = ShaderProg; -} - -/** - * Try to do a glBlitFramebuffer using no-copy texturing. - * We can do this when the src renderbuffer is actually a texture. - * But if the src buffer == dst buffer we cannot do this. - * - * \return new buffer mask indicating the buffers left to blit using the - * normal path. - */ -static GLbitfield -blitframebuffer_texture(struct gl_context *ctx, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter, GLint flipX, - GLint flipY, GLboolean glsl_version) -{ - if (mask & GL_COLOR_BUFFER_BIT) { - const struct gl_framebuffer *drawFb = ctx->DrawBuffer; - const struct gl_framebuffer *readFb = ctx->ReadBuffer; - const struct gl_renderbuffer_attachment *drawAtt; - const struct gl_renderbuffer_attachment *readAtt = - &readFb->Attachment[readFb->_ColorReadBufferIndex]; - - if (readAtt && readAtt->Texture) { - struct blit_state *blit = &ctx->Meta->Blit; - const GLint dstX = MIN2(dstX0, dstX1); - const GLint dstY = MIN2(dstY0, dstY1); - const GLint dstW = abs(dstX1 - dstX0); - const GLint dstH = abs(dstY1 - dstY0); - const struct gl_texture_object *texObj = readAtt->Texture; - const GLuint srcLevel = readAtt->TextureLevel; - const GLint baseLevelSave = texObj->BaseLevel; - const GLint maxLevelSave = texObj->MaxLevel; - const GLenum target = texObj->Target; - GLuint sampler, samplerSave = - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; - int i; - - /* Iterate through all draw buffers */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; - if (idx == -1) - continue; - drawAtt = &drawFb->Attachment[idx]; - - if (drawAtt->Texture == readAtt->Texture) { - /* Can't use same texture as both the source and dest. We need - * to handle overlapping blits and besides, some hw may not - * support this. - */ - return mask; - } - } - - if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) { - /* Can't handle other texture types at this time */ - return mask; - } - - /* Choose between glsl version and fixed function version of - * BlitFramebuffer function. - */ - if (glsl_version) { - setup_glsl_blit_framebuffer(ctx, blit, target); - if (target == GL_TEXTURE_2D) - _mesa_UseProgram(blit->ShaderProg); - else - _mesa_UseProgram(blit->RectShaderProg); - } - else { - setup_ff_blit_framebuffer(ctx, &ctx->Meta->Blit); - } - - _mesa_BindVertexArray(blit->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - - _mesa_GenSamplers(1, &sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); - - /* - printf("Blit from texture!\n"); - printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt); - printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture); - */ - - /* Prepare src texture state */ - _mesa_BindTexture(target, texObj->Name); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter); - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); - } - _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - /* Always do our blits with no sRGB decode or encode. Note that - * GL_FRAMEBUFFER_SRGB has already been disabled by - * _mesa_meta_begin(). - */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } - - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - /* Prepare vertex data (the VBO was previously created and bound) */ - { - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - GLfloat s0, t0, s1, t1; - - if (target == GL_TEXTURE_2D) { - const struct gl_texture_image *texImage - = _mesa_select_tex_image(ctx, texObj, target, srcLevel); - s0 = srcX0 / (float) texImage->Width; - s1 = srcX1 / (float) texImage->Width; - t0 = srcY0 / (float) texImage->Height; - t1 = srcY1 / (float) texImage->Height; - } - else { - assert(target == GL_TEXTURE_RECTANGLE_ARB); - s0 = srcX0; - s1 = srcX1; - t0 = srcY0; - t1 = srcY1; - } - - /* setup vertex positions */ - verts[0].x = -1.0F * flipX; - verts[0].y = -1.0F * flipY; - verts[1].x = 1.0F * flipX; - verts[1].y = -1.0F * flipY; - verts[2].x = 1.0F * flipX; - verts[2].y = 1.0F * flipY; - verts[3].x = -1.0F * flipX; - verts[3].y = 1.0F * flipY; - - verts[0].s = s0; - verts[0].t = t0; - verts[1].s = s1; - verts[1].t = t0; - verts[2].s = s1; - verts[2].t = t1; - verts[3].s = s0; - verts[3].t = t1; - - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - /* setup viewport */ - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - _mesa_DepthMask(GL_FALSE); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - /* Restore texture object state, the texture binding will - * be restored by _mesa_meta_end(). - */ - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); - } - - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); - _mesa_DeleteSamplers(1, &sampler); - - /* Done with color buffer */ - mask &= ~GL_COLOR_BUFFER_BIT; - } - } - - return mask; -} - - -/** - * Meta implementation of ctx->Driver.BlitFramebuffer() in terms - * of texture mapping and polygon rendering. - */ -void -_mesa_meta_BlitFramebuffer(struct gl_context *ctx, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - struct blit_state *blit = &ctx->Meta->Blit; - struct temp_texture *tex = get_temp_texture(ctx); - struct temp_texture *depthTex = get_temp_depth_texture(ctx); - const GLsizei maxTexSize = tex->MaxSize; - const GLint srcX = MIN2(srcX0, srcX1); - const GLint srcY = MIN2(srcY0, srcY1); - const GLint srcW = abs(srcX1 - srcX0); - const GLint srcH = abs(srcY1 - srcY0); - const GLint dstX = MIN2(dstX0, dstX1); - const GLint dstY = MIN2(dstY0, dstY1); - const GLint dstW = abs(dstX1 - dstX0); - const GLint dstH = abs(dstY1 - dstY0); - const GLint srcFlipX = (srcX1 - srcX0) / srcW; - const GLint srcFlipY = (srcY1 - srcY0) / srcH; - const GLint dstFlipX = (dstX1 - dstX0) / dstW; - const GLint dstFlipY = (dstY1 - dstY0) / dstH; - const GLint flipX = srcFlipX * dstFlipX; - const GLint flipY = srcFlipY * dstFlipY; - - struct vertex { - GLfloat x, y, s, t; - }; - struct vertex verts[4]; - GLboolean newTex; - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader && - (ctx->API != API_OPENGLES); - - /* In addition to falling back if the blit size is larger than the maximum - * texture size, fallback if the source is multisampled. This fallback can - * be removed once Mesa gets support ARB_texture_multisample. - */ - if (srcW > maxTexSize || srcH > maxTexSize - || ctx->ReadBuffer->Visual.samples > 0) { - /* XXX avoid this fallback */ - _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, filter); - return; - } - - /* only scissor effects blit so save/clear all other relevant state */ - _mesa_meta_begin(ctx, ~MESA_META_SCISSOR); - - /* Try faster, direct texture approach first */ - mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, filter, - dstFlipX, dstFlipY, use_glsl_version); - if (mask == 0x0) { - _mesa_meta_end(ctx); - return; - } - - /* Choose between glsl version and fixed function version of - * BlitFramebuffer function. - */ - if (use_glsl_version) { - setup_glsl_blit_framebuffer(ctx, blit, tex->Target); - if (tex->Target == GL_TEXTURE_2D) - _mesa_UseProgram(blit->ShaderProg); - else - _mesa_UseProgram(blit->RectShaderProg); - } - else { - setup_ff_blit_framebuffer(ctx, blit); - } - - _mesa_BindVertexArray(blit->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, blit->VBO); - - /* Continue with "normal" approach which involves copying the src rect - * into a temporary texture and is "blitted" by drawing a textured quad. - */ - { - /* setup vertex positions */ - verts[0].x = -1.0F * flipX; - verts[0].y = -1.0F * flipY; - verts[1].x = 1.0F * flipX; - verts[1].y = -1.0F * flipY; - verts[2].x = 1.0F * flipX; - verts[2].y = 1.0F * flipY; - verts[3].x = -1.0F * flipX; - verts[3].y = 1.0F * flipY; - - } - - /* glEnable() in gles2 and gles3 doesn't allow GL_TEXTURE_{1D, 2D, etc.} - * tokens. - */ - if (_mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES) - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - if (mask & GL_COLOR_BUFFER_BIT) { - const struct gl_framebuffer *readFb = ctx->ReadBuffer; - const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; - const GLenum rb_base_format = - _mesa_base_tex_format(ctx, colorReadRb->InternalFormat); - - /* Using the exact source rectangle to create the texture does incorrect - * linear filtering along the edges. So, allocate the texture extended along - * edges by one pixel in x, y directions. - */ - newTex = alloc_texture(tex, srcW + 2, srcH + 2, rb_base_format); - setup_copypix_texture(ctx, tex, newTex, - srcX - 1, srcY - 1, srcW + 2, srcH + 2, - rb_base_format, filter); - /* texcoords (after texture allocation!) */ - { - verts[0].s = 1.0F; - verts[0].t = 1.0F; - verts[1].s = tex->Sright - 1.0F; - verts[1].t = 1.0F; - verts[2].s = tex->Sright - 1.0F; - verts[2].t = tex->Ttop - 1.0F; - verts[3].s = 1.0F; - verts[3].t = tex->Ttop - 1.0F; - - /* upload new vertex data */ - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); - _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); - _mesa_DepthMask(GL_FALSE); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - mask &= ~GL_COLOR_BUFFER_BIT; - } - - if ((mask & GL_DEPTH_BUFFER_BIT) && - _mesa_is_desktop_gl(ctx) && - ctx->Extensions.ARB_depth_texture && - ctx->Extensions.ARB_fragment_program) { - - GLuint *tmp = malloc(srcW * srcH * sizeof(GLuint)); - - if (tmp) { - - newTex = alloc_texture(depthTex, srcW, srcH, GL_DEPTH_COMPONENT); - _mesa_ReadPixels(srcX, srcY, srcW, srcH, GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, tmp); - setup_drawpix_texture(ctx, depthTex, newTex, GL_DEPTH_COMPONENT, - srcW, srcH, GL_DEPTH_COMPONENT, - GL_UNSIGNED_INT, tmp); - - /* texcoords (after texture allocation!) */ - { - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].s = depthTex->Sright; - verts[1].t = 0.0F; - verts[2].s = depthTex->Sright; - verts[2].t = depthTex->Ttop; - verts[3].s = 0.0F; - verts[3].t = depthTex->Ttop; - - /* upload new vertex data */ - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - if (!blit->DepthFP) - init_blit_depth_pixels(ctx); - - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - - _mesa_set_viewport(ctx, dstX, dstY, dstW, dstH); - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - mask &= ~GL_DEPTH_BUFFER_BIT; - - free(tmp); - } - } - - if (mask & GL_STENCIL_BUFFER_BIT) { - /* XXX can't easily do stencil */ - } - - if (_mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES) - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - _mesa_meta_end(ctx); - - if (mask) { - _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, filter); - } -} - -static void -meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) -{ - if (blit->ArrayObj) { - _mesa_DeleteVertexArrays(1, &blit->ArrayObj); - blit->ArrayObj = 0; - _mesa_DeleteBuffers(1, &blit->VBO); - blit->VBO = 0; - } - if (blit->DepthFP) { - _mesa_DeleteProgramsARB(1, &blit->DepthFP); - blit->DepthFP = 0; - } - - _mesa_DeleteObjectARB(blit->ShaderProg); - blit->ShaderProg = 0; - _mesa_DeleteObjectARB(blit->RectShaderProg); - blit->RectShaderProg = 0; - - _mesa_DeleteTextures(1, &blit->depthTex.TexObj); - blit->depthTex.TexObj = 0; -} - - -/** - * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. - */ -void -_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - struct clear_state *clear = &ctx->Meta->Clear; - struct vertex { - GLfloat x, y, z, r, g, b, a; - }; - struct vertex verts[4]; - /* save all state but scissor, pixel pack/unpack */ - GLbitfield metaSave = (MESA_META_ALL - - MESA_META_SCISSOR - - MESA_META_PIXEL_STORE - - MESA_META_CONDITIONAL_RENDER - - MESA_META_FRAMEBUFFER_SRGB); - const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; - - if (buffers & BUFFER_BITS_COLOR) { - /* if clearing color buffers, don't save/restore colormask */ - metaSave -= MESA_META_COLOR_MASK; - } - - _mesa_meta_begin(ctx, metaSave); - - if (clear->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &clear->ArrayObj); - _mesa_BindVertexArray(clear->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &clear->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_COLOR_ARRAY); - } - else { - _mesa_BindVertexArray(clear->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - } - - /* GL_COLOR_BUFFER_BIT */ - if (buffers & BUFFER_BITS_COLOR) { - /* leave colormask, glDrawBuffer state as-is */ - - /* Clears never have the color clamped. */ - if (ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); - } - else { - ASSERT(metaSave & MESA_META_COLOR_MASK); - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - } - - /* GL_DEPTH_BUFFER_BIT */ - if (buffers & BUFFER_BIT_DEPTH) { - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - } - else { - assert(!ctx->Depth.Test); - } - - /* GL_STENCIL_BUFFER_BIT */ - if (buffers & BUFFER_BIT_STENCIL) { - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); - _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, - GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, - ctx->Stencil.Clear & stencilMax, - ctx->Stencil.WriteMask[0]); - } - else { - assert(!ctx->Stencil.Enabled); - } - - /* vertex positions/colors */ - { - const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; - const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin; - const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; - const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax; - const GLfloat z = invert_z(ctx->Depth.Clear); - GLuint i; - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - - /* vertex colors */ - for (i = 0; i < 4; i++) { - verts[i].r = ctx->Color.ClearColor.f[0]; - verts[i].g = ctx->Color.ClearColor.f[1]; - verts[i].b = ctx->Color.ClearColor.f[2]; - verts[i].a = ctx->Color.ClearColor.f[3]; - } - - /* upload new vertex data */ - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, - GL_DYNAMIC_DRAW_ARB); - } - - /* draw quad */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_meta_end(ctx); -} - -static void -meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) -{ - const char *vs_source = - "attribute vec4 position;\n" - "void main()\n" - "{\n" - " gl_Position = position;\n" - "}\n"; - const char *fs_source = - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform vec4 color;\n" - "void main()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - GLuint vs, fs; - bool has_integer_textures; - - if (clear->ArrayObj != 0) - return; - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &clear->ArrayObj); - _mesa_BindVertexArray(clear->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &clear->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); - _mesa_EnableVertexAttribArray(0); - - vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER); - _mesa_ShaderSource(vs, 1, &vs_source, NULL); - _mesa_CompileShader(vs); - - fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER); - _mesa_ShaderSource(fs, 1, &fs_source, NULL); - _mesa_CompileShader(fs); - - clear->ShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(clear->ShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(clear->ShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(clear->ShaderProg, 0, "position"); - _mesa_LinkProgram(clear->ShaderProg); - - clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, - "color"); - - has_integer_textures = _mesa_is_gles3(ctx) || - (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130); - - if (has_integer_textures) { - void *shader_source_mem_ctx = ralloc_context(NULL); - const char *vs_int_source = - ralloc_asprintf(shader_source_mem_ctx, - "#version %s\n" - "in vec4 position;\n" - "void main()\n" - "{\n" - " gl_Position = position;\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - const char *fs_int_source = - ralloc_asprintf(shader_source_mem_ctx, - "#version %s\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform ivec4 color;\n" - "out ivec4 out_color;\n" - "\n" - "void main()\n" - "{\n" - " out_color = color;\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - - vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source); - fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source); - ralloc_free(shader_source_mem_ctx); - - clear->IntegerShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(clear->IntegerShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(clear->IntegerShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position"); - - /* Note that user-defined out attributes get automatically assigned - * locations starting from 0, so we don't need to explicitly - * BindFragDataLocation to 0. - */ - - link_program_with_debug(ctx, clear->IntegerShaderProg); - - clear->IntegerColorLocation = - _mesa_GetUniformLocation(clear->IntegerShaderProg, "color"); - } -} - -static void -meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) -{ - if (clear->ArrayObj == 0) - return; - _mesa_DeleteVertexArrays(1, &clear->ArrayObj); - clear->ArrayObj = 0; - _mesa_DeleteBuffers(1, &clear->VBO); - clear->VBO = 0; - _mesa_DeleteObjectARB(clear->ShaderProg); - clear->ShaderProg = 0; - - if (clear->IntegerShaderProg) { - _mesa_DeleteObjectARB(clear->IntegerShaderProg); - clear->IntegerShaderProg = 0; - } -} - -/** - * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. - */ -void -_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - struct clear_state *clear = &ctx->Meta->Clear; - GLbitfield metaSave; - const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; - struct gl_framebuffer *fb = ctx->DrawBuffer; - const float x0 = ((float)fb->_Xmin / fb->Width) * 2.0f - 1.0f; - const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f; - const float x1 = ((float)fb->_Xmax / fb->Width) * 2.0f - 1.0f; - const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f; - const float z = -invert_z(ctx->Depth.Clear); - struct vertex { - GLfloat x, y, z; - } verts[4]; - - metaSave = (MESA_META_ALPHA_TEST | - MESA_META_BLEND | - MESA_META_DEPTH_TEST | - MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_STENCIL_TEST | - MESA_META_VERTEX | - MESA_META_VIEWPORT | - MESA_META_CLIP | - MESA_META_CLAMP_FRAGMENT_COLOR | - MESA_META_MULTISAMPLE | - MESA_META_OCCLUSION_QUERY); - - if (!(buffers & BUFFER_BITS_COLOR)) { - /* We'll use colormask to disable color writes. Otherwise, - * respect color mask - */ - metaSave |= MESA_META_COLOR_MASK; - } - - _mesa_meta_begin(ctx, metaSave); - - meta_glsl_clear_init(ctx, clear); - - if (fb->_IntegerColor) { - _mesa_UseProgram(clear->IntegerShaderProg); - _mesa_Uniform4iv(clear->IntegerColorLocation, 1, - ctx->Color.ClearColor.i); - } else { - _mesa_UseProgram(clear->ShaderProg); - _mesa_Uniform4fv(clear->ColorLocation, 1, - ctx->Color.ClearColor.f); - } - - _mesa_BindVertexArray(clear->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, clear->VBO); - - /* GL_COLOR_BUFFER_BIT */ - if (buffers & BUFFER_BITS_COLOR) { - /* leave colormask, glDrawBuffer state as-is */ - - /* Clears never have the color clamped. */ - if (ctx->Extensions.ARB_color_buffer_float) - _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); - } - else { - ASSERT(metaSave & MESA_META_COLOR_MASK); - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - } - - /* GL_DEPTH_BUFFER_BIT */ - if (buffers & BUFFER_BIT_DEPTH) { - _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); - _mesa_DepthFunc(GL_ALWAYS); - _mesa_DepthMask(GL_TRUE); - } - else { - assert(!ctx->Depth.Test); - } - - /* GL_STENCIL_BUFFER_BIT */ - if (buffers & BUFFER_BIT_STENCIL) { - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); - _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, - GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, - ctx->Stencil.Clear & stencilMax, - ctx->Stencil.WriteMask[0]); - } - else { - assert(!ctx->Stencil.Enabled); - } - - /* vertex positions */ - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - - /* upload new vertex data */ - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, - GL_DYNAMIC_DRAW_ARB); - printf("_mesa_BufferData\n"); - - /* draw quad */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - printf("_mesa_DrawArrays\n"); - - _mesa_meta_end(ctx); -LEAVE(); -} - -/** - * Meta implementation of ctx->Driver.CopyPixels() in terms - * of texture mapping and polygon rendering and GLSL shaders. - */ -void -_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, - GLsizei width, GLsizei height, - GLint dstX, GLint dstY, GLenum type) -{ - struct copypix_state *copypix = &ctx->Meta->CopyPix; - struct temp_texture *tex = get_temp_texture(ctx); - struct vertex { - GLfloat x, y, z, s, t; - }; - struct vertex verts[4]; - GLboolean newTex; - GLenum intFormat = GL_RGBA; - - if (type != GL_COLOR || - ctx->_ImageTransferState || - ctx->Fog.Enabled || - width > tex->MaxSize || - height > tex->MaxSize) { - /* XXX avoid this fallback */ - _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type); - return; - } - - /* Most GL state applies to glCopyPixels, but a there's a few things - * we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - if (copypix->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArrays(1, ©pix->ArrayObj); - _mesa_BindVertexArray(copypix->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, ©pix->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, copypix->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else { - _mesa_BindVertexArray(copypix->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, copypix->VBO); - } - - newTex = alloc_texture(tex, width, height, intFormat); - - /* vertex positions, texcoords (after texture allocation!) */ - { - const GLfloat dstX0 = (GLfloat) dstX; - const GLfloat dstY0 = (GLfloat) dstY; - const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX; - const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY; - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - - verts[0].x = dstX0; - verts[0].y = dstY0; - verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].x = dstX1; - verts[1].y = dstY0; - verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; - verts[2].x = dstX1; - verts[2].y = dstY1; - verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; - verts[3].x = dstX0; - verts[3].y = dstY1; - verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; - - /* upload new vertex data */ - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - /* Alloc/setup texture */ - setup_copypix_texture(ctx, tex, newTex, srcX, srcY, width, height, - GL_RGBA, GL_NEAREST); - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - /* draw textured quad */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - _mesa_meta_end(ctx); -} - - - -/** - * When the glDrawPixels() image size is greater than the max rectangle - * texture size we use this function to break the glDrawPixels() image - * into tiles which fit into the max texture size. - */ -static void -tiled_draw_pixels(struct gl_context *ctx, - GLint tileSize, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - struct gl_pixelstore_attrib tileUnpack = *unpack; - GLint i, j; - - if (tileUnpack.RowLength == 0) - tileUnpack.RowLength = width; - - for (i = 0; i < width; i += tileSize) { - const GLint tileWidth = MIN2(tileSize, width - i); - const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX); - - tileUnpack.SkipPixels = unpack->SkipPixels + i; - - for (j = 0; j < height; j += tileSize) { - const GLint tileHeight = MIN2(tileSize, height - j); - const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY); - - tileUnpack.SkipRows = unpack->SkipRows + j; - - _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight, - format, type, &tileUnpack, pixels); - } - } -} - - -/** - * One-time init for drawing stencil pixels. - */ -static void -init_draw_stencil_pixels(struct gl_context *ctx) -{ - /* This program is run eight times, once for each stencil bit. - * The stencil values to draw are found in an 8-bit alpha texture. - * We read the texture/stencil value and test if bit 'b' is set. - * If the bit is not set, use KIL to kill the fragment. - * Finally, we use the stencil test to update the stencil buffer. - * - * The basic algorithm for checking if a bit is set is: - * if (is_odd(value / (1 << bit))) - * result is one (or non-zero). - * else - * result is zero. - * The program parameter contains three values: - * parm.x = 255 / (1 << bit) - * parm.y = 0.5 - * parm.z = 0.0 - */ - static const char *program = - "!!ARBfp1.0\n" - "PARAM parm = program.local[0]; \n" - "TEMP t; \n" - "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */ - "# t = t * 255 / bit \n" - "MUL t.x, t.a, parm.x; \n" - "# t = (int) t \n" - "FRC t.y, t.x; \n" - "SUB t.x, t.x, t.y; \n" - "# t = t * 0.5 \n" - "MUL t.x, t.x, parm.y; \n" - "# t = fract(t.x) \n" - "FRC t.x, t.x; # if t.x != 0, then the bit is set \n" - "# t.x = (t.x == 0 ? 1 : 0) \n" - "SGE t.x, -t.x, parm.z; \n" - "KIL -t.x; \n" - "# for debug only \n" - "#MOV result.color, t.x; \n" - "END \n"; - char program2[1000]; - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = get_temp_texture(ctx); - const char *texTarget; - - assert(drawpix->StencilFP == 0); - - /* replace %s with "RECT" or "2D" */ - assert(strlen(program) + 4 < sizeof(program2)); - if (tex->Target == GL_TEXTURE_RECTANGLE) - texTarget = "RECT"; - else - texTarget = "2D"; - _mesa_snprintf(program2, sizeof(program2), program, texTarget); - - _mesa_GenProgramsARB(1, &drawpix->StencilFP); - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program2), (const GLubyte *) program2); -} - - -/** - * One-time init for drawing depth pixels. - */ -static void -init_draw_depth_pixels(struct gl_context *ctx) -{ - static const char *program = - "!!ARBfp1.0\n" - "PARAM color = program.local[0]; \n" - "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" - "MOV result.color, color; \n" - "END \n"; - char program2[200]; - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = get_temp_texture(ctx); - const char *texTarget; - - assert(drawpix->DepthFP == 0); - - /* replace %s with "RECT" or "2D" */ - assert(strlen(program) + 4 < sizeof(program2)); - if (tex->Target == GL_TEXTURE_RECTANGLE) - texTarget = "RECT"; - else - texTarget = "2D"; - _mesa_snprintf(program2, sizeof(program2), program, texTarget); - - _mesa_GenProgramsARB(1, &drawpix->DepthFP); - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); - _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, - strlen(program2), (const GLubyte *) program2); -} - - -/** - * Meta implementation of ctx->Driver.DrawPixels() in terms - * of texture mapping and polygon rendering. - */ -void -_mesa_meta_DrawPixels(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) -{ - struct drawpix_state *drawpix = &ctx->Meta->DrawPix; - struct temp_texture *tex = get_temp_texture(ctx); - const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; - const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; - struct vertex { - GLfloat x, y, z, s, t; - }; - struct vertex verts[4]; - GLenum texIntFormat; - GLboolean fallback, newTex; - GLbitfield metaExtraSave = 0x0; - GLuint vbo; - - /* - * Determine if we can do the glDrawPixels with texture mapping. - */ - fallback = GL_FALSE; - if (ctx->Fog.Enabled) { - fallback = GL_TRUE; - } - - if (_mesa_is_color_format(format)) { - /* use more compact format when possible */ - /* XXX disable special case for GL_LUMINANCE for now to work around - * apparent i965 driver bug (see bug #23670). - */ - if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA) - texIntFormat = format; - else - texIntFormat = GL_RGBA; - - /* If we're not supposed to clamp the resulting color, then just - * promote our texture to fully float. We could do better by - * just going for the matching set of channels, in floating - * point. - */ - if (ctx->Color.ClampFragmentColor != GL_TRUE && - ctx->Extensions.ARB_texture_float) - texIntFormat = GL_RGBA32F; - } - else if (_mesa_is_stencil_format(format)) { - if (ctx->Extensions.ARB_fragment_program && - ctx->Pixel.IndexShift == 0 && - ctx->Pixel.IndexOffset == 0 && - type == GL_UNSIGNED_BYTE) { - /* We'll store stencil as alpha. This only works for GLubyte - * image data because of how incoming values are mapped to alpha - * in [0,1]. - */ - texIntFormat = GL_ALPHA; - metaExtraSave = (MESA_META_COLOR_MASK | - MESA_META_DEPTH_TEST | - MESA_META_PIXEL_TRANSFER | - MESA_META_SHADER | - MESA_META_STENCIL_TEST); - } - else { - fallback = GL_TRUE; - } - } - else if (_mesa_is_depth_format(format)) { - if (ctx->Extensions.ARB_depth_texture && - ctx->Extensions.ARB_fragment_program) { - texIntFormat = GL_DEPTH_COMPONENT; - metaExtraSave = (MESA_META_SHADER); - } - else { - fallback = GL_TRUE; - } - } - else { - fallback = GL_TRUE; - } - - if (fallback) { - _swrast_DrawPixels(ctx, x, y, width, height, - format, type, unpack, pixels); - return; - } - - /* - * Check image size against max texture size, draw as tiles if needed. - */ - if (width > tex->MaxSize || height > tex->MaxSize) { - tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height, - format, type, unpack, pixels); - return; - } - - /* Most GL state applies to glDrawPixels (like blending, stencil, etc), - * but a there's a few things we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT | - metaExtraSave)); - - newTex = alloc_texture(tex, width, height, texIntFormat); - - /* vertex positions, texcoords (after texture allocation!) */ - { - const GLfloat x0 = (GLfloat) x; - const GLfloat y0 = (GLfloat) y; - const GLfloat x1 = x + width * ctx->Pixel.ZoomX; - const GLfloat y1 = y + height * ctx->Pixel.ZoomY; - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; - } - - if (drawpix->ArrayObj == 0) { - /* one-time setup: create vertex array object */ - _mesa_GenVertexArrays(1, &drawpix->ArrayObj); - } - _mesa_BindVertexArray(drawpix->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &vbo); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, vbo); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - verts, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - - /* set given unpack params */ - ctx->Unpack = *unpack; - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - if (_mesa_is_stencil_format(format)) { - /* Drawing stencil */ - GLint bit; - - if (!drawpix->StencilFP) - init_draw_stencil_pixels(ctx); - - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, - GL_ALPHA, type, pixels); - - _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); - - /* set all stencil bits to 0 */ - _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - _mesa_StencilFunc(GL_ALWAYS, 0, 255); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - /* set stencil bits to 1 where needed */ - _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); - - for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) { - const GLuint mask = 1 << bit; - if (mask & origStencilMask) { - _mesa_StencilFunc(GL_ALWAYS, mask, mask); - _mesa_StencilMask(mask); - - _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, - 255.0 / mask, 0.5, 0.0, 0.0); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - } - } - else if (_mesa_is_depth_format(format)) { - /* Drawing depth */ - if (!drawpix->DepthFP) - init_draw_depth_pixels(ctx); - - _mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); - _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); - - /* polygon color = current raster color */ - _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, - ctx->Current.RasterColor); - - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, - format, type, pixels); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - else { - /* Drawing RGBA */ - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, - format, type, pixels); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - _mesa_DeleteBuffers(1, &vbo); - - /* restore unpack params */ - ctx->Unpack = unpackSave; - - _mesa_meta_end(ctx); -} - -static GLboolean -alpha_test_raster_color(struct gl_context *ctx) -{ - GLfloat alpha = ctx->Current.RasterColor[ACOMP]; - GLfloat ref = ctx->Color.AlphaRef; - - switch (ctx->Color.AlphaFunc) { - case GL_NEVER: - return GL_FALSE; - case GL_LESS: - return alpha < ref; - case GL_EQUAL: - return alpha == ref; - case GL_LEQUAL: - return alpha <= ref; - case GL_GREATER: - return alpha > ref; - case GL_NOTEQUAL: - return alpha != ref; - case GL_GEQUAL: - return alpha >= ref; - case GL_ALWAYS: - return GL_TRUE; - default: - assert(0); - return GL_FALSE; - } -} - -/** - * Do glBitmap with a alpha texture quad. Use the alpha test to cull - * the 'off' bits. A bitmap cache as in the gallium/mesa state - * tracker would improve performance a lot. - */ -void -_mesa_meta_Bitmap(struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap1) -{ - struct bitmap_state *bitmap = &ctx->Meta->Bitmap; - struct temp_texture *tex = get_bitmap_temp_texture(ctx); - const GLenum texIntFormat = GL_ALPHA; - const struct gl_pixelstore_attrib unpackSave = *unpack; - GLubyte fg, bg; - struct vertex { - GLfloat x, y, z, s, t, r, g, b, a; - }; - struct vertex verts[4]; - GLboolean newTex; - GLubyte *bitmap8; - - /* - * Check if swrast fallback is needed. - */ - if (ctx->_ImageTransferState || - ctx->FragmentProgram._Enabled || - ctx->Fog.Enabled || - ctx->Texture._EnabledUnits || - width > tex->MaxSize || - height > tex->MaxSize) { - _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1); - return; - } - - if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx)) - return; - - /* Most GL state applies to glBitmap (like blending, stencil, etc), - * but a there's a few things we need to override: - */ - _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST | - MESA_META_PIXEL_STORE | - MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TEXTURE | - MESA_META_TRANSFORM | - MESA_META_CLIP | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - if (bitmap->ArrayObj == 0) { - /* one-time setup */ - - /* create vertex array object */ - _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj); - _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &bitmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, bitmap->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); - _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - _mesa_EnableClientState(GL_COLOR_ARRAY); - } - else { - _mesa_BindVertexArray(bitmap->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, bitmap->VBO); - } - - newTex = alloc_texture(tex, width, height, texIntFormat); - - /* vertex positions, texcoords, colors (after texture allocation!) */ - { - const GLfloat x0 = (GLfloat) x; - const GLfloat y0 = (GLfloat) y; - const GLfloat x1 = (GLfloat) (x + width); - const GLfloat y1 = (GLfloat) (y + height); - const GLfloat z = invert_z(ctx->Current.RasterPos[2]); - GLuint i; - - verts[0].x = x0; - verts[0].y = y0; - verts[0].z = z; - verts[0].s = 0.0F; - verts[0].t = 0.0F; - verts[1].x = x1; - verts[1].y = y0; - verts[1].z = z; - verts[1].s = tex->Sright; - verts[1].t = 0.0F; - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - verts[2].s = tex->Sright; - verts[2].t = tex->Ttop; - verts[3].x = x0; - verts[3].y = y1; - verts[3].z = z; - verts[3].s = 0.0F; - verts[3].t = tex->Ttop; - - for (i = 0; i < 4; i++) { - verts[i].r = ctx->Current.RasterColor[0]; - verts[i].g = ctx->Current.RasterColor[1]; - verts[i].b = ctx->Current.RasterColor[2]; - verts[i].a = ctx->Current.RasterColor[3]; - } - - /* upload new vertex data */ - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - /* choose different foreground/background alpha values */ - CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]); - bg = (fg > 127 ? 0 : 255); - - bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1); - if (!bitmap1) { - _mesa_meta_end(ctx); - return; - } - - bitmap8 = malloc(width * height); - if (bitmap8) { - memset(bitmap8, bg, width * height); - _mesa_expand_bitmap(width, height, &unpackSave, bitmap1, - bitmap8, width, fg); - - _mesa_set_enable(ctx, tex->Target, GL_TRUE); - - _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE); - _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg)); - - setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, - GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_set_enable(ctx, tex->Target, GL_FALSE); - - free(bitmap8); - } - - _mesa_unmap_pbo_source(ctx, &unpackSave); - - _mesa_meta_end(ctx); -} - - -/** - * Check if the call to _mesa_meta_GenerateMipmap() will require a - * software fallback. The fallback path will require that the texture - * images are mapped. - * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise - */ -GLboolean -_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - const GLuint fboSave = ctx->DrawBuffer->Name; - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct gl_texture_image *baseImage; - GLuint srcLevel; - GLenum status; - - /* check for fallbacks */ - if (target == GL_TEXTURE_3D || - target == GL_TEXTURE_1D_ARRAY || - target == GL_TEXTURE_2D_ARRAY) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() to %s target\n", - _mesa_lookup_enum_by_nr(target)); - return GL_TRUE; - } - - srcLevel = texObj->BaseLevel; - baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); - if (!baseImage) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() couldn't find base teximage\n"); - return GL_TRUE; - } - - if (_mesa_is_format_compressed(baseImage->TexFormat)) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() with %s format\n", - _mesa_get_format_name(baseImage->TexFormat)); - return GL_TRUE; - } - - if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && - !ctx->Extensions.EXT_texture_sRGB_decode) { - /* The texture format is sRGB but we can't turn off sRGB->linear - * texture sample conversion. So we won't be able to generate the - * right colors when rendering. Need to use a fallback. - */ - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() of sRGB texture without " - "sRGB decode\n"); - return GL_TRUE; - } - - /* - * Test that we can actually render in the texture's format. - */ - if (!mipmap->FBO) - _mesa_GenFramebuffers(1, &mipmap->FBO); - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } -#if 0 - /* other work is needed to enable 3D mipmap generation */ - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel, zoffset); - } -#endif - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, texObj->Name, srcLevel); - } - - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH, - "glGenerateMipmap() got incomplete FBO\n"); - return GL_TRUE; - } - - return GL_FALSE; -} - - -/** - * Compute the texture coordinates for the four vertices of a quad for - * drawing a 2D texture image or slice of a cube/3D texture. - * \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name - * \param slice slice of a 1D/2D array texture or 3D texture - * \param width width of the texture image - * \param height height of the texture image - * \param coords0/1/2/3 returns the computed texcoords - */ -static void -setup_texture_coords(GLenum faceTarget, - GLint slice, - GLint width, - GLint height, - GLint depth, - GLfloat coords0[3], - GLfloat coords1[3], - GLfloat coords2[3], - GLfloat coords3[3]) -{ - static const GLfloat st[4][2] = { - {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} - }; - GLuint i; - GLfloat r; - - switch (faceTarget) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - if (faceTarget == GL_TEXTURE_3D) { - assert(slice < depth); - assert(depth >= 1); - r = (slice + 0.5f) / depth; - } - else if (faceTarget == GL_TEXTURE_2D_ARRAY) - r = slice; - else - r = 0.0F; - coords0[0] = 0.0F; /* s */ - coords0[1] = 0.0F; /* t */ - coords0[2] = r; /* r */ - coords1[0] = 1.0F; - coords1[1] = 0.0F; - coords1[2] = r; - coords2[0] = 1.0F; - coords2[1] = 1.0F; - coords2[2] = r; - coords3[0] = 0.0F; - coords3[1] = 1.0F; - coords3[2] = r; - break; - case GL_TEXTURE_RECTANGLE_ARB: - coords0[0] = 0.0F; /* s */ - coords0[1] = 0.0F; /* t */ - coords0[2] = 0.0F; /* r */ - coords1[0] = width; - coords1[1] = 0.0F; - coords1[2] = 0.0F; - coords2[0] = width; - coords2[1] = height; - coords2[2] = 0.0F; - coords3[0] = 0.0F; - coords3[1] = height; - coords3[2] = 0.0F; - break; - case GL_TEXTURE_1D_ARRAY: - coords0[0] = 0.0F; /* s */ - coords0[1] = slice; /* t */ - coords0[2] = 0.0F; /* r */ - coords1[0] = 1.0f; - coords1[1] = slice; - coords1[2] = 0.0F; - coords2[0] = 1.0F; - coords2[1] = slice; - coords2[2] = 0.0F; - coords3[0] = 0.0F; - coords3[1] = slice; - coords3[2] = 0.0F; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - /* loop over quad verts */ - for (i = 0; i < 4; i++) { - /* Compute sc = +/-scale and tc = +/-scale. - * Not +/-1 to avoid cube face selection ambiguity near the edges, - * though that can still sometimes happen with this scale factor... - */ - const GLfloat scale = 0.9999f; - const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale; - const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale; - GLfloat *coord; - - switch (i) { - case 0: - coord = coords0; - break; - case 1: - coord = coords1; - break; - case 2: - coord = coords2; - break; - case 3: - coord = coords3; - break; - default: - assert(0); - } - - switch (faceTarget) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - coord[0] = 1.0f; - coord[1] = -tc; - coord[2] = -sc; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - coord[0] = -1.0f; - coord[1] = -tc; - coord[2] = sc; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - coord[0] = sc; - coord[1] = 1.0f; - coord[2] = tc; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - coord[0] = sc; - coord[1] = -1.0f; - coord[2] = -tc; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - coord[0] = sc; - coord[1] = -tc; - coord[2] = 1.0f; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - coord[0] = -sc; - coord[1] = -tc; - coord[2] = -1.0f; - break; - default: - assert(0); - } - } - break; - default: - assert(0 && "unexpected target in meta setup_texture_coords()"); - } -} - - -static void -setup_ff_generate_mipmap(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) -{ - struct vertex { - GLfloat x, y, tex[3]; - }; - - if (mipmap->ArrayObj == 0) { - /* one-time setup */ - /* create vertex array object */ - _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj); - _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &mipmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - /* setup projection matrix */ - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - _mesa_Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); -} - - -static struct glsl_sampler * -setup_texture_sampler(GLenum target, struct gen_mipmap_state *mipmap) -{ - switch(target) { - case GL_TEXTURE_1D: - mipmap->sampler_1d.type = "sampler1D"; - mipmap->sampler_1d.func = "texture1D"; - mipmap->sampler_1d.texcoords = "texCoords.x"; - return &mipmap->sampler_1d; - case GL_TEXTURE_2D: - mipmap->sampler_2d.type = "sampler2D"; - mipmap->sampler_2d.func = "texture2D"; - mipmap->sampler_2d.texcoords = "texCoords.xy"; - return &mipmap->sampler_2d; - case GL_TEXTURE_3D: - /* Code for mipmap generation with 3D textures is not used yet. - * It's a sw fallback. - */ - mipmap->sampler_3d.type = "sampler3D"; - mipmap->sampler_3d.func = "texture3D"; - mipmap->sampler_3d.texcoords = "texCoords"; - return &mipmap->sampler_3d; - case GL_TEXTURE_CUBE_MAP: - mipmap->sampler_cubemap.type = "samplerCube"; - mipmap->sampler_cubemap.func = "textureCube"; - mipmap->sampler_cubemap.texcoords = "texCoords"; - return &mipmap->sampler_cubemap; - case GL_TEXTURE_1D_ARRAY: - mipmap->sampler_1d_array.type = "sampler1DArray"; - mipmap->sampler_1d_array.func = "texture1DArray"; - mipmap->sampler_1d_array.texcoords = "texCoords.xy"; - return &mipmap->sampler_1d_array; - case GL_TEXTURE_2D_ARRAY: - mipmap->sampler_2d_array.type = "sampler2DArray"; - mipmap->sampler_2d_array.func = "texture2DArray"; - mipmap->sampler_2d_array.texcoords = "texCoords"; - return &mipmap->sampler_2d_array; - default: - _mesa_problem(NULL, "Unexpected texture target 0x%x in" - " setup_texture_sampler()\n", target); - return NULL; - } -} - - -static void -setup_glsl_generate_mipmap(struct gl_context *ctx, - struct gen_mipmap_state *mipmap, - GLenum target) -{ - struct vertex { - GLfloat x, y, tex[3]; - }; - struct glsl_sampler *sampler; - const char *vs_source; - char *fs_source; - GLuint vs, fs; - void *mem_ctx; - - /* Check if already initialized */ - if (mipmap->ArrayObj == 0) { - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &mipmap->ArrayObj); - _mesa_BindVertexArray(mipmap->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &mipmap->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); - - /* setup vertex arrays */ - _mesa_VertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(x)); - _mesa_VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, - sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableVertexAttribArray(0); - _mesa_EnableVertexAttribArray(1); - } - - /* Generate a fragment shader program appropriate for the texture target */ - sampler = setup_texture_sampler(target, mipmap); - assert(sampler != NULL); - if (sampler->shader_prog != 0) { - mipmap->ShaderProg = sampler->shader_prog; - return; - } - - mem_ctx = ralloc_context(NULL); - - if (ctx->API == API_OPENGLES2 || ctx->Const.GLSLVersion < 130) { - vs_source = - "attribute vec2 position;\n" - "attribute vec3 textureCoords;\n" - "varying vec3 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n"; - - fs_source = ralloc_asprintf(mem_ctx, - "#extension GL_EXT_texture_array : enable\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "varying vec3 texCoords;\n" - "void main()\n" - "{\n" - " gl_FragColor = %s(texSampler, %s);\n" - "}\n", - sampler->type, - sampler->func, sampler->texcoords); - } - else { - vs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "in vec2 position;\n" - "in vec3 textureCoords;\n" - "out vec3 texCoords;\n" - "void main()\n" - "{\n" - " texCoords = textureCoords;\n" - " gl_Position = vec4(position, 0.0, 1.0);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es"); - fs_source = ralloc_asprintf(mem_ctx, - "#version %s\n" - "#ifdef GL_ES\n" - "precision highp float;\n" - "#endif\n" - "uniform %s texSampler;\n" - "in vec3 texCoords;\n" - "out vec4 out_color;\n" - "\n" - "void main()\n" - "{\n" - " out_color = texture(texSampler, %s);\n" - "}\n", - _mesa_is_desktop_gl(ctx) ? "130" : "300 es", - sampler->type, - sampler->texcoords); - } - - vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); - fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); - - mipmap->ShaderProg = _mesa_CreateProgramObjectARB(); - _mesa_AttachShader(mipmap->ShaderProg, fs); - _mesa_DeleteObjectARB(fs); - _mesa_AttachShader(mipmap->ShaderProg, vs); - _mesa_DeleteObjectARB(vs); - _mesa_BindAttribLocation(mipmap->ShaderProg, 0, "position"); - _mesa_BindAttribLocation(mipmap->ShaderProg, 1, "texcoords"); - link_program_with_debug(ctx, mipmap->ShaderProg); - sampler->shader_prog = mipmap->ShaderProg; - ralloc_free(mem_ctx); -} - - -static void -meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) -{ - if (mipmap->ArrayObj == 0) - return; - _mesa_DeleteVertexArrays(1, &mipmap->ArrayObj); - mipmap->ArrayObj = 0; - _mesa_DeleteBuffers(1, &mipmap->VBO); - mipmap->VBO = 0; - - _mesa_DeleteObjectARB(mipmap->sampler_1d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_2d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_3d.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_cubemap.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_1d_array.shader_prog); - _mesa_DeleteObjectARB(mipmap->sampler_2d_array.shader_prog); - - mipmap->sampler_1d.shader_prog = 0; - mipmap->sampler_2d.shader_prog = 0; - mipmap->sampler_3d.shader_prog = 0; - mipmap->sampler_cubemap.shader_prog = 0; - mipmap->sampler_1d_array.shader_prog = 0; - mipmap->sampler_2d_array.shader_prog = 0; -} - - -/** - * Called via ctx->Driver.GenerateMipmap() - * Note: We don't yet support 3D textures, 1D/2D array textures or texture - * borders. - */ -void -_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj) -{ - struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; - struct vertex { - GLfloat x, y, tex[3]; - }; - struct vertex verts[4]; - const GLuint baseLevel = texObj->BaseLevel; - const GLuint maxLevel = texObj->MaxLevel; - const GLint maxLevelSave = texObj->MaxLevel; - const GLboolean genMipmapSave = texObj->GenerateMipmap; - const GLuint fboSave = ctx->DrawBuffer->Name; - const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit; - const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader && - (ctx->API != API_OPENGLES); - GLenum faceTarget; - GLuint dstLevel; - const GLint slice = 0; - GLuint samplerSave; - - if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { - _mesa_generate_mipmap(ctx, target, texObj); - return; - } - - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { - faceTarget = target; - target = GL_TEXTURE_CUBE_MAP; - } - else { - faceTarget = target; - } - - _mesa_meta_begin(ctx, MESA_META_ALL); - - /* Choose between glsl version and fixed function version of - * GenerateMipmap function. - */ - if (use_glsl_version) { - setup_glsl_generate_mipmap(ctx, mipmap, target); - _mesa_UseProgram(mipmap->ShaderProg); - } - else { - setup_ff_generate_mipmap(ctx, mipmap); - _mesa_set_enable(ctx, target, GL_TRUE); - } - - _mesa_BindVertexArray(mipmap->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, mipmap->VBO); - - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; - - if (currentTexUnitSave != 0) - _mesa_BindTexture(target, texObj->Name); - - if (!mipmap->FBO) { - _mesa_GenFramebuffers(1, &mipmap->FBO); - } - - if (!mipmap->Sampler) { - _mesa_GenSamplers(1, &mipmap->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - - _mesa_SamplerParameteri(mipmap->Sampler, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* We don't want to encode or decode sRGB values; treat them as linear. - * This is not technically correct for GLES3 but we don't get any API - * error at the moment. - */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } - - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); - } - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO); - - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); - else - assert(!genMipmapSave); - - /* Setup texture coordinates */ - setup_texture_coords(faceTarget, - slice, - 0, 0, 1, /* width, height never used here */ - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* setup vertex positions */ - verts[0].x = -1.0F; - verts[0].y = -1.0F; - verts[1].x = 1.0F; - verts[1].y = -1.0F; - verts[2].x = 1.0F; - verts[2].y = 1.0F; - verts[3].x = -1.0F; - verts[3].y = 1.0F; - - /* upload vertex data */ - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - verts, GL_DYNAMIC_DRAW_ARB); - - /* texture is already locked, unlock now */ - _mesa_unlock_texture(ctx, texObj); - - for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { - const struct gl_texture_image *srcImage; - const GLuint srcLevel = dstLevel - 1; - GLsizei srcWidth, srcHeight, srcDepth; - GLsizei dstWidth, dstHeight, dstDepth; - GLenum status; - - srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); - assert(srcImage->Border == 0); - - /* src size */ - srcWidth = srcImage->Width; - srcHeight = srcImage->Height; - srcDepth = srcImage->Depth; - - /* new dst size */ - dstWidth = MAX2(1, srcWidth / 2); - dstHeight = MAX2(1, srcHeight / 2); - dstDepth = MAX2(1, srcDepth / 2); - - if (dstWidth == srcImage->Width && - dstHeight == srcImage->Height && - dstDepth == srcImage->Depth) { - /* all done */ - break; - } - - /* Allocate storage for the destination mipmap image(s) */ - - /* Set MaxLevel large enough to hold the new level when we allocate it */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); - - if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, - dstWidth, dstHeight, dstDepth, - srcImage->Border, - srcImage->InternalFormat, - srcImage->TexFormat)) { - /* All done. We either ran out of memory or we would go beyond the - * last valid level of an immutable texture if we continued. - */ - break; - } - - /* limit minification to src level */ - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); - - /* Set to draw into the current dstLevel */ - if (target == GL_TEXTURE_1D) { - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel); - } - else if (target == GL_TEXTURE_3D) { - GLint zoffset = 0; /* XXX unfinished */ - _mesa_FramebufferTexture3D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - target, - texObj->Name, - dstLevel, zoffset); - } - else { - /* 2D / cube */ - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - faceTarget, - texObj->Name, - dstLevel); - } - - _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - /* sanity check */ - status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_problem(ctx, "Unexpected incomplete framebuffer in " - "_mesa_meta_GenerateMipmap()"); - break; - } - - assert(dstWidth == ctx->DrawBuffer->Width); - assert(dstHeight == ctx->DrawBuffer->Height); - - /* setup viewport */ - _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight); - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - _mesa_lock_texture(ctx, texObj); /* relock */ - - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); - - _mesa_meta_end(ctx); - - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); - if (genMipmapSave) - _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); - - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboSave); -} - - -/** - * Determine the GL data type to use for the temporary image read with - * ReadPixels() and passed to Tex[Sub]Image(). - */ -static GLenum -get_temp_image_type(struct gl_context *ctx, gl_format format) -{ - GLenum baseFormat; - - baseFormat = _mesa_get_format_base_format(format); - - switch (baseFormat) { - case GL_RGBA: - case GL_RGB: - case GL_RG: - case GL_RED: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - if (ctx->DrawBuffer->Visual.redBits <= 8) { - return GL_UNSIGNED_BYTE; - } else if (ctx->DrawBuffer->Visual.redBits <= 16) { - return GL_UNSIGNED_SHORT; - } else { - GLenum datatype = _mesa_get_format_datatype(format); - if (datatype == GL_INT || datatype == GL_UNSIGNED_INT) - return datatype; - return GL_FLOAT; - } - case GL_DEPTH_COMPONENT: { - GLenum datatype = _mesa_get_format_datatype(format); - if (datatype == GL_FLOAT) - return GL_FLOAT; - else - return GL_UNSIGNED_INT; - } - case GL_DEPTH_STENCIL: { - GLenum datatype = _mesa_get_format_datatype(format); - if (datatype == GL_FLOAT) - return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; - else - return GL_UNSIGNED_INT_24_8; - } - default: - _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()", - baseFormat); - return 0; - } -} - - -/** - * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. - * Have to be careful with locking and meta state for pixel transfer. - */ -void -_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height) -{ - struct gl_texture_object *texObj = texImage->TexObject; - GLenum format, type; - GLint bpp; - void *buf; - - /* Choose format/type for temporary image buffer */ - format = _mesa_get_format_base_format(texImage->TexFormat); - if (format == GL_LUMINANCE || - format == GL_LUMINANCE_ALPHA || - format == GL_INTENSITY) { - /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the - * temp image buffer because glReadPixels will do L=R+G+B which is - * not what we want (should be L=R). - */ - format = GL_RGBA; - } - - type = get_temp_image_type(ctx, texImage->TexFormat); - if (_mesa_is_format_integer_color(texImage->TexFormat)) { - format = _mesa_base_format_to_integer_format(format); - } - bpp = _mesa_bytes_per_pixel(format, type); - if (bpp <= 0) { - _mesa_problem(ctx, "Bad bpp in _mesa_meta_CopyTexSubImage()"); - return; - } - - /* - * Alloc image buffer (XXX could use a PBO) - */ - buf = malloc(width * height * bpp); - if (!buf) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); - return; - } - - _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ - - /* - * Read image from framebuffer (disable pixel transfer ops) - */ - _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER); - ctx->Driver.ReadPixels(ctx, x, y, width, height, - format, type, &ctx->Pack, buf); - _mesa_meta_end(ctx); - - _mesa_update_state(ctx); /* to update pixel transfer state */ - - /* - * Store texture data (with pixel transfer ops) - */ - _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); - - if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { - assert(yoffset == 0); - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, zoffset, 0, width, 1, 1, - format, type, buf, &ctx->Unpack); - } else { - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, width, height, 1, - format, type, buf, &ctx->Unpack); - } - - _mesa_meta_end(ctx); - - _mesa_lock_texture(ctx, texObj); /* re-lock */ - - free(buf); -} - - -/** - * Decompress a texture image by drawing a quad with the compressed - * texture and reading the pixels out of the color buffer. - * \param slice which slice of a 3D texture or layer of a 1D/2D texture - * \param destFormat format, ala glReadPixels - * \param destType type, ala glReadPixels - * \param dest destination buffer - * \param destRowLength dest image rowLength (ala GL_PACK_ROW_LENGTH) - */ -static void -decompress_texture_image(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice, - GLenum destFormat, GLenum destType, - GLvoid *dest) -{ - struct decompress_state *decompress = &ctx->Meta->Decompress; - struct gl_texture_object *texObj = texImage->TexObject; - const GLint width = texImage->Width; - const GLint height = texImage->Height; - const GLint depth = texImage->Height; - const GLenum target = texObj->Target; - GLenum faceTarget; - struct vertex { - GLfloat x, y, tex[3]; - }; - struct vertex verts[4]; - GLuint fboDrawSave, fboReadSave; - GLuint rbSave; - GLuint samplerSave; - - if (slice > 0) { - assert(target == GL_TEXTURE_3D || - target == GL_TEXTURE_2D_ARRAY); - } - - if (target == GL_TEXTURE_CUBE_MAP) { - faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; - } - else { - faceTarget = target; - } - - /* save fbo bindings (not saved by _mesa_meta_begin()) */ - fboDrawSave = ctx->DrawBuffer->Name; - fboReadSave = ctx->ReadBuffer->Name; - rbSave = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0; - - _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_PIXEL_STORE); - - samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? - ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; - - /* Create/bind FBO/renderbuffer */ - if (decompress->FBO == 0) { - _mesa_GenFramebuffers(1, &decompress->FBO); - _mesa_GenRenderbuffers(1, &decompress->RBO); - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO); - _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO); - _mesa_FramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, - decompress->RBO); - } - else { - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO); - } - - /* alloc dest surface */ - if (width > decompress->Width || height > decompress->Height) { - _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO); - _mesa_RenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA, - width, height); - decompress->Width = width; - decompress->Height = height; - } - - /* setup VBO data */ - if (decompress->ArrayObj == 0) { - /* create vertex array object */ - _mesa_GenVertexArrays(1, &decompress->ArrayObj); - _mesa_BindVertexArray(decompress->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &decompress->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, decompress->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* setup vertex arrays */ - _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - else { - _mesa_BindVertexArray(decompress->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, decompress->VBO); - } - - if (!decompress->Sampler) { - _mesa_GenSamplers(1, &decompress->Sampler); - _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); - /* nearest filtering */ - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - /* No sRGB decode or encode.*/ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } - - } else { - _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); - } - - setup_texture_coords(faceTarget, slice, width, height, depth, - verts[0].tex, - verts[1].tex, - verts[2].tex, - verts[3].tex); - - /* setup vertex positions */ - verts[0].x = 0.0F; - verts[0].y = 0.0F; - verts[1].x = width; - verts[1].y = 0.0F; - verts[2].x = width; - verts[2].y = height; - verts[3].x = 0.0F; - verts[3].y = height; - - _mesa_MatrixMode(GL_PROJECTION); - _mesa_LoadIdentity(); - _mesa_Ortho(0.0, width, 0.0, height, -1.0, 1.0); - _mesa_set_viewport(ctx, 0, 0, width, height); - - /* upload new vertex data */ - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - - /* setup texture state */ - _mesa_BindTexture(target, texObj->Name); - _mesa_set_enable(ctx, target, GL_TRUE); - - { - /* save texture object state */ - const GLint baseLevelSave = texObj->BaseLevel; - const GLint maxLevelSave = texObj->MaxLevel; - - /* restrict sampling to the texture level of interest */ - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level); - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level); - } - - /* render quad w/ texture into renderbuffer */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - /* Restore texture object state, the texture binding will - * be restored by _mesa_meta_end(). - */ - if (target != GL_TEXTURE_RECTANGLE_ARB) { - _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); - } - - } - - /* read pixels from renderbuffer */ - { - GLenum baseTexFormat = texImage->_BaseFormat; - GLenum destBaseFormat = _mesa_base_tex_format(ctx, destFormat); - - /* The pixel transfer state will be set to default values at this point - * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively - * turned off (as required by glGetTexImage) but we need to handle some - * special cases. In particular, single-channel texture values are - * returned as red and two-channel texture values are returned as - * red/alpha. - */ - if ((baseTexFormat == GL_LUMINANCE || - baseTexFormat == GL_LUMINANCE_ALPHA || - baseTexFormat == GL_INTENSITY) || - /* If we're reading back an RGB(A) texture (using glGetTexImage) as - * luminance then we need to return L=tex(R). - */ - ((baseTexFormat == GL_RGBA || - baseTexFormat == GL_RGB || - baseTexFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA || - destBaseFormat == GL_LUMINANCE_INTEGER_EXT || - destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT))) { - /* Green and blue must be zero */ - _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f); - _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f); - } - - _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest); - } - - /* disable texture unit */ - _mesa_set_enable(ctx, target, GL_FALSE); - - _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); - - _mesa_meta_end(ctx); - - /* restore fbo bindings */ - if (fboDrawSave == fboReadSave) { - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, fboDrawSave); - } - else { - _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fboDrawSave); - _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fboReadSave); - } - _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, rbSave); -} - - -/** - * This is just a wrapper around _mesa_get_tex_image() and - * decompress_texture_image(). Meta functions should not be directly called - * from core Mesa. - */ -void -_mesa_meta_GetTexImage(struct gl_context *ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage) -{ - /* We can only use the decompress-with-blit method here if the texels are - * unsigned, normalized values. We could handle signed and unnormalized - * with floating point renderbuffers... - */ - if (_mesa_is_format_compressed(texImage->TexFormat) && - _mesa_get_format_datatype(texImage->TexFormat) - == GL_UNSIGNED_NORMALIZED) { - struct gl_texture_object *texObj = texImage->TexObject; - GLuint slice; - /* Need to unlock the texture here to prevent deadlock... */ - _mesa_unlock_texture(ctx, texObj); - for (slice = 0; slice < texImage->Depth; slice++) { - void *dst; - if (texImage->TexObject->Target == GL_TEXTURE_2D_ARRAY) { - /* Setup pixel packing. SkipPixels and SkipRows will be applied - * in the decompress_texture_image() function's call to - * glReadPixels but we need to compute the dest slice's address - * here (according to SkipImages and ImageHeight). - */ - struct gl_pixelstore_attrib packing = ctx->Pack; - packing.SkipPixels = 0; - packing.SkipRows = 0; - dst = _mesa_image_address3d(&packing, pixels, texImage->Width, - texImage->Height, format, type, - slice, 0, 0); - } - else { - dst = pixels; - } - decompress_texture_image(ctx, texImage, slice, format, type, dst); - } - /* ... and relock it */ - _mesa_lock_texture(ctx, texObj); - } - else { - _mesa_get_teximage(ctx, format, type, pixels, texImage); - } -} - - -/** - * Meta implementation of ctx->Driver.DrawTex() in terms - * of polygon rendering. - */ -void -_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, - GLfloat width, GLfloat height) -{ - struct drawtex_state *drawtex = &ctx->Meta->DrawTex; - struct vertex { - GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2]; - }; - struct vertex verts[4]; - GLuint i; - - _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | - MESA_META_SHADER | - MESA_META_TRANSFORM | - MESA_META_VERTEX | - MESA_META_VIEWPORT)); - - if (drawtex->ArrayObj == 0) { - /* one-time setup */ - GLint active_texture; - - /* create vertex array object */ - _mesa_GenVertexArrays(1, &drawtex->ArrayObj); - _mesa_BindVertexArray(drawtex->ArrayObj); - - /* create vertex array buffer */ - _mesa_GenBuffers(1, &drawtex->VBO); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO); - _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), - NULL, GL_DYNAMIC_DRAW_ARB); - - /* client active texture is not part of the array object */ - active_texture = ctx->Array.ActiveTexture; - - /* setup vertex arrays */ - _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); - _mesa_EnableClientState(GL_VERTEX_ARRAY); - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - _mesa_ClientActiveTexture(GL_TEXTURE0 + i); - _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i])); - _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); - } - - /* restore client active texture */ - _mesa_ClientActiveTexture(GL_TEXTURE0 + active_texture); - } - else { - _mesa_BindVertexArray(drawtex->ArrayObj); - _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, drawtex->VBO); - } - - /* vertex positions, texcoords */ - { - const GLfloat x1 = x + width; - const GLfloat y1 = y + height; - - z = CLAMP(z, 0.0f, 1.0f); - z = invert_z(z); - - verts[0].x = x; - verts[0].y = y; - verts[0].z = z; - - verts[1].x = x1; - verts[1].y = y; - verts[1].z = z; - - verts[2].x = x1; - verts[2].y = y1; - verts[2].z = z; - - verts[3].x = x; - verts[3].y = y1; - verts[3].z = z; - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - const struct gl_texture_object *texObj; - const struct gl_texture_image *texImage; - GLfloat s, t, s1, t1; - GLuint tw, th; - - if (!ctx->Texture.Unit[i]._ReallyEnabled) { - GLuint j; - for (j = 0; j < 4; j++) { - verts[j].st[i][0] = 0.0f; - verts[j].st[i][1] = 0.0f; - } - continue; - } - - texObj = ctx->Texture.Unit[i]._Current; - texImage = texObj->Image[0][texObj->BaseLevel]; - tw = texImage->Width2; - th = texImage->Height2; - - s = (GLfloat) texObj->CropRect[0] / tw; - t = (GLfloat) texObj->CropRect[1] / th; - s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw; - t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th; - - verts[0].st[i][0] = s; - verts[0].st[i][1] = t; - - verts[1].st[i][0] = s1; - verts[1].st[i][1] = t; - - verts[2].st[i][0] = s1; - verts[2].st[i][1] = t1; - - verts[3].st[i][0] = s; - verts[3].st[i][1] = t1; - } - - _mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); - } - - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - - _mesa_meta_end(ctx); -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/common/dri_util.c.bak b/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/common/dri_util.c.bak deleted file mode 100644 index 6fc2f3d97d..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/common/dri_util.c.bak +++ /dev/null @@ -1,632 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2002, 2004 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file dri_util.c - * DRI utility functions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - */ - - -#include -#include "dri_util.h" -#include "utils.h" -#include "xmlpool.h" -#include "../glsl/glsl_parser_extras.h" - -PUBLIC const char __dri2ConfigOptions[] = - DRI_CONF_BEGIN - DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1) - DRI_CONF_SECTION_END - DRI_CONF_END; - -static const uint __dri2NConfigOptions = 1; - -/*****************************************************************/ -/** \name Screen handling functions */ -/*****************************************************************/ -/*@{*/ - -static void -setupLoaderExtensions(__DRIscreen *psp, - const __DRIextension **extensions) -{ - int i; - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0) - psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i]; - if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0) - psp->dri2.image = (__DRIimageLookupExtension *) extensions[i]; - if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0) - psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i]; - } -} - -static __DRIscreen * -dri2CreateNewScreen(int scrn, int fd, - const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) -{ - static const __DRIextension *emptyExtensionList[] = { NULL }; - __DRIscreen *psp; - drmVersionPtr version; - - psp = calloc(1, sizeof(*psp)); - if (!psp) - return NULL; - - setupLoaderExtensions(psp, extensions); - - version = drmGetVersion(fd); - if (version) { - psp->drm_version.major = version->version_major; - psp->drm_version.minor = version->version_minor; - psp->drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - } - - psp->loaderPrivate = data; - - psp->extensions = emptyExtensionList; - psp->fd = fd; - psp->myNum = scrn; - - psp->api_mask = (1 << __DRI_API_OPENGL); - - *driver_configs = driDriverAPI.InitScreen(psp); - if (*driver_configs == NULL) { - free(psp); - return NULL; - } - - driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions, __dri2NConfigOptions); - driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2"); - - return psp; -} - -/** - * Destroy the per-screen private information. - * - * \internal - * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls - * drmClose(), and finally frees \p screenPrivate. - */ -static void driDestroyScreen(__DRIscreen *psp) -{ - if (psp) { - /* No interaction with the X-server is possible at this point. This - * routine is called after XCloseDisplay, so there is no protocol - * stream open to the X-server anymore. - */ - - _mesa_destroy_shader_compiler(); - - driDriverAPI.DestroyScreen(psp); - - driDestroyOptionCache(&psp->optionCache); - driDestroyOptionInfo(&psp->optionInfo); - - free(psp); - } -} - -static const __DRIextension **driGetExtensions(__DRIscreen *psp) -{ - return psp->extensions; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context handling functions */ -/*****************************************************************/ -/*@{*/ - -static __DRIcontext * -dri2CreateContextAttribs(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, - unsigned num_attribs, - const uint32_t *attribs, - unsigned *error, - void *data) -{ - __DRIcontext *context; - const struct gl_config *modes = (config != NULL) ? &config->modes : NULL; - void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; - gl_api mesa_api; - unsigned major_version = 1; - unsigned minor_version = 0; - uint32_t flags = 0; - - assert((num_attribs == 0) || (attribs != NULL)); - - if (!(screen->api_mask & (1 << api))) { - *error = __DRI_CTX_ERROR_BAD_API; - return NULL; - } - - switch (api) { - case __DRI_API_OPENGL: - mesa_api = API_OPENGL_COMPAT; - break; - case __DRI_API_GLES: - mesa_api = API_OPENGLES; - break; - case __DRI_API_GLES2: - case __DRI_API_GLES3: - mesa_api = API_OPENGLES2; - break; - case __DRI_API_OPENGL_CORE: - mesa_api = API_OPENGL_CORE; - break; - default: - *error = __DRI_CTX_ERROR_BAD_API; - return NULL; - } - - for (unsigned i = 0; i < num_attribs; i++) { - switch (attribs[i * 2]) { - case __DRI_CTX_ATTRIB_MAJOR_VERSION: - major_version = attribs[i * 2 + 1]; - break; - case __DRI_CTX_ATTRIB_MINOR_VERSION: - minor_version = attribs[i * 2 + 1]; - break; - case __DRI_CTX_ATTRIB_FLAGS: - flags = attribs[i * 2 + 1]; - break; - default: - /* We can't create a context that satisfies the requirements of an - * attribute that we don't understand. Return failure. - */ - assert(!"Should not get here."); - *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE; - return NULL; - } - } - - /* Mesa does not support the GL_ARB_compatibilty extension or the - * compatibility profile. This means that we treat a API_OPENGL_COMPAT 3.1 as - * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+. - */ - if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1) - mesa_api = API_OPENGL_CORE; - - if (mesa_api == API_OPENGL_COMPAT - && ((major_version > 3) - || (major_version == 3 && minor_version >= 2))) { - *error = __DRI_CTX_ERROR_BAD_API; - return NULL; - } - - /* The EGL_KHR_create_context spec says: - * - * "Flags are only defined for OpenGL context creation, and specifying - * a flags value other than zero for other types of contexts, - * including OpenGL ES contexts, will generate an error." - * - * The GLX_EXT_create_context_es2_profile specification doesn't say - * anything specific about this case. However, none of the known flags - * have any meaning in an ES context, so this seems safe. - */ - if (mesa_api != API_OPENGL_COMPAT - && mesa_api != API_OPENGL_CORE - && flags != 0) { - *error = __DRI_CTX_ERROR_BAD_FLAG; - return NULL; - } - - /* There are no forward-compatible contexts before OpenGL 3.0. The - * GLX_ARB_create_context spec says: - * - * "Forward-compatible contexts are defined only for OpenGL versions - * 3.0 and later." - * - * Forward-looking contexts are supported by silently converting the - * requested API to API_OPENGL_CORE. - * - * In Mesa, a debug context is the same as a regular context. - */ - if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) { - mesa_api = API_OPENGL_CORE; - } - - if ((flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) - != 0) { - *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; - return NULL; - } - - context = calloc(1, sizeof *context); - if (!context) { - *error = __DRI_CTX_ERROR_NO_MEMORY; - return NULL; - } - - context->loaderPrivate = data; - - context->driScreenPriv = screen; - context->driDrawablePriv = NULL; - context->driReadablePriv = NULL; - - if (!driDriverAPI.CreateContext(mesa_api, modes, context, - major_version, minor_version, - flags, error, shareCtx) ) { - free(context); - return NULL; - } - - *error = __DRI_CTX_ERROR_SUCCESS; - return context; -} - -static __DRIcontext * -dri2CreateNewContextForAPI(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - unsigned error; - - return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL, - &error, data); -} - -static __DRIcontext * -dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, - __DRIcontext *shared, void *data) -{ - return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL, - config, shared, data); -} - -/** - * Destroy the per-context private information. - * - * \internal - * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls - * drmDestroyContext(), and finally frees \p contextPrivate. - */ -static void -driDestroyContext(__DRIcontext *pcp) -{ - if (pcp) { - driDriverAPI.DestroyContext(pcp); - free(pcp); - } -} - -static int -driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) -{ - (void) dest; - (void) src; - (void) mask; - return GL_FALSE; -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context (un)binding functions */ -/*****************************************************************/ -/*@{*/ - -static void dri_get_drawable(__DRIdrawable *pdp); -static void dri_put_drawable(__DRIdrawable *pdp); - -/** - * This function takes both a read buffer and a draw buffer. This is needed - * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent - * function. - */ -static int driBindContext(__DRIcontext *pcp, - __DRIdrawable *pdp, - __DRIdrawable *prp) -{ - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driUnbindContext. - */ - - if (!pcp) - return GL_FALSE; - - /* Bind the drawable to the context */ - pcp->driDrawablePriv = pdp; - pcp->driReadablePriv = prp; - if (pdp) { - pdp->driContextPriv = pcp; - dri_get_drawable(pdp); - } - if (prp && pdp != prp) { - dri_get_drawable(prp); - } - - return driDriverAPI.MakeCurrent(pcp, pdp, prp); -} - -/** - * Unbind context. - * - * \param scrn the screen. - * \param gc context. - * - * \return \c GL_TRUE on success, or \c GL_FALSE on failure. - * - * \internal - * This function calls __DriverAPIRec::UnbindContext, and then decrements - * __DRIdrawableRec::refcount which must be non-zero for a successful - * return. - * - * While casting the opaque private pointers associated with the parameters - * into their respective real types it also assures they are not \c NULL. - */ -static int driUnbindContext(__DRIcontext *pcp) -{ - __DRIdrawable *pdp; - __DRIdrawable *prp; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driUnbindContext. - */ - - if (pcp == NULL) - return GL_FALSE; - - pdp = pcp->driDrawablePriv; - prp = pcp->driReadablePriv; - - /* already unbound */ - if (!pdp && !prp) - return GL_TRUE; - - driDriverAPI.UnbindContext(pcp); - - assert(pdp); - if (pdp->refcount == 0) { - /* ERROR!!! */ - return GL_FALSE; - } - - dri_put_drawable(pdp); - - if (prp != pdp) { - if (prp->refcount == 0) { - /* ERROR!!! */ - return GL_FALSE; - } - - dri_put_drawable(prp); - } - - /* XXX this is disabled so that if we call SwapBuffers on an unbound - * window we can determine the last context bound to the window and - * use that context's lock. (BrianP, 2-Dec-2000) - */ - pcp->driDrawablePriv = NULL; - pcp->driReadablePriv = NULL; - - return GL_TRUE; -} - -/*@}*/ - - -static void dri_get_drawable(__DRIdrawable *pdp) -{ - pdp->refcount++; -} - -static void dri_put_drawable(__DRIdrawable *pdp) -{ - if (pdp) { - pdp->refcount--; - if (pdp->refcount) - return; - - driDriverAPI.DestroyBuffer(pdp); - free(pdp); - } -} - -static __DRIdrawable * -dri2CreateNewDrawable(__DRIscreen *screen, - const __DRIconfig *config, - void *data) -{ - __DRIdrawable *pdraw; - - printf("%s: screen %p config %p, data %p\n", - __FUNCTION__, screen, config, data); - - pdraw = malloc(sizeof *pdraw); - if (!pdraw) - return NULL; - - pdraw->loaderPrivate = data; - - pdraw->driScreenPriv = screen; - pdraw->driContextPriv = NULL; - pdraw->refcount = 0; - pdraw->lastStamp = 0; - pdraw->w = 0; - pdraw->h = 0; - - dri_get_drawable(pdraw); - - if (!driDriverAPI.CreateBuffer(screen, pdraw, &config->modes, GL_FALSE)) { - free(pdraw); - return NULL; - } - - pdraw->dri2.stamp = pdraw->lastStamp + 1; - - return pdraw; -} - -static void -driDestroyDrawable(__DRIdrawable *pdp) -{ - dri_put_drawable(pdp); -} - -static __DRIbuffer * -dri2AllocateBuffer(__DRIscreen *screen, - unsigned int attachment, unsigned int format, - int width, int height) -{ - return driDriverAPI.AllocateBuffer(screen, attachment, format, - width, height); -} - -static void -dri2ReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) -{ - driDriverAPI.ReleaseBuffer(screen, buffer); -} - - -static int -dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val) -{ - if (!driCheckOption(&screen->optionCache, var, DRI_BOOL)) - return -1; - - *val = driQueryOptionb(&screen->optionCache, var); - - return 0; -} - -static int -dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val) -{ - if (!driCheckOption(&screen->optionCache, var, DRI_INT) && - !driCheckOption(&screen->optionCache, var, DRI_ENUM)) - return -1; - - *val = driQueryOptioni(&screen->optionCache, var); - - return 0; -} - -static int -dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val) -{ - if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT)) - return -1; - - *val = driQueryOptionf(&screen->optionCache, var); - - return 0; -} - -static unsigned int -dri2GetAPIMask(__DRIscreen *screen) -{ - return screen->api_mask; -} - - -/** Core interface */ -const __DRIcoreExtension driCoreExtension = { - .base = { __DRI_CORE, __DRI_CORE_VERSION }, - - .createNewScreen = NULL, - .destroyScreen = driDestroyScreen, - .getExtensions = driGetExtensions, - .getConfigAttrib = driGetConfigAttrib, - .indexConfigAttrib = driIndexConfigAttrib, - .createNewDrawable = NULL, - .destroyDrawable = driDestroyDrawable, - .swapBuffers = NULL, - .createNewContext = NULL, - .copyContext = driCopyContext, - .destroyContext = driDestroyContext, - .bindContext = driBindContext, - .unbindContext = driUnbindContext -}; - -/** DRI2 interface */ -const __DRIdri2Extension driDRI2Extension = { - .base = { __DRI_DRI2, 3 }, - - .createNewScreen = dri2CreateNewScreen, - .createNewDrawable = dri2CreateNewDrawable, - .createNewContext = dri2CreateNewContext, - .getAPIMask = dri2GetAPIMask, - .createNewContextForAPI = dri2CreateNewContextForAPI, - .allocateBuffer = dri2AllocateBuffer, - .releaseBuffer = dri2ReleaseBuffer, - .createContextAttribs = dri2CreateContextAttribs -}; - -const __DRI2configQueryExtension dri2ConfigQueryExtension = { - .base = { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION }, - - .configQueryb = dri2ConfigQueryb, - .configQueryi = dri2ConfigQueryi, - .configQueryf = dri2ConfigQueryf, -}; - -void -dri2InvalidateDrawable(__DRIdrawable *drawable) -{ - drawable->dri2.stamp++; -} - -/** - * Check that the gl_framebuffer associated with dPriv is the right size. - * Resize the gl_framebuffer if needed. - * It's expected that the dPriv->driverPrivate member points to a - * gl_framebuffer object. - */ -void -driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv) -{ - struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; - if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) { - ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h); - /* if the driver needs the hw lock for ResizeBuffers, the drawable - might have changed again by now */ - assert(fb->Width == dPriv->w); - assert(fb->Height == dPriv->h); - } -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_context.c.bak b/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_context.c.bak deleted file mode 100644 index e19f860e1d..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_context.c.bak +++ /dev/null @@ -1,920 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/extensions.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" -#include "main/imports.h" -#include "main/renderbuffer.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "drivers/common/driverfuncs.h" -#include "drivers/common/meta.h" - -#include "intel_chipset.h" -#include "intel_buffers.h" -#include "intel_tex.h" -#include "intel_batchbuffer.h" -#include "intel_pixel.h" -#include "intel_regions.h" -#include "intel_buffer_objects.h" -#include "intel_fbo.h" -#include "intel_bufmgr.h" -#include "intel_screen.h" -#include "intel_mipmap_tree.h" - -#include "utils.h" -#include "../glsl/ralloc.h" - -#ifndef INTEL_DEBUG -int INTEL_DEBUG = (0); -#endif - - -static const GLubyte * -intelGetString(struct gl_context * ctx, GLenum name) -{ - const struct brw_context *const brw = brw_context(ctx); - const char *chipset; - static char buffer[128]; - - switch (name) { - case GL_VENDOR: - return (GLubyte *) "Intel Open Source Technology Center"; - break; - - case GL_RENDERER: - switch (brw->intelScreen->deviceID) { -#undef CHIPSET -#define CHIPSET(id, symbol, str) case id: chipset = str; break; -#include "pci_ids/i965_pci_ids.h" - default: - chipset = "Unknown Intel Chipset"; - break; - } - - (void) driGetRendererString(buffer, chipset, 0); - return (GLubyte *) buffer; - - default: - return NULL; - } -} - -void -intel_resolve_for_dri2_flush(struct brw_context *brw, - __DRIdrawable *drawable) -{ - if (brw->gen < 6) { - /* MSAA and fast color clear are not supported, so don't waste time - * checking whether a resolve is needed. - */ - return; - } - - struct gl_framebuffer *fb = drawable->driverPrivate; - struct intel_renderbuffer *rb; - - /* Usually, only the back buffer will need to be downsampled. However, - * the front buffer will also need it if the user has rendered into it. - */ - static const gl_buffer_index buffers[2] = { - BUFFER_BACK_LEFT, - BUFFER_FRONT_LEFT, - }; - - for (int i = 0; i < 2; ++i) { - rb = intel_get_renderbuffer(fb, buffers[i]); - if (rb == NULL || rb->mt == NULL) - continue; - if (rb->mt->num_samples <= 1) - intel_miptree_resolve_color(brw, rb->mt); - else - intel_miptree_downsample(brw, rb->mt); - } -} - -static void -intel_flush_front(struct gl_context *ctx) -{ - struct brw_context *brw = brw_context(ctx); - __DRIcontext *driContext = brw->driContext; - __DRIdrawable *driDrawable = driContext->driDrawablePriv; - __DRIscreen *const screen = brw->intelScreen->driScrnPriv; - - if (brw->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) { - if (screen->dri2.loader->flushFrontBuffer != NULL && - driDrawable && - driDrawable->loaderPrivate) { - - /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT. - * - * This potentially resolves both front and back buffer. It - * is unnecessary to resolve the back, but harms nothing except - * performance. And no one cares about front-buffer render - * performance. - */ - intel_resolve_for_dri2_flush(brw, driDrawable); - - screen->dri2.loader->flushFrontBuffer(driDrawable, - driDrawable->loaderPrivate); - - /* We set the dirty bit in intel_prepare_render() if we're - * front buffer rendering once we get there. - */ - brw->front_buffer_dirty = false; - } - } -} - -static unsigned -intel_bits_per_pixel(const struct intel_renderbuffer *rb) -{ - return _mesa_get_format_bytes(intel_rb_format(rb)) * 8; -} - -static void -intel_query_dri2_buffers(struct brw_context *brw, - __DRIdrawable *drawable, - __DRIbuffer **buffers, - int *count); - -static void -intel_process_dri2_buffer(struct brw_context *brw, - __DRIdrawable *drawable, - __DRIbuffer *buffer, - struct intel_renderbuffer *rb, - const char *buffer_name); - -void -intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) -{ - struct gl_framebuffer *fb = drawable->driverPrivate; - struct intel_renderbuffer *rb; - struct brw_context *brw = context->driverPrivate; - __DRIbuffer *buffers = NULL; - int i, count; - const char *region_name; - - /* Set this up front, so that in case our buffers get invalidated - * while we're getting new buffers, we don't clobber the stamp and - * thus ignore the invalidate. */ - drawable->lastStamp = drawable->dri2.stamp; - - if (unlikely(INTEL_DEBUG & DEBUG_DRI)) - fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); - - intel_query_dri2_buffers(brw, drawable, &buffers, &count); - - if (buffers == NULL) - return; - - for (i = 0; i < count; i++) { - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); - region_name = "dri2 front buffer"; - break; - - case __DRI_BUFFER_FAKE_FRONT_LEFT: - rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); - region_name = "dri2 fake front buffer"; - break; - - case __DRI_BUFFER_BACK_LEFT: - rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); - region_name = "dri2 back buffer"; - break; - - case __DRI_BUFFER_DEPTH: - case __DRI_BUFFER_HIZ: - case __DRI_BUFFER_DEPTH_STENCIL: - case __DRI_BUFFER_STENCIL: - case __DRI_BUFFER_ACCUM: - default: - fprintf(stderr, - "unhandled buffer attach event, attachment type %d\n", - buffers[i].attachment); - return; - } - - intel_process_dri2_buffer(brw, drawable, &buffers[i], rb, region_name); - } - - driUpdateFramebufferSize(&brw->ctx, drawable); -} - -/** - * intel_prepare_render should be called anywhere that curent read/drawbuffer - * state is required. - */ -void -intel_prepare_render(struct brw_context *brw) -{ - __DRIcontext *driContext = brw->driContext; - __DRIdrawable *drawable; - - drawable = driContext->driDrawablePriv; - if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) { - if (drawable->lastStamp != drawable->dri2.stamp) - intel_update_renderbuffers(driContext, drawable); - driContext->dri2.draw_stamp = drawable->dri2.stamp; - } - - drawable = driContext->driReadablePriv; - if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) { - if (drawable->lastStamp != drawable->dri2.stamp) - intel_update_renderbuffers(driContext, drawable); - driContext->dri2.read_stamp = drawable->dri2.stamp; - } - - /* If we're currently rendering to the front buffer, the rendering - * that will happen next will probably dirty the front buffer. So - * mark it as dirty here. - */ - if (brw->is_front_buffer_rendering) - brw->front_buffer_dirty = true; - - /* Wait for the swapbuffers before the one we just emitted, so we - * don't get too many swaps outstanding for apps that are GPU-heavy - * but not CPU-heavy. - * - * We're using intelDRI2Flush (called from the loader before - * swapbuffer) and glFlush (for front buffer rendering) as the - * indicator that a frame is done and then throttle when we get - * here as we prepare to render the next frame. At this point for - * round trips for swap/copy and getting new buffers are done and - * we'll spend less time waiting on the GPU. - * - * Unfortunately, we don't have a handle to the batch containing - * the swap, and getting our hands on that doesn't seem worth it, - * so we just us the first batch we emitted after the last swap. - */ - if (brw->need_throttle && brw->first_post_swapbuffers_batch) { - if (!brw->disable_throttling) - drm_intel_bo_wait_rendering(brw->first_post_swapbuffers_batch); - drm_intel_bo_unreference(brw->first_post_swapbuffers_batch); - brw->first_post_swapbuffers_batch = NULL; - brw->need_throttle = false; - } -} - -static void -intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - struct brw_context *brw = brw_context(ctx); - __DRIcontext *driContext = brw->driContext; - - if (brw->saved_viewport) - brw->saved_viewport(ctx, x, y, w, h); - - if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { - dri2InvalidateDrawable(driContext->driDrawablePriv); - dri2InvalidateDrawable(driContext->driReadablePriv); - } -} - -static const struct dri_debug_control debug_control[] = { - { "tex", DEBUG_TEXTURE}, - { "state", DEBUG_STATE}, - { "ioctl", DEBUG_IOCTL}, - { "blit", DEBUG_BLIT}, - { "mip", DEBUG_MIPTREE}, - { "fall", DEBUG_PERF}, - { "perf", DEBUG_PERF}, - { "bat", DEBUG_BATCH}, - { "pix", DEBUG_PIXEL}, - { "buf", DEBUG_BUFMGR}, - { "reg", DEBUG_REGION}, - { "fbo", DEBUG_FBO}, - { "fs", DEBUG_WM }, - { "gs", DEBUG_GS}, - { "sync", DEBUG_SYNC}, - { "prim", DEBUG_PRIMS }, - { "vert", DEBUG_VERTS }, - { "dri", DEBUG_DRI }, - { "sf", DEBUG_SF }, - { "stats", DEBUG_STATS }, - { "wm", DEBUG_WM }, - { "urb", DEBUG_URB }, - { "vs", DEBUG_VS }, - { "clip", DEBUG_CLIP }, - { "aub", DEBUG_AUB }, - { "shader_time", DEBUG_SHADER_TIME }, - { "no16", DEBUG_NO16 }, - { "blorp", DEBUG_BLORP }, - { NULL, 0 } -}; - - -static void -intelInvalidateState(struct gl_context * ctx, GLuint new_state) -{ - struct brw_context *brw = brw_context(ctx); - - if (ctx->swrast_context) - _swrast_InvalidateState(ctx, new_state); - _vbo_InvalidateState(ctx, new_state); - - brw->NewGLState |= new_state; -} - -void -_intel_flush(struct gl_context *ctx, const char *file, int line) -{ - struct brw_context *brw = brw_context(ctx); - - if (brw->batch.used) - _intel_batchbuffer_flush(brw, file, line); -} - -static void -intel_glFlush(struct gl_context *ctx) -{ - struct brw_context *brw = brw_context(ctx); - - intel_flush(ctx); - intel_flush_front(ctx); - if (brw->is_front_buffer_rendering) - brw->need_throttle = true; -} - -void -intelFinish(struct gl_context * ctx) -{ - struct brw_context *brw = brw_context(ctx); - - intel_flush(ctx); - intel_flush_front(ctx); - - if (brw->batch.last_bo) - drm_intel_bo_wait_rendering(brw->batch.last_bo); -} - -void -intelInitDriverFunctions(struct dd_function_table *functions) -{ - _mesa_init_driver_functions(functions); - - functions->Flush = intel_glFlush; - functions->Finish = intelFinish; - functions->GetString = intelGetString; - functions->UpdateState = intelInvalidateState; - - intelInitTextureFuncs(functions); - intelInitTextureImageFuncs(functions); - intelInitTextureSubImageFuncs(functions); - intelInitTextureCopyImageFuncs(functions); - intelInitClearFuncs(functions); - intelInitBufferFuncs(functions); - intelInitPixelFuncs(functions); - intelInitBufferObjectFuncs(functions); - intel_init_syncobj_functions(functions); -} - -static bool -validate_context_version(struct intel_screen *screen, - int mesa_api, - unsigned major_version, - unsigned minor_version, - unsigned *dri_ctx_error) -{ - unsigned req_version = 10 * major_version + minor_version; - unsigned max_version = 0; - - switch (mesa_api) { - case API_OPENGL_COMPAT: - max_version = screen->max_gl_compat_version; - break; - case API_OPENGL_CORE: - max_version = screen->max_gl_core_version; - break; - case API_OPENGLES: - max_version = screen->max_gl_es1_version; - break; - case API_OPENGLES2: - max_version = screen->max_gl_es2_version; - break; - default: - max_version = 0; - break; - } - - if (max_version == 0) { - *dri_ctx_error = __DRI_CTX_ERROR_BAD_API; - return false; - } else if (req_version > max_version) { - *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION; - return false; - } - - return true; -} - -bool -intelInitContext(struct brw_context *brw, - int api, - unsigned major_version, - unsigned minor_version, - const struct gl_config * mesaVis, - __DRIcontext * driContextPriv, - void *sharedContextPrivate, - struct dd_function_table *functions, - unsigned *dri_ctx_error) -{ - struct gl_context *ctx = &brw->ctx; - struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate; - __DRIscreen *sPriv = driContextPriv->driScreenPriv; - struct intel_screen *intelScreen = sPriv->driverPrivate; - int bo_reuse_mode; - struct gl_config visual; - - /* we can't do anything without a connection to the device */ - if (intelScreen->bufmgr == NULL) { - *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; - return false; - } - - if (!validate_context_version(intelScreen, - api, major_version, minor_version, - dri_ctx_error)) - return false; - - /* Can't rely on invalidate events, fall back to glViewport hack */ - if (!driContextPriv->driScreenPriv->dri2.useInvalidate) { - brw->saved_viewport = functions->Viewport; - functions->Viewport = intel_viewport; - } - - if (mesaVis == NULL) { - memset(&visual, 0, sizeof visual); - mesaVis = &visual; - } - - brw->intelScreen = intelScreen; - - if (!_mesa_initialize_context(&brw->ctx, api, mesaVis, shareCtx, - functions)) { - *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; - printf("%s: failed to init mesa context\n", __FUNCTION__); - return false; - } - - driContextPriv->driverPrivate = brw; - brw->driContext = driContextPriv; - - brw->gen = intelScreen->gen; - - const int devID = intelScreen->deviceID; - if (IS_SNB_GT1(devID) || IS_IVB_GT1(devID) || IS_HSW_GT1(devID)) - brw->gt = 1; - else if (IS_SNB_GT2(devID) || IS_IVB_GT2(devID) || IS_HSW_GT2(devID)) - brw->gt = 2; - else if (IS_HSW_GT3(devID)) - brw->gt = 3; - else - brw->gt = 0; - - if (IS_HASWELL(devID)) { - brw->is_haswell = true; - } else if (IS_BAYTRAIL(devID)) { - brw->is_baytrail = true; - brw->gt = 1; - } else if (IS_G4X(devID)) { - brw->is_g4x = true; - } - - brw->has_separate_stencil = brw->intelScreen->hw_has_separate_stencil; - brw->must_use_separate_stencil = brw->intelScreen->hw_must_use_separate_stencil; - brw->has_hiz = brw->gen >= 6; - brw->has_llc = brw->intelScreen->hw_has_llc; - brw->has_swizzling = brw->intelScreen->hw_has_swizzling; - - memset(&ctx->TextureFormatSupported, - 0, sizeof(ctx->TextureFormatSupported)); - - driParseConfigFiles(&brw->optionCache, &intelScreen->optionCache, - sPriv->myNum, "i965"); - - /* Estimate the size of the mappable aperture into the GTT. There's an - * ioctl to get the whole GTT size, but not one to get the mappable subset. - * It turns out it's basically always 256MB, though some ancient hardware - * was smaller. - */ - uint32_t gtt_size = 256 * 1024 * 1024; - - /* We don't want to map two objects such that a memcpy between them would - * just fault one mapping in and then the other over and over forever. So - * we would need to divide the GTT size by 2. Additionally, some GTT is - * taken up by things like the framebuffer and the ringbuffer and such, so - * be more conservative. - */ - brw->max_gtt_map_object_size = gtt_size / 4; - - brw->bufmgr = intelScreen->bufmgr; - - bo_reuse_mode = driQueryOptioni(&brw->optionCache, "bo_reuse"); - switch (bo_reuse_mode) { - case DRI_CONF_BO_REUSE_DISABLED: - break; - case DRI_CONF_BO_REUSE_ALL: - intel_bufmgr_gem_enable_reuse(brw->bufmgr); - break; - } - - /* Initialize the software rasterizer and helper modules. - * - * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for - * software fallbacks (which we have to support on legacy GL to do weird - * glDrawPixels(), glBitmap(), and other functions). - */ - if (api != API_OPENGL_CORE) { - _swrast_CreateContext(ctx); - } - - _vbo_CreateContext(ctx); - if (ctx->swrast_context) { - _tnl_CreateContext(ctx); - _swsetup_CreateContext(ctx); - - /* Configure swrast to match hardware characteristics: */ - _swrast_allow_pixel_fog(ctx, false); - _swrast_allow_vertex_fog(ctx, true); - } - - _mesa_meta_init(ctx); - - intelInitExtensions(ctx); - - INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); - if (INTEL_DEBUG & DEBUG_BUFMGR) - dri_bufmgr_set_debug(brw->bufmgr, true); - if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && brw->gen < 7) { - fprintf(stderr, - "shader_time debugging requires gen7 (Ivybridge) or better.\n"); - INTEL_DEBUG &= ~DEBUG_SHADER_TIME; - } - if (INTEL_DEBUG & DEBUG_PERF) - brw->perf_debug = true; - - if (INTEL_DEBUG & DEBUG_AUB) - drm_intel_bufmgr_gem_set_aub_dump(brw->bufmgr, true); - - intel_batchbuffer_init(brw); - - intel_fbo_init(brw); - - if (!driQueryOptionb(&brw->optionCache, "hiz")) { - brw->has_hiz = false; - /* On gen6, you can only do separate stencil with HIZ. */ - if (brw->gen == 6) - brw->has_separate_stencil = false; - } - - if (driQueryOptionb(&brw->optionCache, "always_flush_batch")) { - fprintf(stderr, "flushing batchbuffer before/after each draw call\n"); - brw->always_flush_batch = 1; - } - - if (driQueryOptionb(&brw->optionCache, "always_flush_cache")) { - fprintf(stderr, "flushing GPU caches before/after each draw call\n"); - brw->always_flush_cache = 1; - } - - if (driQueryOptionb(&brw->optionCache, "disable_throttling")) { - fprintf(stderr, "disabling flush throttling\n"); - brw->disable_throttling = 1; - } - - return true; -} - -void -intelDestroyContext(__DRIcontext * driContextPriv) -{ - struct brw_context *brw = - (struct brw_context *) driContextPriv->driverPrivate; - struct gl_context *ctx = &brw->ctx; - - assert(brw); /* should never be null */ - if (brw) { - /* Dump a final BMP in case the application doesn't call SwapBuffers */ - if (INTEL_DEBUG & DEBUG_AUB) { - intel_batchbuffer_flush(brw); - aub_dump_bmp(&brw->ctx); - } - - _mesa_meta_free(&brw->ctx); - - brw->vtbl.destroy(brw); - - if (ctx->swrast_context) { - _swsetup_DestroyContext(&brw->ctx); - _tnl_DestroyContext(&brw->ctx); - } - _vbo_DestroyContext(&brw->ctx); - - if (ctx->swrast_context) - _swrast_DestroyContext(&brw->ctx); - - intel_batchbuffer_free(brw); - - drm_intel_bo_unreference(brw->first_post_swapbuffers_batch); - brw->first_post_swapbuffers_batch = NULL; - - driDestroyOptionCache(&brw->optionCache); - - /* free the Mesa context */ - _mesa_free_context_data(&brw->ctx); - - ralloc_free(brw); - driContextPriv->driverPrivate = NULL; - } -} - -GLboolean -intelUnbindContext(__DRIcontext * driContextPriv) -{ - /* Unset current context and dispath table */ - _mesa_make_current(NULL, NULL, NULL); - - return true; -} - -/** - * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior - * on window system framebuffers. - * - * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if - * your renderbuffer can do sRGB encode, and you can flip a switch that does - * sRGB encode if the renderbuffer can handle it. You can ask specifically - * for a visual where you're guaranteed to be capable, but it turns out that - * everyone just makes all their ARGB8888 visuals capable and doesn't offer - * incapable ones, becuase there's no difference between the two in resources - * used. Applications thus get built that accidentally rely on the default - * visual choice being sRGB, so we make ours sRGB capable. Everything sounds - * great... - * - * But for GLES2/3, they decided that it was silly to not turn on sRGB encode - * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent. - * So they removed the enable knob and made it "if the renderbuffer is sRGB - * capable, do sRGB encode". Then, for your window system renderbuffers, you - * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals - * and get no sRGB encode (assuming that both kinds of visual are available). - * Thus our choice to support sRGB by default on our visuals for desktop would - * result in broken rendering of GLES apps that aren't expecting sRGB encode. - * - * Unfortunately, renderbuffer setup happens before a context is created. So - * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3 - * context (without an sRGB visual, though we don't have sRGB visuals exposed - * yet), we go turn that back off before anyone finds out. - */ -static void -intel_gles3_srgb_workaround(struct brw_context *brw, - struct gl_framebuffer *fb) -{ - struct gl_context *ctx = &brw->ctx; - - if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable) - return; - - /* Some day when we support the sRGB capable bit on visuals available for - * GLES, we'll need to respect that and not disable things here. - */ - fb->Visual.sRGBCapable = false; - for (int i = 0; i < BUFFER_COUNT; i++) { - if (fb->Attachment[i].Renderbuffer && - fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) { - fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888; - } - } -} - -GLboolean -intelMakeCurrent(__DRIcontext * driContextPriv, - __DRIdrawable * driDrawPriv, - __DRIdrawable * driReadPriv) -{ - struct brw_context *brw; - GET_CURRENT_CONTEXT(curCtx); - - if (driContextPriv) - brw = (struct brw_context *) driContextPriv->driverPrivate; - else - brw = NULL; - - /* According to the glXMakeCurrent() man page: "Pending commands to - * the previous context, if any, are flushed before it is released." - * But only flush if we're actually changing contexts. - */ - if (brw_context(curCtx) && brw_context(curCtx) != brw) { - _mesa_flush(curCtx); - } - - if (driContextPriv) { - struct gl_context *ctx = &brw->ctx; - struct gl_framebuffer *fb, *readFb; - - if (driDrawPriv == NULL && driReadPriv == NULL) { - fb = _mesa_get_incomplete_framebuffer(); - readFb = _mesa_get_incomplete_framebuffer(); - } else { - fb = driDrawPriv->driverPrivate; - readFb = driReadPriv->driverPrivate; - driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1; - driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1; - } - - /* The sRGB workaround changes the renderbuffer's format. We must change - * the format before the renderbuffer's miptree get's allocated, otherwise - * the formats of the renderbuffer and its miptree will differ. - */ - intel_gles3_srgb_workaround(brw, fb); - intel_gles3_srgb_workaround(brw, readFb); - - intel_prepare_render(brw); - _mesa_make_current(ctx, fb, readFb); - } - else { - _mesa_make_current(NULL, NULL, NULL); - } - - return true; -} - -/** - * \brief Query DRI2 to obtain a DRIdrawable's buffers. - * - * To determine which DRI buffers to request, examine the renderbuffers - * attached to the drawable's framebuffer. Then request the buffers with - * DRI2GetBuffers() or DRI2GetBuffersWithFormat(). - * - * This is called from intel_update_renderbuffers(). - * - * \param drawable Drawable whose buffers are queried. - * \param buffers [out] List of buffers returned by DRI2 query. - * \param buffer_count [out] Number of buffers returned. - * - * \see intel_update_renderbuffers() - * \see DRI2GetBuffers() - * \see DRI2GetBuffersWithFormat() - */ -static void -intel_query_dri2_buffers(struct brw_context *brw, - __DRIdrawable *drawable, - __DRIbuffer **buffers, - int *buffer_count) -{ - __DRIscreen *screen = brw->intelScreen->driScrnPriv; - struct gl_framebuffer *fb = drawable->driverPrivate; - int i = 0; - unsigned attachments[8]; - - struct intel_renderbuffer *front_rb; - struct intel_renderbuffer *back_rb; - - front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); - back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); - - memset(attachments, 0, sizeof(attachments)); - if ((brw->is_front_buffer_rendering || - brw->is_front_buffer_reading || - !back_rb) && front_rb) { - /* If a fake front buffer is in use, then querying for - * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from - * the real front buffer to the fake front buffer. So before doing the - * query, we need to make sure all the pending drawing has landed in the - * real front buffer. - */ - intel_flush(&brw->ctx); - intel_flush_front(&brw->ctx); - - attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - attachments[i++] = intel_bits_per_pixel(front_rb); - } else if (front_rb && brw->front_buffer_dirty) { - /* We have pending front buffer rendering, but we aren't querying for a - * front buffer. If the front buffer we have is a fake front buffer, - * the X server is going to throw it away when it processes the query. - * So before doing the query, make sure all the pending drawing has - * landed in the real front buffer. - */ - intel_flush(&brw->ctx); - intel_flush_front(&brw->ctx); - } - - if (back_rb) { - attachments[i++] = __DRI_BUFFER_BACK_LEFT; - attachments[i++] = intel_bits_per_pixel(back_rb); - } - - assert(i <= ARRAY_SIZE(attachments)); - - *buffers = screen->dri2.loader->getBuffersWithFormat(drawable, - &drawable->w, - &drawable->h, - attachments, i / 2, - buffer_count, - drawable->loaderPrivate); - LEAVE(); -} - -/** - * \brief Assign a DRI buffer's DRM region to a renderbuffer. - * - * This is called from intel_update_renderbuffers(). - * - * \par Note: - * DRI buffers whose attachment point is DRI2BufferStencil or - * DRI2BufferDepthStencil are handled as special cases. - * - * \param buffer_name is a human readable name, such as "dri2 front buffer", - * that is passed to intel_region_alloc_for_handle(). - * - * \see intel_update_renderbuffers() - * \see intel_region_alloc_for_handle() - */ -static void -intel_process_dri2_buffer(struct brw_context *brw, - __DRIdrawable *drawable, - __DRIbuffer *buffer, - struct intel_renderbuffer *rb, - const char *buffer_name) -{ - struct intel_region *region = NULL; - - if (!rb) - return; - - unsigned num_samples = rb->Base.Base.NumSamples; - - /* We try to avoid closing and reopening the same BO name, because the first - * use of a mapping of the buffer involves a bunch of page faulting which is - * moderately expensive. - */ - if (num_samples == 0) { - if (rb->mt && - rb->mt->region && - rb->mt->region->name == buffer->name) - return; - } else { - if (rb->mt && - rb->mt->singlesample_mt && - rb->mt->singlesample_mt->region && - rb->mt->singlesample_mt->region->name == buffer->name) - return; - } - - if (unlikely(INTEL_DEBUG & DEBUG_DRI)) { - fprintf(stderr, - "attaching buffer %d, at %d, cpp %d, pitch %d\n", - buffer->name, buffer->attachment, - buffer->cpp, buffer->pitch); - } - - intel_miptree_release(&rb->mt); - region = intel_region_alloc_for_handle(brw->intelScreen, - buffer->cpp, - drawable->w, - drawable->h, - buffer->pitch, - buffer->name, - buffer_name); - if (!region) - return; - - rb->mt = intel_miptree_create_for_dri2_buffer(brw, - buffer->attachment, - intel_rb_format(rb), - num_samples, - region); - intel_region_release(®ion); -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_fbo.c.bak b/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_fbo.c.bak deleted file mode 100644 index 43e9d9e5dd..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/drivers/dri/i965/intel_fbo.c.bak +++ /dev/null @@ -1,899 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "main/enums.h" -#include "main/imports.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "main/fbobject.h" -#include "main/framebuffer.h" -#include "main/renderbuffer.h" -#include "main/context.h" -#include "main/teximage.h" -#include "main/image.h" - -#include "swrast/swrast.h" -#include "drivers/common/meta.h" - -#include "intel_batchbuffer.h" -#include "intel_buffers.h" -#include "intel_blit.h" -#include "intel_fbo.h" -#include "intel_mipmap_tree.h" -#include "intel_regions.h" -#include "intel_tex.h" -#include "brw_context.h" - -#define FILE_DEBUG_FLAG DEBUG_FBO - -/** - * Create a new framebuffer object. - */ -static struct gl_framebuffer * -intel_new_framebuffer(struct gl_context * ctx, GLuint name) -{ - /* Only drawable state in intel_framebuffer at this time, just use Mesa's - * class - */ - return _mesa_new_framebuffer(ctx, name); -} - - -/** Called by gl_renderbuffer::Delete() */ -static void -intel_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) -{ - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - - ASSERT(irb); - - intel_miptree_release(&irb->mt); - - _mesa_delete_renderbuffer(ctx, rb); -} - -/** - * \see dd_function_table::MapRenderbuffer - */ -static void -intel_map_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **out_map, - GLint *out_stride) -{ - struct brw_context *brw = brw_context(ctx); - struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb; - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - void *map; - int stride; - - if (srb->Buffer) { - /* this is a malloc'd renderbuffer (accum buffer), not an irb */ - GLint bpp = _mesa_get_format_bytes(rb->Format); - GLint rowStride = srb->RowStride; - *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp; - *out_stride = rowStride; - return; - } - - intel_prepare_render(brw); - - /* For a window-system renderbuffer, we need to flip the mapping we receive - * upside-down. So we need to ask for a rectangle on flipped vertically, and - * we then return a pointer to the bottom of it with a negative stride. - */ - if (rb->Name == 0) { - y = rb->Height - y - h; - } - - intel_miptree_map(brw, irb->mt, irb->mt_level, irb->mt_layer, - x, y, w, h, mode, &map, &stride); - - if (rb->Name == 0) { - map += (h - 1) * stride; - stride = -stride; - } - - DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n", - __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format), - x, y, w, h, map, stride); - - *out_map = map; - *out_stride = stride; -} - -/** - * \see dd_function_table::UnmapRenderbuffer - */ -static void -intel_unmap_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb) -{ - struct brw_context *brw = brw_context(ctx); - struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb; - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - - DBG("%s: rb %d (%s)\n", __FUNCTION__, - rb->Name, _mesa_get_format_name(rb->Format)); - - if (srb->Buffer) { - /* this is a malloc'd renderbuffer (accum buffer) */ - /* nothing to do */ - return; - } - - intel_miptree_unmap(brw, irb->mt, irb->mt_level, irb->mt_layer); -} - - -/** - * Round up the requested multisample count to the next supported sample size. - */ -unsigned -intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples) -{ - switch (intel->gen) { - case 6: - /* Gen6 supports only 4x multisampling. */ - if (num_samples > 0) - return 4; - else - return 0; - case 7: - /* Gen7 supports 4x and 8x multisampling. */ - if (num_samples > 4) - return 8; - else if (num_samples > 0) - return 4; - else - return 0; - return 0; - default: - /* MSAA unsupported. */ - return 0; - } -} - - -/** - * Called via glRenderbufferStorageEXT() to set the format and allocate - * storage for a user-created renderbuffer. - */ -static GLboolean -intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) -{ - struct brw_context *brw = brw_context(ctx); - struct intel_screen *screen = brw->intelScreen; - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples); - - switch (internalFormat) { - default: - /* Use the same format-choice logic as for textures. - * Renderbuffers aren't any different from textures for us, - * except they're less useful because you can't texture with - * them. - */ - rb->Format = ctx->Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D, - internalFormat, - GL_NONE, GL_NONE); - break; - case GL_STENCIL_INDEX: - case GL_STENCIL_INDEX1_EXT: - case GL_STENCIL_INDEX4_EXT: - case GL_STENCIL_INDEX8_EXT: - case GL_STENCIL_INDEX16_EXT: - /* These aren't actual texture formats, so force them here. */ - if (brw->has_separate_stencil) { - rb->Format = MESA_FORMAT_S8; - } else { - assert(!brw->must_use_separate_stencil); - rb->Format = MESA_FORMAT_S8_Z24; - } - break; - } - - rb->Width = width; - rb->Height = height; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); - - intel_miptree_release(&irb->mt); - - DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(internalFormat), - _mesa_get_format_name(rb->Format), width, height); - - if (width == 0 || height == 0) - return true; - - irb->mt = intel_miptree_create_for_renderbuffer(brw, rb->Format, - width, height, - rb->NumSamples); - if (!irb->mt) - return false; - - return true; -} - - -static void -intel_image_target_renderbuffer_storage(struct gl_context *ctx, - struct gl_renderbuffer *rb, - void *image_handle) -{ - struct brw_context *brw = brw_context(ctx); - struct intel_renderbuffer *irb; - __DRIscreen *screen; - __DRIimage *image; - - screen = brw->intelScreen->driScrnPriv; - image = screen->dri2.image->lookupEGLImage(screen, image_handle, - screen->loaderPrivate); - if (image == NULL) - return; - - /* __DRIimage is opaque to the core so it has to be checked here */ - switch (image->format) { - case MESA_FORMAT_RGBA8888_REV: - _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetRenderbufferStorage(unsupported image format"); - return; - break; - default: - break; - } - - irb = intel_renderbuffer(rb); - intel_miptree_release(&irb->mt); - irb->mt = intel_miptree_create_for_bo(brw, - image->region->bo, - image->format, - image->offset, - image->region->width, - image->region->height, - image->region->pitch, - image->region->tiling); - if (!irb->mt) - return; - - rb->InternalFormat = image->internal_format; - rb->Width = image->region->width; - rb->Height = image->region->height; - rb->Format = image->format; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, image->internal_format); - rb->NeedsFinishRenderTexture = true; -} - -/** - * Called by _mesa_resize_framebuffer() for each hardware renderbuffer when a - * window system framebuffer is resized. - * - * Any actual buffer reallocations for hardware renderbuffers (which would - * have triggered _mesa_resize_framebuffer()) were done by - * intel_process_dri2_buffer(). - */ -static GLboolean -intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) -{ - ASSERT(rb->Name == 0); - rb->Width = width; - rb->Height = height; - rb->InternalFormat = internalFormat; - - return true; -} - -/** Dummy function for gl_renderbuffer::AllocStorage() */ -static GLboolean -intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) -{ - _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); - return false; -} - -/** - * Create a new intel_renderbuffer which corresponds to an on-screen window, - * not a user-created renderbuffer. - * - * \param num_samples must be quantized. - */ -struct intel_renderbuffer * -intel_create_renderbuffer(gl_format format, unsigned num_samples) -{ - struct intel_renderbuffer *irb; - struct gl_renderbuffer *rb; - - ENTER(); - - GET_CURRENT_CONTEXT(ctx); - - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); - return NULL; - } - - rb = &irb->Base.Base; - - _mesa_init_renderbuffer(rb, 0); - rb->ClassID = INTEL_RB_CLASS; - rb->_BaseFormat = _mesa_get_format_base_format(format); - rb->Format = format; - rb->InternalFormat = rb->_BaseFormat; - rb->NumSamples = num_samples; - - /* intel-specific methods */ - rb->Delete = intel_delete_renderbuffer; - rb->AllocStorage = intel_alloc_window_storage; - - LEAVE(); - - return irb; -} - -/** - * Private window-system buffers (as opposed to ones shared with the display - * server created with intel_create_renderbuffer()) are most similar in their - * handling to user-created renderbuffers, but they have a resize handler that - * may be called at intel_update_renderbuffers() time. - * - * \param num_samples must be quantized. - */ -struct intel_renderbuffer * -intel_create_private_renderbuffer(gl_format format, unsigned num_samples) -{ - struct intel_renderbuffer *irb; - - irb = intel_create_renderbuffer(format, num_samples); - irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage; - - return irb; -} - -/** - * Create a new renderbuffer object. - * Typically called via glBindRenderbufferEXT(). - */ -static struct gl_renderbuffer * -intel_new_renderbuffer(struct gl_context * ctx, GLuint name) -{ - struct intel_renderbuffer *irb; - struct gl_renderbuffer *rb; - - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); - return NULL; - } - - rb = &irb->Base.Base; - - _mesa_init_renderbuffer(rb, name); - rb->ClassID = INTEL_RB_CLASS; - - /* intel-specific methods */ - rb->Delete = intel_delete_renderbuffer; - rb->AllocStorage = intel_alloc_renderbuffer_storage; - /* span routines set in alloc_storage function */ - - return rb; -} - -static bool -intel_renderbuffer_update_wrapper(struct brw_context *brw, - struct intel_renderbuffer *irb, - struct gl_texture_image *image, - uint32_t layer) -{ - struct gl_renderbuffer *rb = &irb->Base.Base; - struct intel_texture_image *intel_image = intel_texture_image(image); - struct intel_mipmap_tree *mt = intel_image->mt; - int level = image->Level; - - rb->Depth = image->Depth; - - rb->AllocStorage = intel_nop_alloc_storage; - - intel_miptree_check_level_layer(mt, level, layer); - irb->mt_level = level; - - switch (mt->msaa_layout) { - case INTEL_MSAA_LAYOUT_UMS: - case INTEL_MSAA_LAYOUT_CMS: - irb->mt_layer = layer * mt->num_samples; - break; - - default: - irb->mt_layer = layer; - } - - intel_miptree_reference(&irb->mt, mt); - - intel_renderbuffer_set_draw_offset(irb); - - if (mt->hiz_mt == NULL && brw_is_hiz_depth_format(brw, rb->Format)) { - intel_miptree_alloc_hiz(brw, mt); - if (!mt->hiz_mt) - return false; - } - - return true; -} - -void -intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb) -{ - unsigned int dst_x, dst_y; - - /* compute offset of the particular 2D image within the texture region */ - intel_miptree_get_image_offset(irb->mt, - irb->mt_level, - irb->mt_layer, - &dst_x, &dst_y); - - irb->draw_x = dst_x; - irb->draw_y = dst_y; -} - -/** - * Called by glFramebufferTexture[123]DEXT() (and other places) to - * prepare for rendering into texture memory. This might be called - * many times to choose different texture levels, cube faces, etc - * before intel_finish_render_texture() is ever called. - */ -static void -intel_render_texture(struct gl_context * ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) -{ - struct brw_context *brw = brw_context(ctx); - struct gl_renderbuffer *rb = att->Renderbuffer; - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - struct gl_texture_image *image = rb->TexImage; - struct intel_texture_image *intel_image = intel_texture_image(image); - struct intel_mipmap_tree *mt = intel_image->mt; - int layer; - - (void) fb; - - if (att->CubeMapFace > 0) { - assert(att->Zoffset == 0); - layer = att->CubeMapFace; - } else { - layer = att->Zoffset; - } - - if (!intel_image->mt) { - /* Fallback on drawing to a texture that doesn't have a miptree - * (has a border, width/height 0, etc.) - */ - _swrast_render_texture(ctx, fb, att); - return; - } - - intel_miptree_check_level_layer(mt, att->TextureLevel, layer); - - if (!intel_renderbuffer_update_wrapper(brw, irb, image, layer)) { - _swrast_render_texture(ctx, fb, att); - return; - } - - DBG("Begin render %s texture tex=%u w=%d h=%d d=%d refcount=%d\n", - _mesa_get_format_name(image->TexFormat), - att->Texture->Name, image->Width, image->Height, image->Depth, - rb->RefCount); -} - - -/** - * Called by Mesa when rendering to a texture is done. - */ -static void -intel_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer *rb) -{ - struct brw_context *brw = brw_context(ctx); - - DBG("Finish render %s texture\n", _mesa_get_format_name(rb->Format)); - - /* Since we've (probably) rendered to the texture and will (likely) use - * it in the texture domain later on in this batchbuffer, flush the - * batch. Once again, we wish for a domain tracker in libdrm to cover - * usage inside of a batchbuffer like GEM does in the kernel. - */ - intel_batchbuffer_emit_mi_flush(brw); -} - -#define fbo_incomplete(fb, ...) do { \ - static GLuint msg_id = 0; \ - if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) { \ - _mesa_gl_debug(ctx, &msg_id, \ - MESA_DEBUG_TYPE_OTHER, \ - MESA_DEBUG_SEVERITY_MEDIUM, \ - __VA_ARGS__); \ - } \ - DBG(__VA_ARGS__); \ - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; \ - } while (0) - -/** - * Do additional "completeness" testing of a framebuffer object. - */ -static void -intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) -{ - struct brw_context *brw = brw_context(ctx); - struct intel_renderbuffer *depthRb = - intel_get_renderbuffer(fb, BUFFER_DEPTH); - struct intel_renderbuffer *stencilRb = - intel_get_renderbuffer(fb, BUFFER_STENCIL); - struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL; - int i; - - DBG("%s() on fb %p (%s)\n", __FUNCTION__, - fb, (fb == ctx->DrawBuffer ? "drawbuffer" : - (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer"))); - - if (depthRb) - depth_mt = depthRb->mt; - if (stencilRb) { - stencil_mt = stencilRb->mt; - if (stencil_mt->stencil_mt) - stencil_mt = stencil_mt->stencil_mt; - } - - if (depth_mt && stencil_mt) { - if (depth_mt == stencil_mt) { - /* For true packed depth/stencil (not faked on prefers-separate-stencil - * hardware) we need to be sure they're the same level/layer, since - * we'll be emitting a single packet describing the packed setup. - */ - if (depthRb->mt_level != stencilRb->mt_level || - depthRb->mt_layer != stencilRb->mt_layer) { - fbo_incomplete(fb, - "FBO incomplete: depth image level/layer %d/%d != " - "stencil image %d/%d\n", - depthRb->mt_level, - depthRb->mt_layer, - stencilRb->mt_level, - stencilRb->mt_layer); - } - } else { - if (!brw->has_separate_stencil) { - fbo_incomplete(fb, "FBO incomplete: separate stencil " - "unsupported\n"); - } - if (stencil_mt->format != MESA_FORMAT_S8) { - fbo_incomplete(fb, "FBO incomplete: separate stencil is %s " - "instead of S8\n", - _mesa_get_format_name(stencil_mt->format)); - } - if (brw->gen < 7 && !intel_renderbuffer_has_hiz(depthRb)) { - /* Before Gen7, separate depth and stencil buffers can be used - * only if HiZ is enabled. From the Sandybridge PRM, Volume 2, - * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable: - * [DevSNB]: This field must be set to the same value (enabled - * or disabled) as Hierarchical Depth Buffer Enable. - */ - fbo_incomplete(fb, "FBO incomplete: separate stencil " - "without HiZ\n"); - } - } - } - - for (i = 0; i < Elements(fb->Attachment); i++) { - struct gl_renderbuffer *rb; - struct intel_renderbuffer *irb; - - if (fb->Attachment[i].Type == GL_NONE) - continue; - - /* A supported attachment will have a Renderbuffer set either - * from being a Renderbuffer or being a texture that got the - * intel_wrap_texture() treatment. - */ - rb = fb->Attachment[i].Renderbuffer; - if (rb == NULL) { - fbo_incomplete(fb, "FBO incomplete: attachment without " - "renderbuffer\n"); - continue; - } - - if (fb->Attachment[i].Type == GL_TEXTURE) { - if (rb->TexImage->Border) { - fbo_incomplete(fb, "FBO incomplete: texture with border\n"); - continue; - } - } - - irb = intel_renderbuffer(rb); - if (irb == NULL) { - fbo_incomplete(fb, "FBO incomplete: software rendering " - "renderbuffer\n"); - continue; - } - - if (!brw_render_target_supported(brw, rb)) { - fbo_incomplete(fb, "FBO incomplete: Unsupported HW " - "texture/renderbuffer format attached: %s\n", - _mesa_get_format_name(intel_rb_format(irb))); - } - } -} - -/** - * Try to do a glBlitFramebuffer using glCopyTexSubImage2D - * We can do this when the dst renderbuffer is actually a texture and - * there is no scaling, mirroring or scissoring. - * - * \return new buffer mask indicating the buffers left to blit using the - * normal path. - */ -static GLbitfield -intel_blit_framebuffer_with_blitter(struct gl_context *ctx, - GLint srcX0, GLint srcY0, - GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - struct brw_context *brw = brw_context(ctx); - - /* Sync up the state of window system buffers. We need to do this before - * we go looking for the buffers. - */ - intel_prepare_render(brw); - - if (mask & GL_COLOR_BUFFER_BIT) { - GLint i; - const struct gl_framebuffer *drawFb = ctx->DrawBuffer; - const struct gl_framebuffer *readFb = ctx->ReadBuffer; - struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer; - struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); - - if (!src_irb) { - perf_debug("glBlitFramebuffer(): missing src renderbuffer. " - "Falling back to software rendering.\n"); - return mask; - } - - /* If the source and destination are the same size with no mirroring, - * the rectangles are within the size of the texture and there is no - * scissor, then we can probably use the blit engine. - */ - if (!(srcX0 - srcX1 == dstX0 - dstX1 && - srcY0 - srcY1 == dstY0 - dstY1 && - srcX1 >= srcX0 && - srcY1 >= srcY0 && - srcX0 >= 0 && srcX1 <= readFb->Width && - srcY0 >= 0 && srcY1 <= readFb->Height && - dstX0 >= 0 && dstX1 <= drawFb->Width && - dstY0 >= 0 && dstY1 <= drawFb->Height && - !ctx->Scissor.Enabled)) { - perf_debug("glBlitFramebuffer(): non-1:1 blit. " - "Falling back to software rendering.\n"); - return mask; - } - - /* Blit to all active draw buffers. We don't do any pre-checking, - * because we assume that copying to MRTs is rare, and failure midway - * through copying is even more rare. Even if it was to occur, it's - * safe to let meta start the copy over from scratch, because - * glBlitFramebuffer completely overwrites the destination pixels, and - * results are undefined if any destination pixels have a dependency on - * source pixels. - */ - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - struct gl_renderbuffer *dst_rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; - struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb); - - if (!dst_irb) { - perf_debug("glBlitFramebuffer(): missing dst renderbuffer. " - "Falling back to software rendering.\n"); - return mask; - } - - gl_format src_format = _mesa_get_srgb_format_linear(src_rb->Format); - gl_format dst_format = _mesa_get_srgb_format_linear(dst_rb->Format); - if (src_format != dst_format) { - perf_debug("glBlitFramebuffer(): unsupported blit from %s to %s. " - "Falling back to software rendering.\n", - _mesa_get_format_name(src_format), - _mesa_get_format_name(dst_format)); - return mask; - } - - if (!intel_miptree_blit(brw, - src_irb->mt, - src_irb->mt_level, src_irb->mt_layer, - srcX0, srcY0, src_rb->Name == 0, - dst_irb->mt, - dst_irb->mt_level, dst_irb->mt_layer, - dstX0, dstY0, dst_rb->Name == 0, - dstX1 - dstX0, dstY1 - dstY0, GL_COPY)) { - perf_debug("glBlitFramebuffer(): unknown blit failure. " - "Falling back to software rendering.\n"); - return mask; - } - } - - mask &= ~GL_COLOR_BUFFER_BIT; - } - - return mask; -} - -static void -intel_blit_framebuffer(struct gl_context *ctx, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - mask = brw_blorp_framebuffer(brw_context(ctx), - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); - if (mask == 0x0) - return; - - /* Try using the BLT engine. */ - mask = intel_blit_framebuffer_with_blitter(ctx, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); - if (mask == 0x0) - return; - - - _mesa_meta_BlitFramebuffer(ctx, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); -} - -/** - * This is a no-op except on multisample buffers shared with DRI2. - */ -void -intel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb) -{ - if (irb->mt && irb->mt->singlesample_mt) - irb->mt->need_downsample = true; -} - -/** - * Does the renderbuffer have hiz enabled? - */ -bool -intel_renderbuffer_has_hiz(struct intel_renderbuffer *irb) -{ - return intel_miptree_slice_has_hiz(irb->mt, irb->mt_level, irb->mt_layer); -} - -void -intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb) -{ - if (irb->mt) { - intel_miptree_slice_set_needs_hiz_resolve(irb->mt, - irb->mt_level, - irb->mt_layer); - } -} - -void -intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb) -{ - if (irb->mt) { - intel_miptree_slice_set_needs_depth_resolve(irb->mt, - irb->mt_level, - irb->mt_layer); - } -} - -bool -intel_renderbuffer_resolve_hiz(struct brw_context *brw, - struct intel_renderbuffer *irb) -{ - if (irb->mt) - return intel_miptree_slice_resolve_hiz(brw, - irb->mt, - irb->mt_level, - irb->mt_layer); - - return false; -} - -bool -intel_renderbuffer_resolve_depth(struct brw_context *brw, - struct intel_renderbuffer *irb) -{ - if (irb->mt) - return intel_miptree_slice_resolve_depth(brw, - irb->mt, - irb->mt_level, - irb->mt_layer); - - return false; -} - -void -intel_renderbuffer_move_to_temp(struct brw_context *brw, - struct intel_renderbuffer *irb, - bool invalidate) -{ - struct gl_renderbuffer *rb =&irb->Base.Base; - struct intel_texture_image *intel_image = intel_texture_image(rb->TexImage); - struct intel_mipmap_tree *new_mt; - int width, height, depth; - - intel_miptree_get_dimensions_for_image(rb->TexImage, &width, &height, &depth); - - new_mt = intel_miptree_create(brw, rb->TexImage->TexObject->Target, - intel_image->base.Base.TexFormat, - intel_image->base.Base.Level, - intel_image->base.Base.Level, - width, height, depth, - true, - irb->mt->num_samples, - INTEL_MIPTREE_TILING_ANY); - - if (brw_is_hiz_depth_format(brw, new_mt->format)) { - intel_miptree_alloc_hiz(brw, new_mt); - } - - intel_miptree_copy_teximage(brw, intel_image, new_mt, invalidate); - - intel_miptree_reference(&irb->mt, intel_image->mt); - intel_renderbuffer_set_draw_offset(irb); - intel_miptree_release(&new_mt); -} - -/** - * Do one-time context initializations related to GL_EXT_framebuffer_object. - * Hook in device driver functions. - */ -void -intel_fbo_init(struct brw_context *brw) -{ - struct dd_function_table *dd = &brw->ctx.Driver; - dd->NewFramebuffer = intel_new_framebuffer; - dd->NewRenderbuffer = intel_new_renderbuffer; - dd->MapRenderbuffer = intel_map_renderbuffer; - dd->UnmapRenderbuffer = intel_unmap_renderbuffer; - dd->RenderTexture = intel_render_texture; - dd->FinishRenderTexture = intel_finish_render_texture; - dd->ValidateFramebuffer = intel_validate_framebuffer; - dd->BlitFramebuffer = intel_blit_framebuffer; - dd->EGLImageTargetRenderbufferStorage = - intel_image_target_renderbuffer_storage; -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/main/clear.c.bak b/contrib/sdk/sources/Mesa/src/mesa/main/clear.c.bak deleted file mode 100644 index ef7621bac4..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/main/clear.c.bak +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file clear.c - * glClearColor, glClearIndex, glClear() functions. - */ - - - -#include "glheader.h" -#include "clear.h" -#include "context.h" -#include "colormac.h" -#include "enums.h" -#include "macros.h" -#include "mtypes.h" -#include "state.h" - - - -void GLAPIENTRY -_mesa_ClearIndex( GLfloat c ) -{ - GET_CURRENT_CONTEXT(ctx); - - ctx->Color.ClearIndex = (GLuint) c; -} - - -/** - * Specify the clear values for the color buffers. - * - * \param red red color component. - * \param green green color component. - * \param blue blue color component. - * \param alpha alpha component. - * - * \sa glClearColor(). - * - * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a - * change, flushes the vertices and notifies the driver via the - * dd_function_table::ClearColor callback. - */ -void GLAPIENTRY -_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) -{ - GET_CURRENT_CONTEXT(ctx); - - ctx->Color.ClearColor.f[0] = red; - ctx->Color.ClearColor.f[1] = green; - ctx->Color.ClearColor.f[2] = blue; - ctx->Color.ClearColor.f[3] = alpha; -} - - -/** - * GL_EXT_texture_integer - */ -void GLAPIENTRY -_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) -{ - GET_CURRENT_CONTEXT(ctx); - - ctx->Color.ClearColor.i[0] = r; - ctx->Color.ClearColor.i[1] = g; - ctx->Color.ClearColor.i[2] = b; - ctx->Color.ClearColor.i[3] = a; -} - - -/** - * GL_EXT_texture_integer - */ -void GLAPIENTRY -_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a) -{ - GET_CURRENT_CONTEXT(ctx); - - ctx->Color.ClearColor.ui[0] = r; - ctx->Color.ClearColor.ui[1] = g; - ctx->Color.ClearColor.ui[2] = b; - ctx->Color.ClearColor.ui[3] = a; -} - - -/** - * Clear buffers. - * - * \param mask bit-mask indicating the buffers to be cleared. - * - * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState - * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, - * etc. If the rasterization mode is set to GL_RENDER then requests the driver - * to clear the buffers, via the dd_function_table::Clear callback. - */ -void GLAPIENTRY -_mesa_Clear( GLbitfield mask ) -{ - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - - FLUSH_CURRENT(ctx, 0); - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glClear 0x%x\n", mask); - - if (mask & ~(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_STENCIL_BUFFER_BIT | - GL_ACCUM_BUFFER_BIT)) { - /* invalid bit set */ - _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask); - return; - } - - /* Accumulation buffers were removed in core contexts, and they never - * existed in OpenGL ES. - */ - if ((mask & GL_ACCUM_BUFFER_BIT) != 0 - && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { - _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); - return; - } - - if (ctx->NewState) { - _mesa_update_state( ctx ); /* update _Xmin, etc */ - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glClear(incomplete framebuffer)"); - return; - } - - if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || - ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || - ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) - return; - - if (ctx->RasterDiscard) - return; - - if (ctx->RenderMode == GL_RENDER) { - GLbitfield bufferMask; - - /* don't clear depth buffer if depth writing disabled */ - if (!ctx->Depth.Mask) - mask &= ~GL_DEPTH_BUFFER_BIT; - - /* Build the bitmask to send to device driver's Clear function. - * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 - * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the - * BUFFER_BIT_COLORn flags. - */ - bufferMask = 0; - if (mask & GL_COLOR_BUFFER_BIT) { - GLuint i; - for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { - bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]); - } - } - - if ((mask & GL_DEPTH_BUFFER_BIT) - && ctx->DrawBuffer->Visual.haveDepthBuffer) { - bufferMask |= BUFFER_BIT_DEPTH; - } - - if ((mask & GL_STENCIL_BUFFER_BIT) - && ctx->DrawBuffer->Visual.haveStencilBuffer) { - bufferMask |= BUFFER_BIT_STENCIL; - } - - if ((mask & GL_ACCUM_BUFFER_BIT) - && ctx->DrawBuffer->Visual.haveAccumBuffer) { - bufferMask |= BUFFER_BIT_ACCUM; - } - - ASSERT(ctx->Driver.Clear); - ctx->Driver.Clear(ctx, bufferMask); - } - LEAVE(); - -} - - -/** Returned by make_color_buffer_mask() for errors */ -#define INVALID_MASK ~0x0 - - -/** - * Convert the glClearBuffer 'drawbuffer' parameter into a bitmask of - * BUFFER_BIT_x values. - * Return INVALID_MASK if the drawbuffer value is invalid. - */ -static GLbitfield -make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer) -{ - const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment; - GLbitfield mask = 0x0; - - switch (drawbuffer) { - case GL_FRONT: - if (att[BUFFER_FRONT_LEFT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_LEFT; - if (att[BUFFER_FRONT_RIGHT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_RIGHT; - break; - case GL_BACK: - if (att[BUFFER_BACK_LEFT].Renderbuffer) - mask |= BUFFER_BIT_BACK_LEFT; - if (att[BUFFER_BACK_RIGHT].Renderbuffer) - mask |= BUFFER_BIT_BACK_RIGHT; - break; - case GL_LEFT: - if (att[BUFFER_FRONT_LEFT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_LEFT; - if (att[BUFFER_BACK_LEFT].Renderbuffer) - mask |= BUFFER_BIT_BACK_LEFT; - break; - case GL_RIGHT: - if (att[BUFFER_FRONT_RIGHT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_RIGHT; - if (att[BUFFER_BACK_RIGHT].Renderbuffer) - mask |= BUFFER_BIT_BACK_RIGHT; - break; - case GL_FRONT_AND_BACK: - if (att[BUFFER_FRONT_LEFT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_LEFT; - if (att[BUFFER_BACK_LEFT].Renderbuffer) - mask |= BUFFER_BIT_BACK_LEFT; - if (att[BUFFER_FRONT_RIGHT].Renderbuffer) - mask |= BUFFER_BIT_FRONT_RIGHT; - if (att[BUFFER_BACK_RIGHT].Renderbuffer) - 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); - } - } - - return mask; -} - - - -/** - * New in GL 3.0 - * Clear signed integer color buffer or stencil buffer (not depth). - */ -void GLAPIENTRY -_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) -{ - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - - FLUSH_CURRENT(ctx, 0); - - if (ctx->NewState) { - _mesa_update_state( ctx ); - } - - switch (buffer) { - case GL_STENCIL: - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "ClearBuffer generates an INVALID VALUE error if buffer is - * COLOR and drawbuffer is less than zero, or greater than the - * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, - * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", - drawbuffer); - return; - } - else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) { - /* Save current stencil clear value, set to 'value', do the - * stencil clear and restore the clear value. - * XXX in the future we may have a new ctx->Driver.ClearBuffer() - * hook instead. - */ - const GLuint clearSave = ctx->Stencil.Clear; - ctx->Stencil.Clear = *value; - ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); - ctx->Stencil.Clear = clearSave; - } - break; - case GL_COLOR: - { - const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", - drawbuffer); - return; - } - else if (mask && !ctx->RasterDiscard) { - union gl_color_union clearSave; - - /* save color */ - clearSave = ctx->Color.ClearColor; - /* set color */ - COPY_4V(ctx->Color.ClearColor.i, value); - /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); - /* restore color */ - ctx->Color.ClearColor = clearSave; - } - } - break; - case GL_DEPTH: - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "The result of ClearBuffer is undefined if no conversion between - * the type of the specified value and the type of the buffer being - * cleared is defined (for example, if ClearBufferiv is called for a - * fixed- or floating-point buffer, or if ClearBufferfv is called - * for a signed or unsigned integer buffer). This is not an error." - * - * In this case we take "undefined" and "not an error" to mean "ignore." - * Note that we still need to generate an error for the invalid - * drawbuffer case (see the GL_STENCIL case above). - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferiv(drawbuffer=%d)", - drawbuffer); - return; - } - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", - _mesa_lookup_enum_by_nr(buffer)); - return; - } -} - - -/** - * New in GL 3.0 - * Clear unsigned integer color buffer (not depth, not stencil). - */ -void GLAPIENTRY -_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) -{ - GET_CURRENT_CONTEXT(ctx); - - FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); - - if (ctx->NewState) { - _mesa_update_state( ctx ); - } - - switch (buffer) { - case GL_COLOR: - { - const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", - drawbuffer); - return; - } - else if (mask && !ctx->RasterDiscard) { - union gl_color_union clearSave; - - /* save color */ - clearSave = ctx->Color.ClearColor; - /* set color */ - COPY_4V(ctx->Color.ClearColor.ui, value); - /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); - /* restore color */ - ctx->Color.ClearColor = clearSave; - } - } - break; - case GL_DEPTH: - case GL_STENCIL: - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "The result of ClearBuffer is undefined if no conversion between - * the type of the specified value and the type of the buffer being - * cleared is defined (for example, if ClearBufferiv is called for a - * fixed- or floating-point buffer, or if ClearBufferfv is called - * for a signed or unsigned integer buffer). This is not an error." - * - * In this case we take "undefined" and "not an error" to mean "ignore." - * Even though we could do something sensible for GL_STENCIL, page 263 - * (page 279 of the PDF) says: - * - * "Only ClearBufferiv should be used to clear stencil buffers." - * - * Note that we still need to generate an error for the invalid - * drawbuffer case (see the GL_STENCIL case in _mesa_ClearBufferiv). - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferuiv(drawbuffer=%d)", - drawbuffer); - return; - } - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", - _mesa_lookup_enum_by_nr(buffer)); - return; - } -} - - -/** - * New in GL 3.0 - * Clear fixed-pt or float color buffer or depth buffer (not stencil). - */ -void GLAPIENTRY -_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) -{ - GET_CURRENT_CONTEXT(ctx); - - FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); - - if (ctx->NewState) { - _mesa_update_state( ctx ); - } - - switch (buffer) { - case GL_DEPTH: - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "ClearBuffer generates an INVALID VALUE error if buffer is - * COLOR and drawbuffer is less than zero, or greater than the - * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, - * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", - drawbuffer); - return; - } - else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) { - /* Save current depth clear value, set to 'value', do the - * depth clear and restore the clear value. - * XXX in the future we may have a new ctx->Driver.ClearBuffer() - * hook instead. - */ - const GLclampd clearSave = ctx->Depth.Clear; - ctx->Depth.Clear = *value; - ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); - ctx->Depth.Clear = clearSave; - } - /* clear depth buffer to value */ - break; - case GL_COLOR: - { - const GLbitfield mask = make_color_buffer_mask(ctx, drawbuffer); - if (mask == INVALID_MASK) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", - drawbuffer); - return; - } - else if (mask && !ctx->RasterDiscard) { - union gl_color_union clearSave; - - /* save color */ - clearSave = ctx->Color.ClearColor; - /* set color */ - COPY_4V(ctx->Color.ClearColor.f, value); - /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); - /* restore color */ - ctx->Color.ClearColor = clearSave; - } - } - break; - case GL_STENCIL: - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "The result of ClearBuffer is undefined if no conversion between - * the type of the specified value and the type of the buffer being - * cleared is defined (for example, if ClearBufferiv is called for a - * fixed- or floating-point buffer, or if ClearBufferfv is called - * for a signed or unsigned integer buffer). This is not an error." - * - * In this case we take "undefined" and "not an error" to mean "ignore." - * Note that we still need to generate an error for the invalid - * drawbuffer case (see the GL_DEPTH case above). - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfv(drawbuffer=%d)", - drawbuffer); - return; - } - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", - _mesa_lookup_enum_by_nr(buffer)); - return; - } -} - - -/** - * New in GL 3.0 - * Clear depth/stencil buffer only. - */ -void GLAPIENTRY -_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, - GLfloat depth, GLint stencil) -{ - GET_CURRENT_CONTEXT(ctx); - GLbitfield mask = 0; - - FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); - - if (buffer != GL_DEPTH_STENCIL) { - _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", - _mesa_lookup_enum_by_nr(buffer)); - return; - } - - /* Page 264 (page 280 of the PDF) of the OpenGL 3.0 spec says: - * - * "ClearBuffer generates an INVALID VALUE error if buffer is - * COLOR and drawbuffer is less than zero, or greater than the - * value of MAX DRAW BUFFERS minus one; or if buffer is DEPTH, - * STENCIL, or DEPTH STENCIL and drawbuffer is not zero." - */ - if (drawbuffer != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClearBufferfi(drawbuffer=%d)", - drawbuffer); - return; - } - - if (ctx->RasterDiscard) - return; - - if (ctx->NewState) { - _mesa_update_state( ctx ); - } - - if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer) - mask |= BUFFER_BIT_DEPTH; - if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer) - mask |= BUFFER_BIT_STENCIL; - - if (mask) { - /* save current clear values */ - const GLclampd clearDepthSave = ctx->Depth.Clear; - const GLuint clearStencilSave = ctx->Stencil.Clear; - - /* set new clear values */ - ctx->Depth.Clear = depth; - ctx->Stencil.Clear = stencil; - - /* clear buffers */ - ctx->Driver.Clear(ctx, mask); - - /* restore */ - ctx->Depth.Clear = clearDepthSave; - ctx->Stencil.Clear = clearStencilSave; - } -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/main/context.c.bak b/contrib/sdk/sources/Mesa/src/mesa/main/context.c.bak deleted file mode 100644 index 9ec7c66b67..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/main/context.c.bak +++ /dev/null @@ -1,1863 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file context.c - * Mesa context/visual/framebuffer management functions. - * \author Brian Paul - */ - -/** - * \mainpage Mesa Main Module - * - * \section MainIntroduction Introduction - * - * The Mesa Main module consists of all the files in the main/ directory. - * Among the features of this module are: - *
    - *
  • Structures to represent most GL state
  • - *
  • State set/get functions
  • - *
  • Display lists
  • - *
  • Texture unit, object and image handling
  • - *
  • Matrix and attribute stacks
  • - *
- * - * Other modules are responsible for API dispatch, vertex transformation, - * point/line/triangle setup, rasterization, vertex array caching, - * vertex/fragment programs/shaders, etc. - * - * - * \section AboutDoxygen About Doxygen - * - * If you're viewing this information as Doxygen-generated HTML you'll - * see the documentation index at the top of this page. - * - * The first line lists the Mesa source code modules. - * The second line lists the indexes available for viewing the documentation - * for each module. - * - * Selecting the Main page link will display a summary of the module - * (this page). - * - * Selecting Data Structures will list all C structures. - * - * Selecting the File List link will list all the source files in - * the module. - * Selecting a filename will show a list of all functions defined in that file. - * - * Selecting the Data Fields link will display a list of all - * documented structure members. - * - * Selecting the Globals link will display a list - * of all functions, structures, global variables and macros in the module. - * - */ - - -#include "glheader.h" -#include "imports.h" -#include "accum.h" -#include "api_exec.h" -#include "api_loopback.h" -#include "arrayobj.h" -#include "attrib.h" -#include "blend.h" -#include "buffers.h" -#include "bufferobj.h" -#include "context.h" -#include "cpuinfo.h" -#include "debug.h" -#include "depth.h" -#include "dlist.h" -#include "eval.h" -#include "extensions.h" -#include "fbobject.h" -#include "feedback.h" -#include "fog.h" -#include "formats.h" -#include "framebuffer.h" -#include "hint.h" -#include "hash.h" -#include "light.h" -#include "lines.h" -#include "macros.h" -#include "matrix.h" -#include "multisample.h" -#include "pixel.h" -#include "pixelstore.h" -#include "points.h" -#include "polygon.h" -#include "queryobj.h" -#include "syncobj.h" -#include "rastpos.h" -#include "remap.h" -#include "scissor.h" -#include "shared.h" -#include "shaderobj.h" -#include "simple_list.h" -#include "state.h" -#include "stencil.h" -#include "texcompress_s3tc.h" -#include "texstate.h" -#include "transformfeedback.h" -#include "mtypes.h" -#include "varray.h" -#include "version.h" -#include "viewport.h" -#include "vtxfmt.h" -#include "program/program.h" -#include "program/prog_print.h" -#include "math/m_matrix.h" -#include "main/dispatch.h" /* for _gloffset_COUNT */ - -#ifdef USE_SPARC_ASM -#include "sparc/sparc.h" -#endif - -#include "glsl_parser_extras.h" -#include - - -#ifndef MESA_VERBOSE -int MESA_VERBOSE = (VERBOSE_API|VERBOSE_DRIVER|VERBOSE_STATE|VERBOSE_DRAW); -#endif - -#ifndef MESA_DEBUG_FLAGS -int MESA_DEBUG_FLAGS = 0; -#endif - - -/* ubyte -> float conversion */ -GLfloat _mesa_ubyte_to_float_color_tab[256]; - - - -/** - * Swap buffers notification callback. - * - * \param ctx GL context. - * - * Called by window system just before swapping buffers. - * We have to finish any pending rendering. - */ -void -_mesa_notifySwapBuffers(struct gl_context *ctx) -{ - if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS) - _mesa_debug(ctx, "SwapBuffers\n"); - FLUSH_CURRENT( ctx, 0 ); - if (ctx->Driver.Flush) { - ctx->Driver.Flush(ctx); - } -} - - -/**********************************************************************/ -/** \name GL Visual allocation/destruction */ -/**********************************************************************/ -/*@{*/ - -/** - * Allocates a struct gl_config structure and initializes it via - * _mesa_initialize_visual(). - * - * \param dbFlag double buffering - * \param stereoFlag stereo buffer - * \param depthBits requested bits per depth buffer value. Any value in [0, 32] - * is acceptable but the actual depth type will be GLushort or GLuint as - * needed. - * \param stencilBits requested minimum bits per stencil buffer value - * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number - * of bits per color component in accum buffer. - * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE - * \param redBits number of bits per color component in frame buffer for RGB(A) - * mode. We always use 8 in core Mesa though. - * \param greenBits same as above. - * \param blueBits same as above. - * \param alphaBits same as above. - * \param numSamples not really used. - * - * \return pointer to new struct gl_config or NULL if requested parameters - * can't be met. - * - * \note Need to add params for level and numAuxBuffers (at least) - */ -struct gl_config * -_mesa_create_visual( GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLint numSamples ) -{ - struct gl_config *vis = CALLOC_STRUCT(gl_config); - if (vis) { - if (!_mesa_initialize_visual(vis, dbFlag, stereoFlag, - redBits, greenBits, blueBits, alphaBits, - depthBits, stencilBits, - accumRedBits, accumGreenBits, - accumBlueBits, accumAlphaBits, - numSamples)) { - free(vis); - return NULL; - } - } - return vis; -} - - -/** - * Makes some sanity checks and fills in the fields of the struct - * gl_config object with the given parameters. If the caller needs to - * set additional fields, he should just probably init the whole - * gl_config object himself. - * - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \sa _mesa_create_visual() above for the parameter description. - */ -GLboolean -_mesa_initialize_visual( struct gl_config *vis, - GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLint numSamples ) -{ - assert(vis); - - if (depthBits < 0 || depthBits > 32) { - return GL_FALSE; - } - if (stencilBits < 0 || stencilBits > 8) { - return GL_FALSE; - } - assert(accumRedBits >= 0); - assert(accumGreenBits >= 0); - assert(accumBlueBits >= 0); - assert(accumAlphaBits >= 0); - - vis->rgbMode = GL_TRUE; - vis->doubleBufferMode = dbFlag; - vis->stereoMode = stereoFlag; - - vis->redBits = redBits; - vis->greenBits = greenBits; - vis->blueBits = blueBits; - vis->alphaBits = alphaBits; - vis->rgbBits = redBits + greenBits + blueBits; - - vis->indexBits = 0; - vis->depthBits = depthBits; - vis->stencilBits = stencilBits; - - vis->accumRedBits = accumRedBits; - vis->accumGreenBits = accumGreenBits; - vis->accumBlueBits = accumBlueBits; - vis->accumAlphaBits = accumAlphaBits; - - vis->haveAccumBuffer = accumRedBits > 0; - vis->haveDepthBuffer = depthBits > 0; - vis->haveStencilBuffer = stencilBits > 0; - - vis->numAuxBuffers = 0; - vis->level = 0; - vis->sampleBuffers = numSamples > 0 ? 1 : 0; - vis->samples = numSamples; - - return GL_TRUE; -} - - -/** - * Destroy a visual and free its memory. - * - * \param vis visual. - * - * Frees the visual structure. - */ -void -_mesa_destroy_visual( struct gl_config *vis ) -{ - free(vis); -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Context allocation, initialization, destroying - * - * The purpose of the most initialization functions here is to provide the - * default state values according to the OpenGL specification. - */ -/**********************************************************************/ -/*@{*/ - - -/** - * This is lame. gdb only seems to recognize enum types that are - * actually used somewhere. We want to be able to print/use enum - * values such as TEXTURE_2D_INDEX in gdb. But we don't actually use - * the gl_texture_index type anywhere. Thus, this lame function. - */ -static void -dummy_enum_func(void) -{ - gl_buffer_index bi = BUFFER_FRONT_LEFT; - gl_face_index fi = FACE_POS_X; - gl_frag_result fr = FRAG_RESULT_DEPTH; - gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX; - gl_vert_attrib va = VERT_ATTRIB_POS; - gl_varying_slot vs = VARYING_SLOT_POS; - - (void) bi; - (void) fi; - (void) fr; - (void) ti; - (void) va; - (void) vs; -} - - -/** - * One-time initialization mutex lock. - * - * \sa Used by one_time_init(). - */ -_glthread_DECLARE_STATIC_MUTEX(OneTimeLock); - - - -/** - * Calls all the various one-time-init functions in Mesa. - * - * While holding a global mutex lock, calls several initialization functions, - * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is - * defined. - * - * \sa _math_init(). - */ -static void -one_time_init( struct gl_context *ctx ) -{ - static GLbitfield api_init_mask = 0x0; - - _glthread_LOCK_MUTEX(OneTimeLock); - - /* truly one-time init */ - if (!api_init_mask) { - GLuint i; - - /* do some implementation tests */ - assert( sizeof(GLbyte) == 1 ); - assert( sizeof(GLubyte) == 1 ); - assert( sizeof(GLshort) == 2 ); - assert( sizeof(GLushort) == 2 ); - assert( sizeof(GLint) == 4 ); - assert( sizeof(GLuint) == 4 ); - - _mesa_get_cpu_features(); - - for (i = 0; i < 256; i++) { - _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; - } - -#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) - if (MESA_VERBOSE != 0) { - _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", - PACKAGE_VERSION, __DATE__, __TIME__); - } -#endif - -#ifdef DEBUG - _mesa_test_formats(); -#endif - } - - /* per-API one-time init */ - if (!(api_init_mask & (1 << ctx->API))) { - _mesa_init_get_hash(ctx); - - _mesa_init_remap_table(); - } - - api_init_mask |= 1 << ctx->API; - - _glthread_UNLOCK_MUTEX(OneTimeLock); - - /* Hopefully atexit() is widely available. If not, we may need some - * #ifdef tests here. - */ - atexit(_mesa_destroy_shader_compiler); - - dummy_enum_func(); -} - - -/** - * Initialize fields of gl_current_attrib (aka ctx->Current.*) - */ -static void -_mesa_init_current(struct gl_context *ctx) -{ - GLuint i; - - /* Init all to (0,0,0,1) */ - for (i = 0; i < Elements(ctx->Current.Attrib); i++) { - ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 ); - } - - /* redo special cases: */ - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX], 1.0, 0.0, 0.0, 1.0 ); - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG], 1.0, 0.0, 0.0, 1.0 ); -} - - -/** - * Init vertex/fragment/geometry program limits. - * Important: drivers should override these with actual limits. - */ -static void -init_program_limits(struct gl_context *ctx, GLenum type, - struct gl_program_constants *prog) -{ - prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; - prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS; - prog->MaxTexInstructions = MAX_PROGRAM_INSTRUCTIONS; - prog->MaxTexIndirections = MAX_PROGRAM_INSTRUCTIONS; - prog->MaxTemps = MAX_PROGRAM_TEMPS; - prog->MaxEnvParams = MAX_PROGRAM_ENV_PARAMS; - prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; - prog->MaxAddressOffset = MAX_PROGRAM_LOCAL_PARAMS; - - switch (type) { - case GL_VERTEX_PROGRAM_ARB: - prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; - prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; - prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - prog->MaxUniformComponents = 4 * MAX_UNIFORMS; - break; - case GL_FRAGMENT_PROGRAM_ARB: - prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; - prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; - prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; - prog->MaxUniformComponents = 4 * MAX_UNIFORMS; - break; - case MESA_GEOMETRY_PROGRAM: - prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; - prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; - prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - prog->MaxUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS; - break; - default: - assert(0 && "Bad program type in init_program_limits()"); - } - - /* Set the native limits to zero. This implies that there is no native - * support for shaders. Let the drivers fill in the actual values. - */ - prog->MaxNativeInstructions = 0; - prog->MaxNativeAluInstructions = 0; - prog->MaxNativeTexInstructions = 0; - prog->MaxNativeTexIndirections = 0; - prog->MaxNativeAttribs = 0; - prog->MaxNativeTemps = 0; - prog->MaxNativeAddressRegs = 0; - prog->MaxNativeParameters = 0; - - /* Set GLSL datatype range/precision info assuming IEEE float values. - * Drivers should override these defaults as needed. - */ - prog->MediumFloat.RangeMin = 127; - prog->MediumFloat.RangeMax = 127; - prog->MediumFloat.Precision = 23; - prog->LowFloat = prog->HighFloat = prog->MediumFloat; - - /* Assume ints are stored as floats for now, since this is the least-common - * denominator. The OpenGL ES spec implies (page 132) that the precision - * of integer types should be 0. Practically speaking, IEEE - * single-precision floating point values can only store integers in the - * range [-0x01000000, 0x01000000] without loss of precision. - */ - prog->MediumInt.RangeMin = 24; - prog->MediumInt.RangeMax = 24; - prog->MediumInt.Precision = 0; - prog->LowInt = prog->HighInt = prog->MediumInt; - - prog->MaxUniformBlocks = 12; - prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents + - ctx->Const.MaxUniformBlockSize / 4 * - prog->MaxUniformBlocks); -} - - -/** - * Initialize fields of gl_constants (aka ctx->Const.*). - * Use defaults from config.h. The device drivers will often override - * some of these values (such as number of texture units). - */ -static void -_mesa_init_constants(struct gl_context *ctx) -{ - assert(ctx); - - /* Constants, may be overriden (usually only reduced) by device drivers */ - ctx->Const.MaxTextureMbytes = MAX_TEXTURE_MBYTES; - ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; - ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; - ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; - ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; - ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; - ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; - ctx->Const.FragmentProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, - ctx->Const.FragmentProgram.MaxTextureImageUnits); - ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; - ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; - ctx->Const.MaxTextureBufferSize = 65536; - ctx->Const.TextureBufferOffsetAlignment = 1; - ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; - ctx->Const.SubPixelBits = SUB_PIXEL_BITS; - ctx->Const.MinPointSize = MIN_POINT_SIZE; - ctx->Const.MaxPointSize = MAX_POINT_SIZE; - ctx->Const.MinPointSizeAA = MIN_POINT_SIZE; - ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE; - ctx->Const.PointSizeGranularity = (GLfloat) POINT_SIZE_GRANULARITY; - ctx->Const.MinLineWidth = MIN_LINE_WIDTH; - ctx->Const.MaxLineWidth = MAX_LINE_WIDTH; - ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; - ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; - ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; - ctx->Const.MaxClipPlanes = 6; - ctx->Const.MaxLights = MAX_LIGHTS; - ctx->Const.MaxShininess = 128.0; - ctx->Const.MaxSpotExponent = 128.0; - ctx->Const.MaxViewportWidth = MAX_VIEWPORT_WIDTH; - ctx->Const.MaxViewportHeight = MAX_VIEWPORT_HEIGHT; - - /** GL_ARB_uniform_buffer_object */ - ctx->Const.MaxCombinedUniformBlocks = 36; - ctx->Const.MaxUniformBufferBindings = 36; - ctx->Const.MaxUniformBlockSize = 16384; - ctx->Const.UniformBufferOffsetAlignment = 1; - - init_program_limits(ctx, GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); - init_program_limits(ctx, GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); - init_program_limits(ctx, MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram); - - ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; - ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; - - /* CheckArrayBounds is overriden by drivers/x11 for X server */ - ctx->Const.CheckArrayBounds = GL_FALSE; - - /* GL_ARB_draw_buffers */ - ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS; - - ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS; - ctx->Const.MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE; - - ctx->Const.VertexProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxVarying = 16; /* old limit not to break tnl and swrast */ - ctx->Const.GeometryProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; - ctx->Const.MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; - - /* Shading language version */ - if (_mesa_is_desktop_gl(ctx)) { - ctx->Const.GLSLVersion = 120; - _mesa_override_glsl_version(ctx); - } - else if (ctx->API == API_OPENGLES2) { - ctx->Const.GLSLVersion = 100; - } - else if (ctx->API == API_OPENGLES) { - ctx->Const.GLSLVersion = 0; /* GLSL not supported */ - } - - /* GL_ARB_framebuffer_object */ - ctx->Const.MaxSamples = 0; - - /* GL_ARB_sync */ - ctx->Const.MaxServerWaitTimeout = 0x1fff7fffffffULL; - - /* GL_ATI_envmap_bumpmap */ - ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS; - - /* GL_EXT_provoking_vertex */ - ctx->Const.QuadsFollowProvokingVertexConvention = GL_TRUE; - - /* GL_EXT_transform_feedback */ - ctx->Const.MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS; - ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS; - ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS; - ctx->Const.MaxVertexStreams = 1; - - /* GL 3.2 */ - ctx->Const.ProfileMask = ctx->API == API_OPENGL_CORE - ? GL_CONTEXT_CORE_PROFILE_BIT - : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; - - /** GL_EXT_gpu_shader4 */ - ctx->Const.MinProgramTexelOffset = -8; - ctx->Const.MaxProgramTexelOffset = 7; - - /* GL_ARB_robustness */ - ctx->Const.ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB; - - /* PrimitiveRestart */ - ctx->Const.PrimitiveRestartInSoftware = GL_FALSE; - - /* ES 3.0 or ARB_ES3_compatibility */ - ctx->Const.MaxElementIndex = 0xffffffffu; - - /* GL_ARB_texture_multisample */ - ctx->Const.MaxColorTextureSamples = 1; - ctx->Const.MaxDepthTextureSamples = 1; - ctx->Const.MaxIntegerSamples = 1; -} - - -/** - * Do some sanity checks on the limits/constants for the given context. - * Only called the first time a context is bound. - */ -static void -check_context_limits(struct gl_context *ctx) -{ - /* check that we don't exceed the size of various bitfields */ - assert(VARYING_SLOT_MAX <= - (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten))); - assert(VARYING_SLOT_MAX <= - (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead))); - - /* shader-related checks */ - assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); - assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); - - /* Texture unit checks */ - assert(ctx->Const.FragmentProgram.MaxTextureImageUnits > 0); - assert(ctx->Const.FragmentProgram.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); - assert(ctx->Const.MaxTextureCoordUnits > 0); - assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); - assert(ctx->Const.MaxTextureUnits > 0); - assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); - assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); - assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.FragmentProgram.MaxTextureImageUnits, - ctx->Const.MaxTextureCoordUnits)); - assert(ctx->Const.MaxCombinedTextureImageUnits > 0); - assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); - assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); - /* number of coord units cannot be greater than number of image units */ - assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.FragmentProgram.MaxTextureImageUnits); - - - /* Texture size checks */ - assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS); - assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS); - assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS); - assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE); - - /* Texture level checks */ - assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); - assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); - - /* Max texture size should be <= max viewport size (render to texture) */ - assert((1U << (ctx->Const.MaxTextureLevels - 1)) - <= ctx->Const.MaxViewportWidth); - assert((1U << (ctx->Const.MaxTextureLevels - 1)) - <= ctx->Const.MaxViewportHeight); - - assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); - - /* if this fails, add more enum values to gl_buffer_index */ - assert(BUFFER_COLOR0 + MAX_DRAW_BUFFERS <= BUFFER_COUNT); - - /* XXX probably add more tests */ -} - - -/** - * Initialize the attribute groups in a GL context. - * - * \param ctx GL context. - * - * Initializes all the attributes, calling the respective init* - * functions for the more complex data structures. - */ -static GLboolean -init_attrib_groups(struct gl_context *ctx) -{ - assert(ctx); - - /* Constants */ - _mesa_init_constants( ctx ); - - /* Extensions */ - _mesa_init_extensions( ctx ); - - /* Attribute Groups */ - _mesa_init_accum( ctx ); - _mesa_init_attrib( ctx ); - _mesa_init_buffer_objects( ctx ); - _mesa_init_color( ctx ); - _mesa_init_current( ctx ); - _mesa_init_depth( ctx ); - _mesa_init_debug( ctx ); - _mesa_init_display_list( ctx ); - _mesa_init_errors( ctx ); - _mesa_init_eval( ctx ); - _mesa_init_fbobjects( ctx ); - _mesa_init_feedback( ctx ); - _mesa_init_fog( ctx ); - _mesa_init_hint( ctx ); - _mesa_init_line( ctx ); - _mesa_init_lighting( ctx ); - _mesa_init_matrix( ctx ); - _mesa_init_multisample( ctx ); - _mesa_init_pixel( ctx ); - _mesa_init_pixelstore( ctx ); - _mesa_init_point( ctx ); - _mesa_init_polygon( ctx ); - _mesa_init_program( ctx ); - _mesa_init_queryobj( ctx ); - _mesa_init_sync( ctx ); - _mesa_init_rastpos( ctx ); - _mesa_init_scissor( ctx ); - _mesa_init_shader_state( ctx ); - _mesa_init_stencil( ctx ); - _mesa_init_transform( ctx ); - _mesa_init_transform_feedback( ctx ); - _mesa_init_varray( ctx ); - _mesa_init_viewport( ctx ); - - if (!_mesa_init_texture( ctx )) - return GL_FALSE; - - _mesa_init_texture_s3tc( ctx ); - - /* Miscellaneous */ - ctx->NewState = _NEW_ALL; - ctx->NewDriverState = ~0; - ctx->ErrorValue = GL_NO_ERROR; - ctx->ResetStatus = GL_NO_ERROR; - ctx->varying_vp_inputs = VERT_BIT_ALL; - - return GL_TRUE; -} - - -/** - * Update default objects in a GL context with respect to shared state. - * - * \param ctx GL context. - * - * Removes references to old default objects, (texture objects, program - * objects, etc.) and changes to reference those from the current shared - * state. - */ -static GLboolean -update_default_objects(struct gl_context *ctx) -{ - assert(ctx); - - _mesa_update_default_objects_program(ctx); - _mesa_update_default_objects_texture(ctx); - _mesa_update_default_objects_buffer_objects(ctx); - - return GL_TRUE; -} - - -/** - * This is the default function we plug into all dispatch table slots - * This helps prevents a segfault when someone calls a GL function without - * first checking if the extension's supported. - */ -int -_mesa_generic_nop(void) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, - "unsupported function called " - "(unsupported extension or deprecated function?)"); - return 0; -} - - -/** - * Allocate and initialize a new dispatch table. - */ -struct _glapi_table * -_mesa_alloc_dispatch_table() -{ - /* Find the larger of Mesa's dispatch table and libGL's dispatch table. - * In practice, this'll be the same for stand-alone Mesa. But for DRI - * Mesa we do this to accomodate different versions of libGL and various - * DRI drivers. - */ - GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); - struct _glapi_table *table; - - table = malloc(numEntries * sizeof(_glapi_proc)); - if (table) { - _glapi_proc *entry = (_glapi_proc *) table; - GLint i; - for (i = 0; i < numEntries; i++) { - entry[i] = (_glapi_proc) _mesa_generic_nop; - } - } - return table; -} - -/** - * Creates a minimal dispatch table for use within glBegin()/glEnd(). - * - * This ensures that we generate GL_INVALID_OPERATION errors from most - * functions, since the set of functions that are valid within Begin/End is - * very small. - * - * From the GL 1.0 specification section 2.6.3, "GL Commands within - * Begin/End" - * - * "The only GL commands that are allowed within any Begin/End pairs are - * the commands for specifying vertex coordinates, vertex color, normal - * coordinates, and texture coordinates (Vertex, Color, Index, Normal, - * TexCoord), EvalCoord and EvalPoint commands (see section 5.1), - * commands for specifying lighting material parameters (Material - * commands see section 2.12.2), display list invocation commands - * (CallList and CallLists see section 5.4), and the EdgeFlag - * command. Executing Begin after Begin has already been executed but - * before an End is issued generates the INVALID OPERATION error, as does - * executing End without a previous corresponding Begin. Executing any - * other GL command within Begin/End results in the error INVALID - * OPERATION." - * - * The table entries for specifying vertex attributes are set up by - * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists - * are set by install_vtxfmt() as well. - */ -static struct _glapi_table * -create_beginend_table(const struct gl_context *ctx) -{ - struct _glapi_table *table; - - table = _mesa_alloc_dispatch_table(); - if (!table) - return NULL; - - /* Fill in functions which return a value, since they should return some - * specific value even if they emit a GL_INVALID_OPERATION error from them - * being called within glBegin()/glEnd(). - */ -#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec)) - - COPY_DISPATCH(GenLists); - COPY_DISPATCH(IsProgram); - COPY_DISPATCH(IsVertexArray); - COPY_DISPATCH(IsBuffer); - COPY_DISPATCH(IsEnabled); - COPY_DISPATCH(IsEnabledi); - COPY_DISPATCH(IsRenderbuffer); - COPY_DISPATCH(IsFramebuffer); - COPY_DISPATCH(CheckFramebufferStatus); - COPY_DISPATCH(RenderMode); - COPY_DISPATCH(GetString); - COPY_DISPATCH(GetStringi); - COPY_DISPATCH(GetPointerv); - COPY_DISPATCH(IsQuery); - COPY_DISPATCH(IsSampler); - COPY_DISPATCH(IsSync); - COPY_DISPATCH(IsTexture); - COPY_DISPATCH(IsTransformFeedback); - COPY_DISPATCH(DeleteQueries); - COPY_DISPATCH(AreTexturesResident); - COPY_DISPATCH(FenceSync); - COPY_DISPATCH(ClientWaitSync); - COPY_DISPATCH(MapBuffer); - COPY_DISPATCH(UnmapBuffer); - COPY_DISPATCH(MapBufferRange); - COPY_DISPATCH(ObjectPurgeableAPPLE); - COPY_DISPATCH(ObjectUnpurgeableAPPLE); - - _mesa_loopback_init_api_table(ctx, table); - - return table; -} - -void -_mesa_initialize_dispatch_tables(struct gl_context *ctx) -{ - /* Do the code-generated setup of the exec table in api_exec.c. */ - _mesa_initialize_exec_table(ctx); - - if (ctx->Save) - _mesa_initialize_save_table(ctx); -} - -/** - * Initialize a struct gl_context struct (rendering context). - * - * This includes allocating all the other structs and arrays which hang off of - * the context by pointers. - * Note that the driver needs to pass in its dd_function_table here since - * we need to at least call driverFunctions->NewTextureObject to create the - * default texture objects. - * - * Called by _mesa_create_context(). - * - * Performs the imports and exports callback tables initialization, and - * miscellaneous one-time initializations. If no shared context is supplied one - * is allocated, and increase its reference count. Setups the GL API dispatch - * tables. Initialize the TNL module. Sets the maximum Z buffer depth. - * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables - * for debug flags. - * - * \param ctx the context to initialize - * \param api the GL API type to create the context for - * \param visual describes the visual attributes for this context - * \param share_list points to context to share textures, display lists, - * etc with, or NULL - * \param driverFunctions table of device driver functions for this context - * to use - */ -GLboolean -_mesa_initialize_context(struct gl_context *ctx, - gl_api api, - const struct gl_config *visual, - struct gl_context *share_list, - const struct dd_function_table *driverFunctions) -{ - struct gl_shared_state *shared; - int i; - - assert(driverFunctions->NewTextureObject); - assert(driverFunctions->FreeTextureImageBuffer); - - ctx->API = api; - ctx->Visual = *visual; - ctx->DrawBuffer = NULL; - ctx->ReadBuffer = NULL; - ctx->WinSysDrawBuffer = NULL; - ctx->WinSysReadBuffer = NULL; - - if (_mesa_is_desktop_gl(ctx)) { - _mesa_override_gl_version(ctx); - } - - /* misc one-time initializations */ - one_time_init(ctx); - - /* Plug in driver functions and context pointer here. - * This is important because when we call alloc_shared_state() below - * we'll call ctx->Driver.NewTextureObject() to create the default - * textures. - */ - ctx->Driver = *driverFunctions; - - if (share_list) { - /* share state with another context */ - shared = share_list->Shared; - } - else { - /* allocate new, unshared state */ - shared = _mesa_alloc_shared_state(ctx); - if (!shared) - return GL_FALSE; - } - - _mesa_reference_shared_state(ctx, &ctx->Shared, shared); - - if (!init_attrib_groups( ctx )) - goto fail; - - /* setup the API dispatch tables with all nop functions */ - ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table(); - if (!ctx->OutsideBeginEnd) - goto fail; - ctx->Exec = ctx->OutsideBeginEnd; - ctx->CurrentDispatch = ctx->OutsideBeginEnd; - - ctx->FragmentProgram._MaintainTexEnvProgram - = (_mesa_getenv("MESA_TEX_PROG") != NULL); - - ctx->VertexProgram._MaintainTnlProgram - = (_mesa_getenv("MESA_TNL_PROG") != NULL); - if (ctx->VertexProgram._MaintainTnlProgram) { - /* this is required... */ - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - } - - /* Mesa core handles all the formats that mesa core knows about. - * Drivers will want to override this list with just the formats - * they can handle, and confirm that appropriate fallbacks exist in - * _mesa_choose_tex_format(). - */ - memset(&ctx->TextureFormatSupported, GL_TRUE, - sizeof(ctx->TextureFormatSupported)); - - switch (ctx->API) { - case API_OPENGL_COMPAT: - ctx->BeginEnd = create_beginend_table(ctx); - ctx->Save = _mesa_alloc_dispatch_table(); - if (!ctx->BeginEnd || !ctx->Save) - goto fail; - - /* fall-through */ - case API_OPENGL_CORE: - break; - case API_OPENGLES: - /** - * GL_OES_texture_cube_map says - * "Initially all texture generation modes are set to REFLECTION_MAP_OES" - */ - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; - texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; - } - break; - case API_OPENGLES2: - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - break; - } - - ctx->FirstTimeCurrent = GL_TRUE; - - return GL_TRUE; - -fail: - _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - free(ctx->BeginEnd); - free(ctx->Exec); - free(ctx->Save); - return GL_FALSE; -} - - -/** - * Allocate and initialize a struct gl_context structure. - * Note that the driver needs to pass in its dd_function_table here since - * we need to at least call driverFunctions->NewTextureObject to initialize - * the rendering context. - * - * \param api the GL API type to create the context for - * \param visual a struct gl_config pointer (we copy the struct contents) - * \param share_list another context to share display lists with or NULL - * \param driverFunctions points to the dd_function_table into which the - * driver has plugged in all its special functions. - * - * \return pointer to a new __struct gl_contextRec or NULL if error. - */ -struct gl_context * -_mesa_create_context(gl_api api, - const struct gl_config *visual, - struct gl_context *share_list, - const struct dd_function_table *driverFunctions) -{ - struct gl_context *ctx; - - ASSERT(visual); - - ctx = calloc(1, sizeof(struct gl_context)); - if (!ctx) - return NULL; - - if (_mesa_initialize_context(ctx, api, visual, share_list, - driverFunctions)) { - return ctx; - } - else { - free(ctx); - return NULL; - } -} - - -/** - * Free the data associated with the given context. - * - * But doesn't free the struct gl_context struct itself. - * - * \sa _mesa_initialize_context() and init_attrib_groups(). - */ -void -_mesa_free_context_data( struct gl_context *ctx ) -{ - if (!_mesa_get_current_context()){ - /* No current context, but we may need one in order to delete - * texture objs, etc. So temporarily bind the context now. - */ - _mesa_make_current(ctx, NULL, NULL); - } - - /* unreference WinSysDraw/Read buffers */ - _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL); - _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL); - _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); - _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL); - - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); - - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); - - _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, NULL); - _mesa_reference_array_object(ctx, &ctx->Array.DefaultArrayObj, NULL); - - _mesa_free_attrib_data(ctx); - _mesa_free_buffer_objects(ctx); - _mesa_free_lighting_data( ctx ); - _mesa_free_eval_data( ctx ); - _mesa_free_texture_data( ctx ); - _mesa_free_matrix_data( ctx ); - _mesa_free_viewport_data( ctx ); - _mesa_free_program_data(ctx); - _mesa_free_shader_state(ctx); - _mesa_free_queryobj_data(ctx); - _mesa_free_sync_data(ctx); - _mesa_free_varray_data(ctx); - _mesa_free_transform_feedback(ctx); - - _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL); - _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); - - /* free dispatch tables */ - free(ctx->BeginEnd); - free(ctx->Exec); - free(ctx->Save); - - /* Shared context state (display lists, textures, etc) */ - _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - - /* needs to be after freeing shared state */ - _mesa_free_display_list_data(ctx); - - _mesa_free_errors_data(ctx); - - free((void *)ctx->Extensions.String); - - free(ctx->VersionString); - - /* unbind the context if it's currently bound */ - if (ctx == _mesa_get_current_context()) { - _mesa_make_current(NULL, NULL, NULL); - } -} - - -/** - * Destroy a struct gl_context structure. - * - * \param ctx GL context. - * - * Calls _mesa_free_context_data() and frees the gl_context object itself. - */ -void -_mesa_destroy_context( struct gl_context *ctx ) -{ - if (ctx) { - _mesa_free_context_data(ctx); - free( (void *) ctx ); - } -} - - -/** - * Copy attribute groups from one context to another. - * - * \param src source context - * \param dst destination context - * \param mask bitwise OR of GL_*_BIT flags - * - * According to the bits specified in \p mask, copies the corresponding - * attributes from \p src into \p dst. For many of the attributes a simple \c - * memcpy is not enough due to the existence of internal pointers in their data - * structures. - */ -void -_mesa_copy_context( const struct gl_context *src, struct gl_context *dst, - GLuint mask ) -{ - if (mask & GL_ACCUM_BUFFER_BIT) { - /* OK to memcpy */ - dst->Accum = src->Accum; - } - if (mask & GL_COLOR_BUFFER_BIT) { - /* OK to memcpy */ - dst->Color = src->Color; - } - if (mask & GL_CURRENT_BIT) { - /* OK to memcpy */ - dst->Current = src->Current; - } - if (mask & GL_DEPTH_BUFFER_BIT) { - /* OK to memcpy */ - dst->Depth = src->Depth; - } - if (mask & GL_ENABLE_BIT) { - /* no op */ - } - if (mask & GL_EVAL_BIT) { - /* OK to memcpy */ - dst->Eval = src->Eval; - } - if (mask & GL_FOG_BIT) { - /* OK to memcpy */ - dst->Fog = src->Fog; - } - if (mask & GL_HINT_BIT) { - /* OK to memcpy */ - dst->Hint = src->Hint; - } - if (mask & GL_LIGHTING_BIT) { - GLuint i; - /* begin with memcpy */ - dst->Light = src->Light; - /* fixup linked lists to prevent pointer insanity */ - make_empty_list( &(dst->Light.EnabledList) ); - for (i = 0; i < MAX_LIGHTS; i++) { - if (dst->Light.Light[i].Enabled) { - insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i])); - } - } - } - if (mask & GL_LINE_BIT) { - /* OK to memcpy */ - dst->Line = src->Line; - } - if (mask & GL_LIST_BIT) { - /* OK to memcpy */ - dst->List = src->List; - } - if (mask & GL_PIXEL_MODE_BIT) { - /* OK to memcpy */ - dst->Pixel = src->Pixel; - } - if (mask & GL_POINT_BIT) { - /* OK to memcpy */ - dst->Point = src->Point; - } - if (mask & GL_POLYGON_BIT) { - /* OK to memcpy */ - dst->Polygon = src->Polygon; - } - if (mask & GL_POLYGON_STIPPLE_BIT) { - /* Use loop instead of memcpy due to problem with Portland Group's - * C compiler. Reported by John Stone. - */ - GLuint i; - for (i = 0; i < 32; i++) { - dst->PolygonStipple[i] = src->PolygonStipple[i]; - } - } - if (mask & GL_SCISSOR_BIT) { - /* OK to memcpy */ - dst->Scissor = src->Scissor; - } - if (mask & GL_STENCIL_BUFFER_BIT) { - /* OK to memcpy */ - dst->Stencil = src->Stencil; - } - if (mask & GL_TEXTURE_BIT) { - /* Cannot memcpy because of pointers */ - _mesa_copy_texture_state(src, dst); - } - if (mask & GL_TRANSFORM_BIT) { - /* OK to memcpy */ - dst->Transform = src->Transform; - } - if (mask & GL_VIEWPORT_BIT) { - /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ - dst->Viewport.X = src->Viewport.X; - dst->Viewport.Y = src->Viewport.Y; - dst->Viewport.Width = src->Viewport.Width; - dst->Viewport.Height = src->Viewport.Height; - dst->Viewport.Near = src->Viewport.Near; - dst->Viewport.Far = src->Viewport.Far; - _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap); - } - - /* XXX FIXME: Call callbacks? - */ - dst->NewState = _NEW_ALL; - dst->NewDriverState = ~0; -} - - -/** - * Check if the given context can render into the given framebuffer - * by checking visual attributes. - * - * Most of these tests could go away because Mesa is now pretty flexible - * in terms of mixing rendering contexts with framebuffers. As long - * as RGB vs. CI mode agree, we're probably good. - * - * \return GL_TRUE if compatible, GL_FALSE otherwise. - */ -static GLboolean -check_compatible(const struct gl_context *ctx, - const struct gl_framebuffer *buffer) -{ - const struct gl_config *ctxvis = &ctx->Visual; - const struct gl_config *bufvis = &buffer->Visual; - - if (buffer == _mesa_get_incomplete_framebuffer()) - return GL_TRUE; - -#if 0 - /* disabling this fixes the fgl_glxgears pbuffer demo */ - if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode) - return GL_FALSE; -#endif - if (ctxvis->stereoMode && !bufvis->stereoMode) - return GL_FALSE; - if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer) - return GL_FALSE; - if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer) - return GL_FALSE; - if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer) - return GL_FALSE; - if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask) - return GL_FALSE; - if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask) - return GL_FALSE; - if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask) - return GL_FALSE; -#if 0 - /* disabled (see bug 11161) */ - if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits) - return GL_FALSE; -#endif - if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Check if the viewport/scissor size has not yet been initialized. - * Initialize the size if the given width and height are non-zero. - */ -void -_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) -{ - if (!ctx->ViewportInitialized && width > 0 && height > 0) { - /* Note: set flag here, before calling _mesa_set_viewport(), to prevent - * potential infinite recursion. - */ - ctx->ViewportInitialized = GL_TRUE; - _mesa_set_viewport(ctx, 0, 0, width, height); - _mesa_set_scissor(ctx, 0, 0, width, height); - } -} - - -/** - * Bind the given context to the given drawBuffer and readBuffer and - * make it the current context for the calling thread. - * We'll render into the drawBuffer and read pixels from the - * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). - * - * We check that the context's and framebuffer's visuals are compatible - * and return immediately if they're not. - * - * \param newCtx the new GL context. If NULL then there will be no current GL - * context. - * \param drawBuffer the drawing framebuffer - * \param readBuffer the reading framebuffer - */ -GLboolean -_mesa_make_current( struct gl_context *newCtx, - struct gl_framebuffer *drawBuffer, - struct gl_framebuffer *readBuffer ) -{ - GET_CURRENT_CONTEXT(curCtx); - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(newCtx, "_mesa_make_current()\n"); - - /* Check that the context's and framebuffer's visuals are compatible. - */ - if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) { - if (!check_compatible(newCtx, drawBuffer)) { - _mesa_warning(newCtx, - "MakeCurrent: incompatible visuals for context and drawbuffer"); - return GL_FALSE; - } - } - if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) { - if (!check_compatible(newCtx, readBuffer)) { - _mesa_warning(newCtx, - "MakeCurrent: incompatible visuals for context and readbuffer"); - return GL_FALSE; - } - } - - if (curCtx && - (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && - /* make sure this context is valid for flushing */ - curCtx != newCtx) - _mesa_flush(curCtx); - - /* We used to call _glapi_check_multithread() here. Now do it in drivers */ - _glapi_set_context((void *) newCtx); - ASSERT(_mesa_get_current_context() == newCtx); - - if (!newCtx) { - _glapi_set_dispatch(NULL); /* none current */ - } - else { - _glapi_set_dispatch(newCtx->CurrentDispatch); - - if (drawBuffer && readBuffer) { - ASSERT(_mesa_is_winsys_fbo(drawBuffer)); - ASSERT(_mesa_is_winsys_fbo(readBuffer)); - _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer); - _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer); - - /* - * Only set the context's Draw/ReadBuffer fields if they're NULL - * or not bound to a user-created FBO. - */ - if (!newCtx->DrawBuffer || _mesa_is_winsys_fbo(newCtx->DrawBuffer)) { - _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); - /* Update the FBO's list of drawbuffers/renderbuffers. - * For winsys FBOs this comes from the GL state (which may have - * changed since the last time this FBO was bound). - */ - _mesa_update_draw_buffers(newCtx); - } - if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) { - _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); - } - - /* XXX only set this flag if we're really changing the draw/read - * framebuffer bindings. - */ - newCtx->NewState |= _NEW_BUFFERS; - - if (drawBuffer) { - _mesa_check_init_viewport(newCtx, - drawBuffer->Width, drawBuffer->Height); - } - } - - if (newCtx->FirstTimeCurrent) { - assert(newCtx->Version > 0); - - newCtx->Extensions.String = _mesa_make_extension_string(newCtx); - - check_context_limits(newCtx); - - /* We can use this to help debug user's problems. Tell them to set - * the MESA_INFO env variable before running their app. Then the - * first time each context is made current we'll print some useful - * information. - */ - if (_mesa_getenv("MESA_INFO")) { - _mesa_print_info(); - } - - newCtx->FirstTimeCurrent = GL_FALSE; - } - } - - return GL_TRUE; -} - - -/** - * Make context 'ctx' share the display lists, textures and programs - * that are associated with 'ctxToShare'. - * Any display lists, textures or programs associated with 'ctx' will - * be deleted if nobody else is sharing them. - */ -GLboolean -_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) -{ - if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { - struct gl_shared_state *oldShared = NULL; - - /* save ref to old state to prevent it from being deleted immediately */ - _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared); - - /* update ctx's Shared pointer */ - _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared); - - update_default_objects(ctx); - - /* release the old shared state */ - _mesa_reference_shared_state(ctx, &oldShared, NULL); - - return GL_TRUE; - } - else { - return GL_FALSE; - } -} - - - -/** - * \return pointer to the current GL context for this thread. - * - * Calls _glapi_get_context(). This isn't the fastest way to get the current - * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in - * context.h. - */ -struct gl_context * -_mesa_get_current_context( void ) -{ - return (struct gl_context *) _glapi_get_context(); -} - - -/** - * Get context's current API dispatch table. - * - * It'll either be the immediate-mode execute dispatcher or the display list - * compile dispatcher. - * - * \param ctx GL context. - * - * \return pointer to dispatch_table. - * - * Simply returns __struct gl_contextRec::CurrentDispatch. - */ -struct _glapi_table * -_mesa_get_dispatch(struct gl_context *ctx) -{ - return ctx->CurrentDispatch; -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Miscellaneous functions */ -/**********************************************************************/ -/*@{*/ - -/** - * Record an error. - * - * \param ctx GL context. - * \param error error code. - * - * Records the given error code and call the driver's dd_function_table::Error - * function if defined. - * - * \sa - * This is called via _mesa_error(). - */ -void -_mesa_record_error(struct gl_context *ctx, GLenum error) -{ - if (!ctx) - return; - - if (ctx->ErrorValue == GL_NO_ERROR) { - ctx->ErrorValue = error; - } -} - - -/** - * Flush commands and wait for completion. - */ -void -_mesa_finish(struct gl_context *ctx) -{ - FLUSH_VERTICES( ctx, 0 ); - FLUSH_CURRENT( ctx, 0 ); - if (ctx->Driver.Finish) { - ctx->Driver.Finish(ctx); - } -} - - -/** - * Flush commands. - */ -void -_mesa_flush(struct gl_context *ctx) -{ - FLUSH_VERTICES( ctx, 0 ); - FLUSH_CURRENT( ctx, 0 ); - if (ctx->Driver.Flush) { - ctx->Driver.Flush(ctx); - } -} - - - -/** - * Execute glFinish(). - * - * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the - * dd_function_table::Finish driver callback, if not NULL. - */ -void GLAPIENTRY -_mesa_Finish(void) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - _mesa_finish(ctx); -} - - -/** - * Execute glFlush(). - * - * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the - * dd_function_table::Flush driver callback, if not NULL. - */ -void GLAPIENTRY -_mesa_Flush(void) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - _mesa_flush(ctx); -} - - -/* - * ARB_blend_func_extended - ERRORS section - * "The error INVALID_OPERATION is generated by Begin or any procedure that - * implicitly calls Begin if any draw buffer has a blend function requiring the - * second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or - * ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than - * the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements." - */ -static GLboolean -_mesa_check_blend_func_error(struct gl_context *ctx) -{ - GLuint i; - for (i = ctx->Const.MaxDualSourceDrawBuffers; - i < ctx->DrawBuffer->_NumColorDrawBuffers; - i++) { - if (ctx->Color.Blend[i]._UsesDualSrc) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "dual source blend on illegal attachment"); - return GL_FALSE; - } - } - return GL_TRUE; -} - -/** - * Prior to drawing anything with glBegin, glDrawArrays, etc. this function - * is called to see if it's valid to render. This involves checking that - * the current shader is valid and the framebuffer is complete. - * If an error is detected it'll be recorded here. - * \return GL_TRUE if OK to render, GL_FALSE if not - */ -GLboolean -_mesa_valid_to_render(struct gl_context *ctx, const char *where) -{ - bool vert_from_glsl_shader = false; - bool geom_from_glsl_shader = false; - bool frag_from_glsl_shader = false; - - /* This depends on having up to date derived state (shaders) */ - if (ctx->NewState) - _mesa_update_state(ctx); - - if (ctx->Shader.CurrentVertexProgram) { - vert_from_glsl_shader = true; - - if (!ctx->Shader.CurrentVertexProgram->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(shader not linked)", where); - return GL_FALSE; - } -#if 0 /* not normally enabled */ - { - char errMsg[100]; - if (!_mesa_validate_shader_program(ctx, - ctx->Shader.CurrentVertexProgram, - errMsg)) { - _mesa_warning(ctx, "Shader program %u is invalid: %s", - ctx->Shader.CurrentVertexProgram->Name, errMsg); - } - } -#endif - } - - if (ctx->Shader.CurrentGeometryProgram) { - geom_from_glsl_shader = true; - - if (!ctx->Shader.CurrentGeometryProgram->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(shader not linked)", where); - return GL_FALSE; - } -#if 0 /* not normally enabled */ - { - char errMsg[100]; - if (!_mesa_validate_shader_program(ctx, - ctx->Shader.CurrentGeometryProgram, - errMsg)) { - _mesa_warning(ctx, "Shader program %u is invalid: %s", - ctx->Shader.CurrentGeometryProgram->Name, errMsg); - } - } -#endif - } - - if (ctx->Shader.CurrentFragmentProgram) { - frag_from_glsl_shader = true; - - if (!ctx->Shader.CurrentFragmentProgram->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(shader not linked)", where); - return GL_FALSE; - } -#if 0 /* not normally enabled */ - { - char errMsg[100]; - if (!_mesa_validate_shader_program(ctx, - ctx->Shader.CurrentFragmentProgram, - errMsg)) { - _mesa_warning(ctx, "Shader program %u is invalid: %s", - ctx->Shader.CurrentFragmentProgram->Name, errMsg); - } - } -#endif - } - - /* Any shader stages that are not supplied by the GLSL shader and have - * assembly shaders enabled must now be validated. - */ - if (!vert_from_glsl_shader - && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(vertex program not valid)", where); - return GL_FALSE; - } - - /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current - * FINISHME: geometry program should validated here. - */ - (void) geom_from_glsl_shader; - - if (!frag_from_glsl_shader) { - if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(fragment program not valid)", where); - return GL_FALSE; - } - - /* If drawing to integer-valued color buffers, there must be an - * active fragment shader (GL_EXT_texture_integer). - */ - if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(integer format but no fragment shader)", where); - return GL_FALSE; - } - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "%s(incomplete framebuffer)", where); - return GL_FALSE; - } - - if (_mesa_check_blend_func_error(ctx) == GL_FALSE) { - return GL_FALSE; - } - -#ifdef DEBUG - if (ctx->Shader.Flags & GLSL_LOG) { - struct gl_shader_program *shProg[MESA_SHADER_TYPES]; - gl_shader_type i; - - shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram; - shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram; - shProg[MESA_SHADER_FRAGMENT] = ctx->Shader.CurrentFragmentProgram; - - for (i = 0; i < MESA_SHADER_TYPES; i++) { - if (shProg[i] == NULL || shProg[i]->_Used - || shProg[i]->_LinkedShaders[i] == NULL) - continue; - - /* This is the first time this shader is being used. - * Append shader's constants/uniforms to log file. - * - * Only log data for the program target that matches the shader - * target. It's possible to have a program bound to the vertex - * shader target that also supplied a fragment shader. If that - * program isn't also bound to the fragment shader target we don't - * want to log its fragment data. - */ - _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]); - } - - for (i = 0; i < MESA_SHADER_TYPES; i++) { - if (shProg[i] != NULL) - shProg[i]->_Used = GL_TRUE; - } - } -#endif - - return GL_TRUE; -} - - -/*@}*/ diff --git a/contrib/sdk/sources/Mesa/src/mesa/main/cpuinfo.c.bak b/contrib/sdk/sources/Mesa/src/mesa/main/cpuinfo.c.bak deleted file mode 100644 index 50b190d6b5..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/main/cpuinfo.c.bak +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#include "main/compiler.h" -#include "main/cpuinfo.h" - - -/** - * This function should be called before the various "cpu_has_foo" macros - * are used. - */ -void -_mesa_get_cpu_features(void) -{ -#ifdef USE_X86_ASM - _mesa_get_x86_features(); -#endif -} - - -/** - * Return a string describing the CPU architexture and extensions that - * Mesa is using (such as SSE or Altivec). - * \return information string, free it with free() - */ -char * -_mesa_get_cpu_string(void) -{ -#define MAX_STRING 50 - char *buffer; - - buffer = malloc(MAX_STRING); - if (!buffer) - return NULL; - - buffer[0] = 0; - -#ifdef USE_X86_ASM - - if (_mesa_x86_cpu_features) { - strcat(buffer, "x86"); - } - -# ifdef USE_MMX_ASM - if (cpu_has_mmx) { - strcat(buffer, (cpu_has_mmxext) ? "/MMX+" : "/MMX"); - } -# endif -# ifdef USE_3DNOW_ASM - if (cpu_has_3dnow) { - strcat(buffer, (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"); - } -# endif -# ifdef USE_SSE_ASM - if (cpu_has_xmm) { - strcat(buffer, (cpu_has_xmm2) ? "/SSE2" : "/SSE"); - } -# endif - - assert(strlen(buffer) < MAX_STRING); - - return buffer; -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/main/state.c.bak b/contrib/sdk/sources/Mesa/src/mesa/main/state.c.bak deleted file mode 100644 index c2962ac0f7..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/main/state.c.bak +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file state.c - * State management. - * - * This file manages recalculation of derived values in struct gl_context. - */ - - -#include "glheader.h" -#include "mtypes.h" -#include "arrayobj.h" -#include "context.h" -#include "debug.h" -#include "macros.h" -#include "ffvertex_prog.h" -#include "framebuffer.h" -#include "light.h" -#include "matrix.h" -#include "pixel.h" -#include "program/program.h" -#include "program/prog_parameter.h" -#include "shaderobj.h" -#include "state.h" -#include "stencil.h" -#include "texenvprogram.h" -#include "texobj.h" -#include "texstate.h" -#include "varray.h" -#include "blend.h" - - -/** - * Update the following fields: - * ctx->VertexProgram._Enabled - * ctx->FragmentProgram._Enabled - * ctx->ATIFragmentShader._Enabled - * This needs to be done before texture state validation. - */ -static void -update_program_enables(struct gl_context *ctx) -{ - /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment - * program is enabled AND valid. Similarly for ATI fragment shaders. - * GLSL shaders not relevant here. - */ - ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled - && ctx->VertexProgram.Current->Base.Instructions; - ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled - && ctx->FragmentProgram.Current->Base.Instructions; - ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled - && ctx->ATIFragmentShader.Current->Instructions[0]; -} - - -/** - * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point - * to the current/active programs. Then call ctx->Driver.BindProgram() to - * tell the driver which programs to use. - * - * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment - * programs or programs derived from fixed-function state. - * - * This function needs to be called after texture state validation in case - * we're generating a fragment program from fixed-function texture state. - * - * \return bitfield which will indicate _NEW_PROGRAM state if a new vertex - * or fragment program is being used. - */ -static GLbitfield -update_program(struct gl_context *ctx) -{ - const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram; - const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram; - struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram; - const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current; - const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current; - const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current; - GLbitfield new_state = 0x0; - - /* - * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current - * pointers to the programs that should be used for rendering. If either - * is NULL, use fixed-function code paths. - * - * These programs may come from several sources. The priority is as - * follows: - * 1. OpenGL 2.0/ARB vertex/fragment shaders - * 2. ARB/NV vertex/fragment programs - * 3. Programs derived from fixed-function state. - * - * Note: it's possible for a vertex shader to get used with a fragment - * program (and vice versa) here, but in practice that shouldn't ever - * come up, or matter. - */ - - if (fsProg && fsProg->LinkStatus - && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { - /* Use GLSL fragment shader */ - _mesa_reference_shader_program(ctx, - &ctx->Shader._CurrentFragmentProgram, - fsProg); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, - gl_fragment_program(fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, - NULL); - } - else if (ctx->FragmentProgram._Enabled) { - /* Use user-defined fragment program */ - _mesa_reference_shader_program(ctx, - &ctx->Shader._CurrentFragmentProgram, - NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, - ctx->FragmentProgram.Current); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, - NULL); - } - else if (ctx->FragmentProgram._MaintainTexEnvProgram) { - /* Use fragment program generated from fixed-function state */ - struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); - - _mesa_reference_shader_program(ctx, - &ctx->Shader._CurrentFragmentProgram, - f); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, - gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, - gl_fragment_program(f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program)); - } - else { - /* No fragment program */ - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, - NULL); - } - - if (gsProg && gsProg->LinkStatus - && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { - /* Use GLSL geometry shader */ - _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, - gl_geometry_program(gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program)); - } else { - /* No geometry program */ - _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); - } - - /* Examine vertex program after fragment program as - * _mesa_get_fixed_func_vertex_program() needs to know active - * fragprog inputs. - */ - if (vsProg && vsProg->LinkStatus - && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) { - /* Use GLSL vertex shader */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - gl_vertex_program(vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program)); - } - else if (ctx->VertexProgram._Enabled) { - /* Use user-defined vertex program */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - ctx->VertexProgram.Current); - } - else if (ctx->VertexProgram._MaintainTnlProgram) { - /* Use vertex program generated from fixed-function state */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, - _mesa_get_fixed_func_vertex_program(ctx)); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, - ctx->VertexProgram._Current); - } - else { - /* no vertex program */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); - } - - /* Let the driver know what's happening: - */ - if (ctx->FragmentProgram._Current != prevFP) { - new_state |= _NEW_PROGRAM; - if (ctx->Driver.BindProgram) { - ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, - (struct gl_program *) ctx->FragmentProgram._Current); - } - } - - if (ctx->GeometryProgram._Current != prevGP) { - new_state |= _NEW_PROGRAM; - if (ctx->Driver.BindProgram) { - ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM, - (struct gl_program *) ctx->GeometryProgram._Current); - } - } - - if (ctx->VertexProgram._Current != prevVP) { - new_state |= _NEW_PROGRAM; - if (ctx->Driver.BindProgram) { - ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, - (struct gl_program *) ctx->VertexProgram._Current); - } - } - - return new_state; -} - - -/** - * Examine shader constants and return either _NEW_PROGRAM_CONSTANTS or 0. - */ -static GLbitfield -update_program_constants(struct gl_context *ctx) -{ - GLbitfield new_state = 0x0; - - if (ctx->FragmentProgram._Current) { - const struct gl_program_parameter_list *params = - ctx->FragmentProgram._Current->Base.Parameters; - if (params && params->StateFlags & ctx->NewState) { - new_state |= _NEW_PROGRAM_CONSTANTS; - } - } - - if (ctx->GeometryProgram._Current) { - const struct gl_program_parameter_list *params = - ctx->GeometryProgram._Current->Base.Parameters; - /*FIXME: StateFlags is always 0 because we have unnamed constant - * not state changes */ - if (params /*&& params->StateFlags & ctx->NewState*/) { - new_state |= _NEW_PROGRAM_CONSTANTS; - } - } - - if (ctx->VertexProgram._Current) { - const struct gl_program_parameter_list *params = - ctx->VertexProgram._Current->Base.Parameters; - if (params && params->StateFlags & ctx->NewState) { - new_state |= _NEW_PROGRAM_CONSTANTS; - } - } - - return new_state; -} - - - - -static void -update_viewport_matrix(struct gl_context *ctx) -{ - const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; - - ASSERT(depthMax > 0); - - /* Compute scale and bias values. This is really driver-specific - * and should be maintained elsewhere if at all. - * NOTE: RasterPos uses this. - */ - _math_matrix_viewport(&ctx->Viewport._WindowMap, - ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height, - ctx->Viewport.Near, ctx->Viewport.Far, - depthMax); -} - - -/** - * Update derived multisample state. - */ -static void -update_multisample(struct gl_context *ctx) -{ - ctx->Multisample._Enabled = GL_FALSE; - if (ctx->Multisample.Enabled && - ctx->DrawBuffer && - ctx->DrawBuffer->Visual.sampleBuffers) - ctx->Multisample._Enabled = GL_TRUE; -} - - -/** - * Update the ctx->VertexProgram._TwoSideEnabled flag. - */ -static void -update_twoside(struct gl_context *ctx) -{ - if (ctx->Shader.CurrentVertexProgram || - ctx->VertexProgram._Enabled) { - ctx->VertexProgram._TwoSideEnabled = ctx->VertexProgram.TwoSideEnabled; - } else { - ctx->VertexProgram._TwoSideEnabled = (ctx->Light.Enabled && - ctx->Light.Model.TwoSide); - } -} - - -/** - * Compute derived GL state. - * If __struct gl_contextRec::NewState is non-zero then this function \b must - * be called before rendering anything. - * - * Calls dd_function_table::UpdateState to perform any internal state - * management necessary. - * - * \sa _mesa_update_modelview_project(), _mesa_update_texture(), - * _mesa_update_buffer_bounds(), - * _mesa_update_lighting() and _mesa_update_tnl_spaces(). - */ -void -_mesa_update_state_locked( struct gl_context *ctx ) -{ - GLbitfield new_state = ctx->NewState; - GLbitfield prog_flags = _NEW_PROGRAM; - GLbitfield new_prog_state = 0x0; - - if (new_state == _NEW_CURRENT_ATTRIB) - goto out; - - if (MESA_VERBOSE & VERBOSE_STATE) - _mesa_print_state("_mesa_update_state", new_state); - - /* Determine which state flags effect vertex/fragment program state */ - if (ctx->FragmentProgram._MaintainTexEnvProgram) { - prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | - _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT | - _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP | - _NEW_COLOR); - } - if (ctx->VertexProgram._MaintainTnlProgram) { - prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE | - _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT | - _NEW_FOG | _NEW_LIGHT | - _MESA_NEW_NEED_EYE_COORDS); - } - - /* - * Now update derived state info - */ - - if (new_state & prog_flags) - update_program_enables( ctx ); - - if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) - _mesa_update_modelview_project( ctx, new_state ); - - if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) - _mesa_update_texture( ctx, new_state ); - - if (new_state & _NEW_BUFFERS) - _mesa_update_framebuffer(ctx); - - if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) - _mesa_update_draw_buffer_bounds( ctx ); - - if (new_state & _NEW_LIGHT) - _mesa_update_lighting( ctx ); - - if (new_state & (_NEW_LIGHT | _NEW_PROGRAM)) - update_twoside( ctx ); - - if (new_state & (_NEW_STENCIL | _NEW_BUFFERS)) - _mesa_update_stencil( ctx ); - - if (new_state & _NEW_PIXEL) - _mesa_update_pixel( ctx, new_state ); - - if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) - update_viewport_matrix(ctx); - - if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) - update_multisample( ctx ); - - /* ctx->_NeedEyeCoords is now up to date. - * - * If the truth value of this variable has changed, update for the - * new lighting space and recompute the positions of lights and the - * normal transform. - * - * If the lighting space hasn't changed, may still need to recompute - * light positions & normal transforms for other reasons. - */ - if (new_state & _MESA_NEW_NEED_EYE_COORDS) - _mesa_update_tnl_spaces( ctx, new_state ); - - if (new_state & prog_flags) { - /* When we generate programs from fixed-function vertex/fragment state - * this call may generate/bind a new program. If so, we need to - * propogate the _NEW_PROGRAM flag to the driver. - */ - new_prog_state |= update_program( ctx ); - } - - if (ctx->Const.CheckArrayBounds && - new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) { - _mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj); - } - - out: - new_prog_state |= update_program_constants(ctx); - - /* - * Give the driver a chance to act upon the new_state flags. - * The driver might plug in different span functions, for example. - * Also, this is where the driver can invalidate the state of any - * active modules (such as swrast_setup, swrast, tnl, etc). - * - * Set ctx->NewState to zero to avoid recursion if - * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) - */ - new_state = ctx->NewState | new_prog_state; - ctx->NewState = 0; - - printf("call update state\n"); - - ctx->Driver.UpdateState(ctx, new_state); -} - - -/* This is the usual entrypoint for state updates: - */ -void -_mesa_update_state( struct gl_context *ctx ) -{ - _mesa_lock_context_textures(ctx); - _mesa_update_state_locked(ctx); - _mesa_unlock_context_textures(ctx); -} - - - - -/** - * Want to figure out which fragment program inputs are actually - * constant/current values from ctx->Current. These should be - * referenced as a tracked state variable rather than a fragment - * program input, to save the overhead of putting a constant value in - * every submitted vertex, transferring it to hardware, interpolating - * it across the triangle, etc... - * - * When there is a VP bound, just use vp->outputs. But when we're - * generating vp from fixed function state, basically want to - * calculate: - * - * vp_out_2_fp_in( vp_in_2_vp_out( varying_inputs ) | - * potential_vp_outputs ) - * - * Where potential_vp_outputs is calculated by looking at enabled - * texgen, etc. - * - * The generated fragment program should then only declare inputs that - * may vary or otherwise differ from the ctx->Current values. - * Otherwise, the fp should track them as state values instead. - */ -void -_mesa_set_varying_vp_inputs( struct gl_context *ctx, - GLbitfield64 varying_inputs ) -{ - if (ctx->varying_vp_inputs != varying_inputs) { - ctx->varying_vp_inputs = varying_inputs; - - /* Only the fixed-func generated programs need to use the flag - * and the fixed-func fragment program uses it only if there is also - * a fixed-func vertex program, so this only depends on the latter. - * - * It's okay to check the VP pointer here, because this is called after - * _mesa_update_state in the vbo module. */ - if (ctx->VertexProgram._TnlProgram || - ctx->FragmentProgram._TexEnvProgram) { - ctx->NewState |= _NEW_VARYING_VP_INPUTS; - } - /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ - } -} - - -/** - * Used by drivers to tell core Mesa that the driver is going to - * install/ use its own vertex program. In particular, this will - * prevent generated fragment programs from using state vars instead - * of ordinary varyings/inputs. - */ -void -_mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) -{ - if (ctx->VertexProgram._Overriden != flag) { - ctx->VertexProgram._Overriden = flag; - - /* Set one of the bits which will trigger fragment program - * regeneration: - */ - ctx->NewState |= _NEW_PROGRAM; - } -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/swrast/s_clear.c.bak b/contrib/sdk/sources/Mesa/src/mesa/swrast/s_clear.c.bak deleted file mode 100644 index 3d549d7f72..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/swrast/s_clear.c.bak +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "main/glheader.h" -#include "main/accum.h" -#include "main/condrender.h" -#include "main/format_pack.h" -#include "main/macros.h" -#include "main/imports.h" -#include "main/mtypes.h" - -#include "s_context.h" -#include "s_depth.h" -#include "s_stencil.h" - - - -/** - * Clear an rgba color buffer with masking if needed. - */ -static void -clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb, - const GLubyte colorMask[4]) -{ - const GLint x = ctx->DrawBuffer->_Xmin; - const GLint y = ctx->DrawBuffer->_Ymin; - const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - const GLuint pixelSize = _mesa_get_format_bytes(rb->Format); - const GLboolean doMasking = (colorMask[0] == 0 || - colorMask[1] == 0 || - colorMask[2] == 0 || - colorMask[3] == 0); - const GLfloat (*clearColor)[4] = - (const GLfloat (*)[4]) ctx->Color.ClearColor.f; - GLbitfield mapMode = GL_MAP_WRITE_BIT; - GLubyte *map; - GLint rowStride; - GLint i, j; - - if (doMasking) { - /* we'll need to read buffer values too */ - mapMode |= GL_MAP_READ_BIT; - } - - /* map dest buffer */ - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, - mapMode, &map, &rowStride); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)"); - return; - } - - /* for 1, 2, 4-byte clearing */ -#define SIMPLE_TYPE_CLEAR(TYPE) \ - do { \ - TYPE pixel, pixelMask; \ - _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, &pixel); \ - if (doMasking) { \ - _mesa_pack_colormask(rb->Format, colorMask, &pixelMask); \ - pixel &= pixelMask; \ - pixelMask = ~pixelMask; \ - } \ - for (i = 0; i < height; i++) { \ - TYPE *row = (TYPE *) map; \ - if (doMasking) { \ - for (j = 0; j < width; j++) { \ - row[j] = (row[j] & pixelMask) | pixel; \ - } \ - } \ - else { \ - for (j = 0; j < width; j++) { \ - row[j] = pixel; \ - } \ - } \ - map += rowStride; \ - } \ - } while (0) - - - /* for 3, 6, 8, 12, 16-byte clearing */ -#define MULTI_WORD_CLEAR(TYPE, N) \ - do { \ - TYPE pixel[N], pixelMask[N]; \ - GLuint k; \ - _mesa_pack_float_rgba_row(rb->Format, 1, clearColor, pixel); \ - if (doMasking) { \ - _mesa_pack_colormask(rb->Format, colorMask, pixelMask); \ - for (k = 0; k < N; k++) { \ - pixel[k] &= pixelMask[k]; \ - pixelMask[k] = ~pixelMask[k]; \ - } \ - } \ - for (i = 0; i < height; i++) { \ - TYPE *row = (TYPE *) map; \ - if (doMasking) { \ - for (j = 0; j < width; j++) { \ - for (k = 0; k < N; k++) { \ - row[j * N + k] = \ - (row[j * N + k] & pixelMask[k]) | pixel[k]; \ - } \ - } \ - } \ - else { \ - for (j = 0; j < width; j++) { \ - for (k = 0; k < N; k++) { \ - row[j * N + k] = pixel[k]; \ - } \ - } \ - } \ - map += rowStride; \ - } \ - } while(0) - - switch (pixelSize) { - case 1: - SIMPLE_TYPE_CLEAR(GLubyte); - break; - case 2: - SIMPLE_TYPE_CLEAR(GLushort); - break; - case 3: - MULTI_WORD_CLEAR(GLubyte, 3); - break; - case 4: - SIMPLE_TYPE_CLEAR(GLuint); - break; - case 6: - MULTI_WORD_CLEAR(GLushort, 3); - break; - case 8: - MULTI_WORD_CLEAR(GLuint, 2); - break; - case 12: - MULTI_WORD_CLEAR(GLuint, 3); - break; - case 16: - MULTI_WORD_CLEAR(GLuint, 4); - break; - default: - _mesa_problem(ctx, "bad pixel size in clear_rgba_buffer()"); - } - - /* unmap buffer */ - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} - - -/** - * Clear the front/back/left/right/aux color buffers. - * This function is usually only called if the device driver can't - * clear its own color buffers for some reason (such as with masking). - */ -static void -clear_color_buffers(struct gl_context *ctx) -{ - GLuint buf; - - for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) { - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf]; - - /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported, - * the framebuffer can be complete with some attachments be missing. In - * this case the _ColorDrawBuffers pointer will be NULL. - */ - if (rb == NULL) - continue; - - clear_rgba_buffer(ctx, rb, ctx->Color.ColorMask[buf]); - } -} - - -/** - * Called via the device driver's ctx->Driver.Clear() function if the - * device driver can't clear one or more of the buffers itself. - * \param buffers bitfield of BUFFER_BIT_* values indicating which - * renderbuffers are to be cleared. - * \param all if GL_TRUE, clear whole buffer, else clear specified region. - */ -void -_swrast_Clear(struct gl_context *ctx, GLbitfield buffers) -{ - const GLbitfield BUFFER_DS = BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL; - ENTER(); - -#ifdef DEBUG_FOO - { - const GLbitfield legalBits = - BUFFER_BIT_FRONT_LEFT | - BUFFER_BIT_FRONT_RIGHT | - BUFFER_BIT_BACK_LEFT | - BUFFER_BIT_BACK_RIGHT | - BUFFER_BIT_DEPTH | - BUFFER_BIT_STENCIL | - BUFFER_BIT_ACCUM | - BUFFER_BIT_AUX0; - assert((buffers & (~legalBits)) == 0); - } -#endif - - if (!_mesa_check_conditional_render(ctx)) - return; /* don't clear */ - - if (SWRAST_CONTEXT(ctx)->NewState) - _swrast_validate_derived(ctx); - - if ((buffers & BUFFER_BITS_COLOR) - && (ctx->DrawBuffer->_NumColorDrawBuffers > 0)) { - clear_color_buffers(ctx); - } - - if (buffers & BUFFER_BIT_ACCUM) { - _mesa_clear_accum_buffer(ctx); - } - - if (buffers & BUFFER_DS) { - struct gl_renderbuffer *depthRb = - ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; - struct gl_renderbuffer *stencilRb = - ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; - - if ((buffers & BUFFER_DS) == BUFFER_DS && depthRb == stencilRb) { - /* clear depth and stencil together */ - _swrast_clear_depth_stencil_buffer(ctx); - } - else { - /* clear depth, stencil separately */ - if (buffers & BUFFER_BIT_DEPTH) { - _swrast_clear_depth_buffer(ctx); - } - if (buffers & BUFFER_BIT_STENCIL) { - _swrast_clear_stencil_buffer(ctx); - } - } - } - LEAVE(); -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/vbo/vbo_exec_array.c.bak b/contrib/sdk/sources/Mesa/src/mesa/vbo/vbo_exec_array.c.bak deleted file mode 100644 index ba6953d838..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/vbo/vbo_exec_array.c.bak +++ /dev/null @@ -1,1664 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/state.h" -#include "main/api_validate.h" -#include "main/dispatch.h" -#include "main/varray.h" -#include "main/bufferobj.h" -#include "main/enums.h" -#include "main/macros.h" -#include "main/transformfeedback.h" - -#include "vbo_context.h" - - -/** - * All vertex buffers should be in an unmapped state when we're about - * to draw. This debug function checks that. - */ -static void -check_buffers_are_unmapped(const struct gl_client_array **inputs) -{ -#ifdef DEBUG - GLuint i; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (inputs[i]) { - struct gl_buffer_object *obj = inputs[i]->BufferObj; - assert(!_mesa_bufferobj_mapped(obj)); - (void) obj; - } - } -#endif -} - - -/** - * A debug function that may be called from other parts of Mesa as - * needed during debugging. - */ -void -vbo_check_buffers_are_unmapped(struct gl_context *ctx) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - /* check the current vertex arrays */ - check_buffers_are_unmapped(exec->array.inputs); - /* check the current glBegin/glVertex/glEnd-style VBO */ - assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj)); -} - - - -/** - * Compute min and max elements by scanning the index buffer for - * glDraw[Range]Elements() calls. - * If primitive restart is enabled, we need to ignore restart - * indexes when computing min/max. - */ -static void -vbo_get_minmax_index(struct gl_context *ctx, - const struct _mesa_prim *prim, - const struct _mesa_index_buffer *ib, - GLuint *min_index, GLuint *max_index, - const GLuint count) -{ - const GLboolean restart = ctx->Array._PrimitiveRestart; - const GLuint restartIndex = _mesa_primitive_restart_index(ctx, ib->type); - const int index_size = vbo_sizeof_ib_type(ib->type); - const char *indices; - GLuint i; - - indices = (char *) ib->ptr + prim->start * index_size; - if (_mesa_is_bufferobj(ib->obj)) { - GLsizeiptr size = MIN2(count * index_size, ib->obj->Size); - indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size, - GL_MAP_READ_BIT, ib->obj); - } - - switch (ib->type) { - case GL_UNSIGNED_INT: { - const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - GLuint min_ui = ~0U; - if (restart) { - for (i = 0; i < count; i++) { - if (ui_indices[i] != restartIndex) { - if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; - if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; - } - } - } - else { - for (i = 0; i < count; i++) { - if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; - if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; - } - } - *min_index = min_ui; - *max_index = max_ui; - break; - } - case GL_UNSIGNED_SHORT: { - const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - GLuint min_us = ~0U; - if (restart) { - for (i = 0; i < count; i++) { - if (us_indices[i] != restartIndex) { - if (us_indices[i] > max_us) max_us = us_indices[i]; - if (us_indices[i] < min_us) min_us = us_indices[i]; - } - } - } - else { - for (i = 0; i < count; i++) { - if (us_indices[i] > max_us) max_us = us_indices[i]; - if (us_indices[i] < min_us) min_us = us_indices[i]; - } - } - *min_index = min_us; - *max_index = max_us; - break; - } - case GL_UNSIGNED_BYTE: { - const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - GLuint min_ub = ~0U; - if (restart) { - for (i = 0; i < count; i++) { - if (ub_indices[i] != restartIndex) { - if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; - if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; - } - } - } - else { - for (i = 0; i < count; i++) { - if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; - if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; - } - } - *min_index = min_ub; - *max_index = max_ub; - break; - } - default: - assert(0); - break; - } - - if (_mesa_is_bufferobj(ib->obj)) { - ctx->Driver.UnmapBuffer(ctx, ib->obj); - } -} - -/** - * Compute min and max elements for nr_prims - */ -void -vbo_get_minmax_indices(struct gl_context *ctx, - const struct _mesa_prim *prims, - const struct _mesa_index_buffer *ib, - GLuint *min_index, - GLuint *max_index, - GLuint nr_prims) -{ - GLuint tmp_min, tmp_max; - GLuint i; - GLuint count; - - *min_index = ~0; - *max_index = 0; - - for (i = 0; i < nr_prims; i++) { - const struct _mesa_prim *start_prim; - - start_prim = &prims[i]; - count = start_prim->count; - /* Do combination if possible to reduce map/unmap count */ - while ((i + 1 < nr_prims) && - (prims[i].start + prims[i].count == prims[i+1].start)) { - count += prims[i+1].count; - i++; - } - vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count); - *min_index = MIN2(*min_index, tmp_min); - *max_index = MAX2(*max_index, tmp_max); - } -} - - -/** - * Check that element 'j' of the array has reasonable data. - * Map VBO if needed. - * For debugging purposes; not normally used. - */ -static void -check_array_data(struct gl_context *ctx, struct gl_client_array *array, - GLuint attrib, GLuint j) -{ - if (array->Enabled) { - const void *data = array->Ptr; - if (_mesa_is_bufferobj(array->BufferObj)) { - if (!array->BufferObj->Pointer) { - /* need to map now */ - array->BufferObj->Pointer = - ctx->Driver.MapBufferRange(ctx, 0, array->BufferObj->Size, - GL_MAP_READ_BIT, array->BufferObj); - } - data = ADD_POINTERS(data, array->BufferObj->Pointer); - } - switch (array->Type) { - case GL_FLOAT: - { - GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j); - GLint k; - for (k = 0; k < array->Size; k++) { - if (IS_INF_OR_NAN(f[k]) || - f[k] >= 1.0e20 || f[k] <= -1.0e10) { - printf("Bad array data:\n"); - printf(" Element[%u].%u = %f\n", j, k, f[k]); - printf(" Array %u at %p\n", attrib, (void* ) array); - printf(" Type 0x%x, Size %d, Stride %d\n", - array->Type, array->Size, array->Stride); - printf(" Address/offset %p in Buffer Object %u\n", - array->Ptr, array->BufferObj->Name); - f[k] = 1.0; /* XXX replace the bad value! */ - } - /*assert(!IS_INF_OR_NAN(f[k]));*/ - } - } - break; - default: - ; - } - } -} - - -/** - * Unmap the buffer object referenced by given array, if mapped. - */ -static void -unmap_array_buffer(struct gl_context *ctx, struct gl_client_array *array) -{ - if (array->Enabled && - _mesa_is_bufferobj(array->BufferObj) && - _mesa_bufferobj_mapped(array->BufferObj)) { - ctx->Driver.UnmapBuffer(ctx, array->BufferObj); - } -} - - -/** - * Examine the array's data for NaNs, etc. - * For debug purposes; not normally used. - */ -static void -check_draw_elements_data(struct gl_context *ctx, GLsizei count, GLenum elemType, - const void *elements, GLint basevertex) -{ - struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - const void *elemMap; - GLint i, k; - - if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) { - elemMap = ctx->Driver.MapBufferRange(ctx, 0, - ctx->Array.ArrayObj->ElementArrayBufferObj->Size, - GL_MAP_READ_BIT, - ctx->Array.ArrayObj->ElementArrayBufferObj); - elements = ADD_POINTERS(elements, elemMap); - } - - for (i = 0; i < count; i++) { - GLuint j; - - /* j = element[i] */ - switch (elemType) { - case GL_UNSIGNED_BYTE: - j = ((const GLubyte *) elements)[i]; - break; - case GL_UNSIGNED_SHORT: - j = ((const GLushort *) elements)[i]; - break; - case GL_UNSIGNED_INT: - j = ((const GLuint *) elements)[i]; - break; - default: - assert(0); - } - - /* check element j of each enabled array */ - for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { - check_array_data(ctx, &arrayObj->VertexAttrib[k], k, j); - } - } - - if (_mesa_is_bufferobj(arrayObj->ElementArrayBufferObj)) { - ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); - } - - for (k = 0; k < Elements(arrayObj->VertexAttrib); k++) { - unmap_array_buffer(ctx, &arrayObj->VertexAttrib[k]); - } -} - - -/** - * Check array data, looking for NaNs, etc. - */ -static void -check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count) -{ - /* TO DO */ -} - - -/** - * Print info/data for glDrawArrays(), for debugging. - */ -static void -print_draw_arrays(struct gl_context *ctx, - GLenum mode, GLint start, GLsizei count) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - int i; - - printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", - mode, start, count); - - for (i = 0; i < 32; i++) { - struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj; - GLuint bufName = bufObj->Name; - GLint stride = exec->array.inputs[i]->Stride; - printf("attr %2d: size %d stride %d enabled %d " - "ptr %p Bufobj %u\n", - i, - exec->array.inputs[i]->Size, - stride, - /*exec->array.inputs[i]->Enabled,*/ - arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled, - exec->array.inputs[i]->Ptr, - bufName); - - if (bufName) { - GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, - GL_MAP_READ_BIT, bufObj); - int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr; - float *f = (float *) (p + offset); - int *k = (int *) f; - int i; - int n = (count * stride) / 4; - if (n > 32) - n = 32; - printf(" Data at offset %d:\n", offset); - for (i = 0; i < n; i++) { - printf(" float[%d] = 0x%08x %f\n", i, k[i], f[i]); - } - ctx->Driver.UnmapBuffer(ctx, bufObj); - } - } -} - - -/** - * Set the vbo->exec->inputs[] pointers to point to the enabled - * vertex arrays. This depends on the current vertex program/shader - * being executed because of whether or not generic vertex arrays - * alias the conventional vertex arrays. - * For arrays that aren't enabled, we set the input[attrib] pointer - * to point at a zero-stride current value "array". - */ -static void -recalculate_input_bindings(struct gl_context *ctx) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib; - const struct gl_client_array **inputs = &exec->array.inputs[0]; - GLbitfield64 const_inputs = 0x0; - GLuint i; - - switch (get_program_mode(ctx)) { - case VP_NONE: - /* When no vertex program is active (or the vertex program is generated - * from fixed-function state). We put the material values into the - * generic slots. This is the only situation where material values - * are available as per-vertex attributes. - */ - for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) - inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; - else { - inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; - const_inputs |= VERT_BIT(i); - } - } - - for (i = 0; i < MAT_ATTRIB_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC(i)] = - &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i]; - const_inputs |= VERT_BIT_GENERIC(i); - } - - /* Could use just about anything, just to fill in the empty - * slots: - */ - for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; - const_inputs |= VERT_BIT_GENERIC(i); - } - break; - - case VP_ARB: - /* There are no shaders in OpenGL ES 1.x, so this code path should be - * impossible to reach. The meta code is careful to not use shaders in - * ES1. - */ - assert(ctx->API != API_OPENGLES); - - /* In the compatibility profile of desktop OpenGL, the generic[0] - * attribute array aliases and overrides the legacy position array. - * Otherwise, legacy attributes available in the legacy slots, - * generic attributes in the generic slots and materials are not - * available as per-vertex attributes. - * - * In all other APIs, only the generic attributes exist, and none of the - * slots are considered "magic." - */ - if (ctx->API == API_OPENGL_COMPAT) { - if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) - inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0]; - else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) - inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; - else { - inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; - const_inputs |= VERT_BIT_POS; - } - - for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) - inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; - else { - inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; - const_inputs |= VERT_BIT_FF(i); - } - } - - for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) - inputs[VERT_ATTRIB_GENERIC(i)] = - &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; - else { - inputs[VERT_ATTRIB_GENERIC(i)] = - &vbo->currval[VBO_ATTRIB_GENERIC0+i]; - const_inputs |= VERT_BIT_GENERIC(i); - } - } - - inputs[VERT_ATTRIB_GENERIC0] = inputs[0]; - } else { - /* Other parts of the code assume that inputs[0] through - * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL - * ES 2.0+ or OpenGL core profile, none of these arrays should ever - * be enabled. - */ - for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) { - assert(!vertexAttrib[VERT_ATTRIB_FF(i)].Enabled); - - inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; - const_inputs |= VERT_BIT_FF(i); - } - - for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { - if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) - inputs[VERT_ATTRIB_GENERIC(i)] = - &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; - else { - inputs[VERT_ATTRIB_GENERIC(i)] = - &vbo->currval[VBO_ATTRIB_GENERIC0+i]; - const_inputs |= VERT_BIT_GENERIC(i); - } - } - } - - break; - } - - _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) ); - ctx->NewDriverState |= ctx->DriverFlags.NewArray; -} - - -/** - * Examine the enabled vertex arrays to set the exec->array.inputs[] values. - * These will point to the arrays to actually use for drawing. Some will - * be user-provided arrays, other will be zero-stride const-valued arrays. - * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state - * validation must be done after this call. - */ -void -vbo_bind_arrays(struct gl_context *ctx) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; -ENTER(); - vbo_draw_method(vbo, DRAW_ARRAYS); - - if (exec->array.recalculate_inputs) { - recalculate_input_bindings(ctx); - exec->array.recalculate_inputs = GL_FALSE; - - /* Again... because we may have changed the bitmask of per-vertex varying - * attributes. If we regenerate the fixed-function vertex program now - * we may be able to prune down the number of vertex attributes which we - * need in the shader. - */ - if (ctx->NewState) { - /* Setting "validating" to TRUE prevents _mesa_update_state from - * invalidating what we just did. - */ - exec->validating = GL_TRUE; - _mesa_update_state(ctx); - exec->validating = GL_FALSE; - } - } -LEAVE(); -} - - -/** - * Handle a draw case that potentially has primitive restart enabled. - * - * If primitive restart is enabled, and PrimitiveRestartInSoftware is - * set, then vbo_sw_primitive_restart is used to handle the primitive - * restart case in software. - */ -static void -vbo_handle_primitive_restart(struct gl_context *ctx, - const struct _mesa_prim *prim, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLboolean index_bounds_valid, - GLuint min_index, - GLuint max_index) -{ - struct vbo_context *vbo = vbo_context(ctx); - - if ((ib != NULL) && - ctx->Const.PrimitiveRestartInSoftware && - ctx->Array._PrimitiveRestart) { - /* Handle primitive restart in software */ - vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); - } else { - /* Call driver directly for draw_prims */ - vbo->draw_prims(ctx, prim, nr_prims, ib, - index_bounds_valid, min_index, max_index, NULL); - } -} - - -/** - * Helper function called by the other DrawArrays() functions below. - * This is where we handle primitive restart for drawing non-indexed - * arrays. If primitive restart is enabled, it typically means - * splitting one DrawArrays() into two. - */ -static void -vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, - GLsizei count, GLuint numInstances, GLuint baseInstance) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct _mesa_prim prim[2]; -ENTER(); - vbo_bind_arrays(ctx); - - /* init most fields to zero */ - memset(prim, 0, sizeof(prim)); - prim[0].begin = 1; - prim[0].end = 1; - prim[0].mode = mode; - prim[0].num_instances = numInstances; - prim[0].base_instance = baseInstance; - - /* Implement the primitive restart index */ - if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) { - GLuint primCount = 0; - - if (ctx->Array.RestartIndex == start) { - /* special case: RestartIndex at beginning */ - if (count > 1) { - prim[0].start = start + 1; - prim[0].count = count - 1; - primCount = 1; - } - } - else if (ctx->Array.RestartIndex == start + count - 1) { - /* special case: RestartIndex at end */ - if (count > 1) { - prim[0].start = start; - prim[0].count = count - 1; - primCount = 1; - } - } - else { - /* general case: RestartIndex in middle, split into two prims */ - prim[0].start = start; - prim[0].count = ctx->Array.RestartIndex - start; - - prim[1] = prim[0]; - prim[1].start = ctx->Array.RestartIndex + 1; - prim[1].count = count - prim[1].start; - - primCount = 2; - } - - if (primCount > 0) { - /* draw one or two prims */ - check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, prim, primCount, NULL, - GL_TRUE, start, start + count - 1, NULL); - } - } - else { - /* no prim restart */ - prim[0].start = start; - prim[0].count = count; - - check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, prim, 1, NULL, - GL_TRUE, start, start + count - 1, - NULL); - } - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { - _mesa_flush(ctx); - } -LEAVE(); -} - - -/** - * Execute a glRectf() function. - */ -static void GLAPIENTRY -vbo_exec_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - CALL_Begin(GET_DISPATCH(), (GL_QUADS)); - CALL_Vertex2f(GET_DISPATCH(), (x1, y1)); - CALL_Vertex2f(GET_DISPATCH(), (x2, y1)); - CALL_Vertex2f(GET_DISPATCH(), (x2, y2)); - CALL_Vertex2f(GET_DISPATCH(), (x1, y2)); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY -vbo_exec_EvalMesh1(GLenum mode, GLint i1, GLint i2) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - GLfloat u, du; - GLenum prim; - - switch (mode) { - case GL_POINT: - prim = GL_POINTS; - break; - case GL_LINE: - prim = GL_LINE_STRIP; - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); - return; - } - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map1Vertex4 && - !ctx->Eval.Map1Vertex3) - return; - - du = ctx->Eval.MapGrid1du; - u = ctx->Eval.MapGrid1u1 + i1 * du; - - CALL_Begin(GET_DISPATCH(), (prim)); - for (i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord1f(GET_DISPATCH(), (u)); - } - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY -vbo_exec_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat u, du, v, dv, v1, u1; - GLint i, j; - - switch (mode) { - case GL_POINT: - case GL_LINE: - case GL_FILL: - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" ); - return; - } - - /* No effect if vertex maps disabled. - */ - if (!ctx->Eval.Map2Vertex4 && - !ctx->Eval.Map2Vertex3) - return; - - du = ctx->Eval.MapGrid2du; - dv = ctx->Eval.MapGrid2dv; - v1 = ctx->Eval.MapGrid2v1 + j1 * dv; - u1 = ctx->Eval.MapGrid2u1 + i1 * du; - - switch (mode) { - case GL_POINT: - CALL_Begin(GET_DISPATCH(), (GL_POINTS)); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - } - CALL_End(GET_DISPATCH(), ()); - break; - case GL_LINE: - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - CALL_End(GET_DISPATCH(), ()); - } - for (u=u1,i=i1;i<=i2;i++,u+=du) { - CALL_Begin(GET_DISPATCH(), (GL_LINE_STRIP)); - for (v=v1,j=j1;j<=j2;j++,v+=dv) { - CALL_EvalCoord2f(GET_DISPATCH(), (u, v)); - } - CALL_End(GET_DISPATCH(), ()); - } - break; - case GL_FILL: - for (v=v1,j=j1;jDriver.MapBufferRange(ctx, 0, - ctx->Array.ArrayObj->ElementArrayBufferObj->Size, - GL_MAP_READ_BIT, - ctx->Array.ArrayObj->ElementArrayBufferObj); - switch (type) { - case GL_UNSIGNED_BYTE: - { - const GLubyte *us = (const GLubyte *) map; - GLint i; - for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size; i++) { - printf("%02x ", us[i]); - if (i % 32 == 31) - printf("\n"); - } - printf("\n"); - } - break; - case GL_UNSIGNED_SHORT: - { - const GLushort *us = (const GLushort *) map; - GLint i; - for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 2; i++) { - printf("%04x ", us[i]); - if (i % 16 == 15) - printf("\n"); - } - printf("\n"); - } - break; - case GL_UNSIGNED_INT: - { - const GLuint *us = (const GLuint *) map; - GLint i; - for (i = 0; i < ctx->Array.ArrayObj->ElementArrayBufferObj->Size / 4; i++) { - printf("%08x ", us[i]); - if (i % 8 == 7) - printf("\n"); - } - printf("\n"); - } - break; - default: - ; - } - - ctx->Driver.UnmapBuffer(ctx, ctx->Array.ArrayObj->ElementArrayBufferObj); -} -#endif - - -/** - * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. - * Do the rendering for a glDrawElements or glDrawRangeElements call after - * we've validated buffer bounds, etc. - */ -static void -vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, - GLboolean index_bounds_valid, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, - GLint basevertex, GLuint numInstances, - GLuint baseInstance) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct _mesa_index_buffer ib; - struct _mesa_prim prim[1]; - - vbo_bind_arrays(ctx); - - ib.count = count; - ib.type = type; - ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; - ib.ptr = indices; - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 1; - prim[0].basevertex = basevertex; - prim[0].num_instances = numInstances; - prim[0].base_instance = baseInstance; - - /* Need to give special consideration to rendering a range of - * indices starting somewhere above zero. Typically the - * application is issuing multiple DrawRangeElements() to draw - * successive primitives layed out linearly in the vertex arrays. - * Unless the vertex arrays are all in a VBO (or locked as with - * CVA), the OpenGL semantics imply that we need to re-read or - * re-upload the vertex data on each draw call. - * - * In the case of hardware tnl, we want to avoid starting the - * upload at zero, as it will mean every draw call uploads an - * increasing amount of not-used vertex data. Worse - in the - * software tnl module, all those vertices might be transformed and - * lit but never rendered. - * - * If we just upload or transform the vertices in start..end, - * however, the indices will be incorrect. - * - * At this level, we don't know exactly what the requirements of - * the backend are going to be, though it will likely boil down to - * either: - * - * 1) Do nothing, everything is in a VBO and is processed once - * only. - * - * 2) Adjust the indices and vertex arrays so that start becomes - * zero. - * - * Rather than doing anything here, I'll provide a helper function - * for the latter case elsewhere. - */ - - check_buffers_are_unmapped(exec->array.inputs); - vbo_handle_primitive_restart(ctx, prim, 1, &ib, - index_bounds_valid, start, end); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { - _mesa_flush(ctx); - } -} - - -/** - * Called by glDrawRangeElementsBaseVertex() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, - GLint basevertex) -{ - static GLuint warnCount = 0; - GLboolean index_bounds_valid = GL_TRUE; - GLuint max_element; - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, - "glDrawRangeElementsBaseVertex(%s, %u, %u, %d, %s, %p, %d)\n", - _mesa_lookup_enum_by_nr(mode), start, end, count, - _mesa_lookup_enum_by_nr(type), indices, basevertex); - - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, - type, indices, basevertex )) - return; - - if (ctx->Const.CheckArrayBounds) { - /* _MaxElement was computed, so we can use it. - * This path is used for drivers which need strict bounds checking. - */ - max_element = ctx->Array.ArrayObj->_MaxElement; - } - else { - /* Generally, hardware drivers don't need to know the buffer bounds - * if all vertex attributes are in VBOs. - * However, if none of vertex attributes are in VBOs, _MaxElement - * is always set to some random big number anyway, so bounds checking - * is mostly useless. - * - * This is only useful to catch invalid values in the "end" parameter - * like ~0. - */ - max_element = 2 * 1000 * 1000 * 1000; /* just a big number */ - } - - if ((int) end + basevertex < 0 || - start + basevertex >= max_element) { - /* The application requested we draw using a range of indices that's - * outside the bounds of the current VBO. This is invalid and appears - * to give undefined results. The safest thing to do is to simply - * ignore the range, in case the application botched their range tracking - * but did provide valid indices. Also issue a warning indicating that - * the application is broken. - */ - if (warnCount++ < 10) { - _mesa_warning(ctx, "glDrawRangeElements(start %u, end %u, " - "basevertex %d, count %d, type 0x%x, indices=%p):\n" - "\trange is outside VBO bounds (max=%u); ignoring.\n" - "\tThis should be fixed in the application.", - start, end, basevertex, count, type, indices, - max_element - 1); - } - index_bounds_valid = GL_FALSE; - } - - /* NOTE: It's important that 'end' is a reasonable value. - * in _tnl_draw_prims(), we use end to determine how many vertices - * to transform. If it's too large, we can unnecessarily split prims - * or we can read/write out of memory in several different places! - */ - - /* Catch/fix some potential user errors */ - if (type == GL_UNSIGNED_BYTE) { - start = MIN2(start, 0xff); - end = MIN2(end, 0xff); - } - else if (type == GL_UNSIGNED_SHORT) { - start = MIN2(start, 0xffff); - end = MIN2(end, 0xffff); - } - - if (0) { - printf("glDraw[Range]Elements{,BaseVertex}" - "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, " - "base %d\n", - start, end, type, count, - ctx->Array.ArrayObj->ElementArrayBufferObj->Name, - basevertex); - } - - if ((int) start + basevertex < 0 || - end + basevertex >= max_element) - index_bounds_valid = GL_FALSE; - -#if 0 - check_draw_elements_data(ctx, count, type, indices); -#else - (void) check_draw_elements_data; -#endif - - vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, - count, type, indices, basevertex, 1, 0); -} - - -/** - * Called by glDrawRangeElements() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, const GLvoid *indices) -{ - if (MESA_VERBOSE & VERBOSE_DRAW) { - GET_CURRENT_CONTEXT(ctx); - _mesa_debug(ctx, - "glDrawRangeElements(%s, %u, %u, %d, %s, %p)\n", - _mesa_lookup_enum_by_nr(mode), start, end, count, - _mesa_lookup_enum_by_nr(type), indices); - } - - vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, - indices, 0); -} - - -/** - * Called by glDrawElements() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElements(%s, %u, %s, %p)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices); - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 )) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, 0, 1, 0); -} - - -/** - * Called by glDrawElementsBaseVertex() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElementsBaseVertex(%s, %d, %s, %p, %d)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices, basevertex); - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, - basevertex )) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, basevertex, 1, 0); -} - - -/** - * Called by glDrawElementsInstanced() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices, numInstances); - - if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, 0)) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, 0, numInstances, 0); -} - - -/** - * Called by glDrawElementsInstancedBaseVertex() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances, - GLint basevertex) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElementsInstancedBaseVertex(%s, %d, %s, %p, %d; %d)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices, - numInstances, basevertex); - - if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, basevertex)) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, basevertex, numInstances, 0); -} - - -/** - * Called by glDrawElementsInstancedBaseInstance() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances, - GLuint baseInstance) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices, - numInstances, baseInstance); - - if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, 0)) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, 0, numInstances, - baseInstance); -} - - -/** - * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode. - */ -static void GLAPIENTRY -vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances, - GLint basevertex, GLuint baseInstance) -{ - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n", - _mesa_lookup_enum_by_nr(mode), count, - _mesa_lookup_enum_by_nr(type), indices, - numInstances, basevertex, baseInstance); - - if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices, - numInstances, basevertex)) - return; - - vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0, - count, type, indices, basevertex, numInstances, - baseInstance); -} - - -/** - * Inner support for both _mesa_MultiDrawElements() and - * _mesa_MultiDrawRangeElements(). - * This does the actual rendering after we've checked array indexes, etc. - */ -static void -vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid * const *indices, - GLsizei primcount, - const GLint *basevertex) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct _mesa_index_buffer ib; - struct _mesa_prim *prim; - unsigned int index_type_size = vbo_sizeof_ib_type(type); - uintptr_t min_index_ptr, max_index_ptr; - GLboolean fallback = GL_FALSE; - int i; - - if (primcount == 0) - return; - - prim = calloc(1, primcount * sizeof(*prim)); - if (prim == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); - return; - } - - vbo_bind_arrays(ctx); - - min_index_ptr = (uintptr_t)indices[0]; - max_index_ptr = 0; - for (i = 0; i < primcount; i++) { - min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]); - max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] + - index_type_size * count[i]); - } - - /* Check if we can handle this thing as a bunch of index offsets from the - * same index pointer. If we can't, then we have to fall back to doing - * a draw_prims per primitive. - * Check that the difference between each prim's indexes is a multiple of - * the index/element size. - */ - if (index_type_size != 1) { - for (i = 0; i < primcount; i++) { - if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) { - fallback = GL_TRUE; - break; - } - } - } - - /* If the index buffer isn't in a VBO, then treating the application's - * subranges of the index buffer as one large index buffer may lead to - * us reading unmapped memory. - */ - if (!_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) - fallback = GL_TRUE; - - if (!fallback) { - ib.count = (max_index_ptr - min_index_ptr) / index_type_size; - ib.type = type; - ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; - ib.ptr = (void *)min_index_ptr; - - for (i = 0; i < primcount; i++) { - prim[i].begin = (i == 0); - prim[i].end = (i == primcount - 1); - prim[i].weak = 0; - prim[i].pad = 0; - prim[i].mode = mode; - prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size; - prim[i].count = count[i]; - prim[i].indexed = 1; - prim[i].num_instances = 1; - prim[i].base_instance = 0; - if (basevertex != NULL) - prim[i].basevertex = basevertex[i]; - else - prim[i].basevertex = 0; - } - - check_buffers_are_unmapped(exec->array.inputs); - vbo_handle_primitive_restart(ctx, prim, primcount, &ib, - GL_FALSE, ~0, ~0); - } else { - /* render one prim at a time */ - for (i = 0; i < primcount; i++) { - ib.count = count[i]; - ib.type = type; - ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj; - ib.ptr = indices[i]; - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count[i]; - prim[0].indexed = 1; - prim[0].num_instances = 1; - prim[0].base_instance = 0; - if (basevertex != NULL) - prim[0].basevertex = basevertex[i]; - else - prim[0].basevertex = 0; - - check_buffers_are_unmapped(exec->array.inputs); - vbo_handle_primitive_restart(ctx, prim, 1, &ib, - GL_FALSE, ~0, ~0); - } - } - - free(prim); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { - _mesa_flush(ctx); - } -} - - -static void GLAPIENTRY -vbo_exec_MultiDrawElements(GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid * const *indices, - GLsizei primcount) -{ - GET_CURRENT_CONTEXT(ctx); - - if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount, NULL)) - return; - - vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, - NULL); -} - - -static void GLAPIENTRY -vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid * const *indices, - GLsizei primcount, - const GLsizei *basevertex) -{ - GET_CURRENT_CONTEXT(ctx); - - if (!_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount, basevertex)) - return; - - vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount, - basevertex); -} - -static void -vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj, - GLuint stream, GLuint numInstances) -{ - struct vbo_context *vbo = vbo_context(ctx); - struct vbo_exec_context *exec = &vbo->exec; - struct _mesa_prim prim[2]; - - if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, - numInstances)) { - return; - } - - vbo_bind_arrays(ctx); - - /* init most fields to zero */ - memset(prim, 0, sizeof(prim)); - prim[0].begin = 1; - prim[0].end = 1; - prim[0].mode = mode; - prim[0].num_instances = numInstances; - prim[0].base_instance = 0; - - /* Maybe we should do some primitive splitting for primitive restart - * (like in DrawArrays), but we have no way to know how many vertices - * will be rendered. */ - - check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, prim, 1, NULL, - GL_TRUE, 0, 0, obj); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { - _mesa_flush(ctx); - } -} - -/** - * Like DrawArrays, but take the count from a transform feedback object. - * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. - * \param name the transform feedback object - * User still has to setup of the vertex attribute info with - * glVertexPointer, glColorPointer, etc. - * Part of GL_ARB_transform_feedback2. - */ -static void GLAPIENTRY -vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", - _mesa_lookup_enum_by_nr(mode), name); - - vbo_draw_transform_feedback(ctx, mode, obj, 0, 1); -} - -static void GLAPIENTRY -vbo_exec_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawTransformFeedbackStream(%s, %u, %u)\n", - _mesa_lookup_enum_by_nr(mode), name, stream); - - vbo_draw_transform_feedback(ctx, mode, obj, stream, 1); -} - -static void GLAPIENTRY -vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, - GLsizei primcount) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", - _mesa_lookup_enum_by_nr(mode), name); - - vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount); -} - -static void GLAPIENTRY -vbo_exec_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, - GLuint stream, GLsizei primcount) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - if (MESA_VERBOSE & VERBOSE_DRAW) - _mesa_debug(ctx, "glDrawTransformFeedbackStreamInstanced" - "(%s, %u, %u, %i)\n", - _mesa_lookup_enum_by_nr(mode), name, stream, primcount); - - vbo_draw_transform_feedback(ctx, mode, obj, stream, primcount); -} - - -/** - * Initialize the dispatch table with the VBO functions for drawing. - */ -void -vbo_initialize_exec_dispatch(const struct gl_context *ctx, - struct _glapi_table *exec) -{ - SET_DrawArrays(exec, vbo_exec_DrawArrays); - SET_DrawElements(exec, vbo_exec_DrawElements); - - if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { - SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements); - } - - SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements); - - if (ctx->API == API_OPENGL_COMPAT) { - SET_Rectf(exec, vbo_exec_Rectf); - SET_EvalMesh1(exec, vbo_exec_EvalMesh1); - SET_EvalMesh2(exec, vbo_exec_EvalMesh2); - } - - if (_mesa_is_desktop_gl(ctx)) { - SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex); - SET_DrawRangeElementsBaseVertex(exec, vbo_exec_DrawRangeElementsBaseVertex); - SET_MultiDrawElementsBaseVertex(exec, vbo_exec_MultiDrawElementsBaseVertex); - SET_DrawArraysInstancedBaseInstance(exec, vbo_exec_DrawArraysInstancedBaseInstance); - SET_DrawElementsInstancedBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseInstance); - SET_DrawElementsInstancedBaseVertex(exec, vbo_exec_DrawElementsInstancedBaseVertex); - SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance); - } - - if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { - SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced); - SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced); - } - - if (_mesa_is_desktop_gl(ctx)) { - SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback); - SET_DrawTransformFeedbackStream(exec, vbo_exec_DrawTransformFeedbackStream); - SET_DrawTransformFeedbackInstanced(exec, vbo_exec_DrawTransformFeedbackInstanced); - SET_DrawTransformFeedbackStreamInstanced(exec, vbo_exec_DrawTransformFeedbackStreamInstanced); - } -} - - - -/** - * The following functions are only used for OpenGL ES 1/2 support. - * And some aren't even supported (yet) in ES 1/2. - */ - - -void GLAPIENTRY -_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) -{ - vbo_exec_DrawArrays(mode, first, count); -} - - -void GLAPIENTRY -_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - vbo_exec_DrawElements(mode, count, type, indices); -} - - -void GLAPIENTRY -_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex); -} - - -void GLAPIENTRY -_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices) -{ - vbo_exec_DrawRangeElements(mode, start, end, count, type, indices); -} - - -void GLAPIENTRY -_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type, - indices, basevertex); -} - - -void GLAPIENTRY -_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount) -{ - vbo_exec_MultiDrawElements(mode, count, type, indices, primcount); -} - - -void GLAPIENTRY -_mesa_MultiDrawElementsBaseVertex(GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid **indices, GLsizei primcount, - const GLint *basevertex) -{ - vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, - primcount, basevertex); -} - -void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name) -{ - vbo_exec_DrawTransformFeedback(mode, name); -} diff --git a/contrib/sdk/sources/Mesa/src/mesa/x86/matypes.h.bak b/contrib/sdk/sources/Mesa/src/mesa/x86/matypes.h.bak deleted file mode 100644 index b38650b482..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/x86/matypes.h.bak +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is automatically generated from the Mesa internal type - * definitions. Do not edit directly. - */ - -#ifndef __ASM_TYPES_H__ -#define __ASM_TYPES_H__ - - - -/* ============================================================= - * Offsets for struct gl_context - */ - - -#define CTX_LIGHT_ENABLED 8776 -#define CTX_LIGHT_SHADE_MODEL 8780 -#define CTX_LIGHT_COLOR_MAT_FACE 8788 -#define CTX_LIGHT_COLOR_MAT_MODE 8792 -#define CTX_LIGHT_COLOR_MAT_MASK 8796 -#define CTX_LIGHT_COLOR_MAT_ENABLED 8800 -#define CTX_LIGHT_ENABLED_LIST 8816 -#define CTX_LIGHT_NEED_VERTS 9081 -#define CTX_LIGHT_BASE_COLOR 9084 - - -/* ============================================================= - * Offsets for struct vertex_buffer - */ - -#define VB_SIZE 0 -#define VB_COUNT 4 - -#define VB_ELTS 8 -#define VB_OBJ_PTR 112 -#define VB_EYE_PTR 16 -#define VB_CLIP_PTR 24 -#define VB_PROJ_CLIP_PTR 32 -#define VB_CLIP_OR_MASK 40 -#define VB_CLIP_MASK 48 -#define VB_NORMAL_PTR 128 -#define VB_EDGE_FLAG 64 -#define VB_TEX0_COORD_PTR 176 -#define VB_TEX1_COORD_PTR 184 -#define VB_TEX2_COORD_PTR 192 -#define VB_TEX3_COORD_PTR 200 -#define VB_INDEX_PTR 160 -#define VB_COLOR_PTR 136 -#define VB_SECONDARY_COLOR_PTR 144 -#define VB_FOG_COORD_PTR 152 -#define VB_PRIMITIVE 96 - - -/* - * Flags for struct vertex_buffer - */ - -#define VERT_BIT_OBJ 0x1 -#define VERT_BIT_NORM 0x4 -#define VERT_BIT_RGBA 0x8 -#define VERT_BIT_SPEC_RGB 0x10 -#define VERT_BIT_FOG_COORD 0x20 -#define VERT_BIT_TEX0 0x100 -#define VERT_BIT_TEX1 0x200 -#define VERT_BIT_TEX2 0x400 -#define VERT_BIT_TEX3 0x800 - - -/* ============================================================= - * Offsets for GLvector4f - */ - -#define V4F_DATA 0 -#define V4F_START 8 -#define V4F_COUNT 16 -#define V4F_STRIDE 20 -#define V4F_SIZE 24 -#define V4F_FLAGS 28 - -/* - * Flags for GLvector4f - */ - -#define VEC_MALLOC 0x10 -#define VEC_NOT_WRITEABLE 0x40 -#define VEC_BAD_STRIDE 0x100 - -#define VEC_SIZE_1 0x1 -#define VEC_SIZE_2 0x3 -#define VEC_SIZE_3 0x7 -#define VEC_SIZE_4 0xf - - -/* ============================================================= - * Offsets for GLmatrix - */ - -#define MATRIX_DATA 0 -#define MATRIX_INV 8 -#define MATRIX_FLAGS 16 -#define MATRIX_TYPE 20 - - -/* ============================================================= - * Offsets for struct gl_light - */ - -#define LIGHT_NEXT 0 -#define LIGHT_PREV 8 - -#define LIGHT_AMBIENT 16 -#define LIGHT_DIFFUSE 32 -#define LIGHT_SPECULAR 48 -#define LIGHT_EYE_POSITION 64 -#define LIGHT_SPOT_DIRECTION 80 -#define LIGHT_SPOT_EXPONENT 96 -#define LIGHT_SPOT_CUTOFF 100 -#define LIGHT_COS_CUTOFF 104 -#define LIGHT_CONST_ATTEN 108 -#define LIGHT_LINEAR_ATTEN 112 -#define LIGHT_QUADRATIC_ATTEN 116 -#define LIGHT_ENABLED 120 - -#define LIGHT_FLAGS 124 - -#define LIGHT_POSITION 128 -#define LIGHT_VP_INF_NORM 144 -#define LIGHT_H_INF_NORM 156 -#define LIGHT_NORM_DIRECTION 168 -#define LIGHT_VP_INF_SPOT_ATTEN 184 - -#define LIGHT_MAT_AMBIENT 188 -#define LIGHT_MAT_DIFFUSE 212 -#define LIGHT_MAT_SPECULAR 236 - -#define SIZEOF_GL_LIGHT 264 - -/* - * Flags for struct gl_light - */ - -#define LIGHT_SPOT 0x1 -#define LIGHT_LOCAL_VIEWER 0x2 -#define LIGHT_POSITIONAL 0x4 - -#define LIGHT_NEED_VERTICES 0x6 - - -/* ============================================================= - * Offsets for struct gl_lightmodel - */ - -#define LIGHT_MODEL_AMBIENT 0 -#define LIGHT_MODEL_LOCAL_VIEWER 16 -#define LIGHT_MODEL_TWO_SIDE 17 -#define LIGHT_MODEL_COLOR_CONTROL 20 - - -#endif /* __ASM_TYPES_H__ */ diff --git a/contrib/sdk/sources/Mesa/src/mesa/x86/mmx_blend.S.bak b/contrib/sdk/sources/Mesa/src/mesa/x86/mmx_blend.S.bak deleted file mode 100644 index 038adbeccb..0000000000 --- a/contrib/sdk/sources/Mesa/src/mesa/x86/mmx_blend.S.bak +++ /dev/null @@ -1,401 +0,0 @@ - ; -/* - * Written by Jos� Fonseca - */ - -#ifdef USE_MMX_ASM -#include "assyntax.h" -#include "matypes.h" - -/* integer multiplication - alpha plus one - * - * makes the following approximation to the division (Sree) - * - * rgb*a/255 ~= (rgb*(a+1)) >> 256 - * - * which is the fastest method that satisfies the following OpenGL criteria - * - * 0*0 = 0 and 255*255 = 255 - * - * note that MX1 is a register with 0xffffffffffffffff constant which can be easily obtained making - * - * PCMPEQW ( MX1, MX1 ) - */ -#define GMB_MULT_AP1( MP1, MA1, MP2, MA2, MX1 ) \ - PSUBW ( MX1, MA1 ) /* a1 + 1 | a1 + 1 | a1 + 1 | a1 + 1 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ - ;\ -TWO(PSUBW ( MX1, MA2 )) /* a2 + 1 | a2 + 1 | a2 + 1 | a2 + 1 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 ~= t1/255 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 ~= t2/255 */ - - -/* integer multiplication - geometric series - * - * takes the geometric series approximation to the division - * - * t/255 = (t >> 8) + (t >> 16) + (t >> 24) .. - * - * in this case just the first two terms to fit in 16bit arithmetic - * - * t/255 ~= (t + (t >> 8)) >> 8 - * - * note that just by itself it doesn't satisfies the OpenGL criteria, as 255*255 = 254, - * so the special case a = 255 must be accounted or roundoff must be used - */ -#define GMB_MULT_GS( MP1, MA1, MP2, MA2 ) \ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* integer multiplication - geometric series plus rounding - * - * when using a geometric series division instead of truncating the result - * use roundoff in the approximation (Jim Blinn) - * - * t = rgb*a + 0x80 - * - * achieving the exact results - * - * note that M80 is register with the 0x0080008000800080 constant - */ -#define GMB_MULT_GSR( MP1, MA1, MP2, MA2, M80 ) \ - PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\ - PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\ - ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\ -TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series - */ -#define GMB_LERP_GS( MP1, MQ1, MA1, MP2, MQ2, MA2) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series with roundoff - * - * this is a generalization of Blinn's formula to signed arithmetic - * - * note that M80 is a register with the 0x0080008000800080 constant - */ -#define GMB_LERP_GSR( MP1, MQ1, MA1, MP2, MQ2, MA2, M80) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - PSRLW ( CONST(15), MP1 ) /* q1 > p1 ? 1 : 0 */ ;\ -TWO(PSRLW ( CONST(15), MP2 )) /* q2 > q2 ? 1 : 0 */ ;\ - ;\ - PSLLW ( CONST(8), MP1 ) /* q1 > p1 ? 0x100 : 0 */ ;\ -TWO(PSLLW ( CONST(8), MP2 )) /* q2 > q2 ? 0x100 : 0 */ ;\ - ;\ - PSUBW ( MP1, MA1 ) /* t1 -=? 0x100 */ ;\ -TWO(PSUBW ( MP2, MA2 )) /* t2 -=? 0x100 */ ;\ - ;\ - PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\ -TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* linear interpolation - geometric series with correction - * - * instead of the roundoff this adds a small correction to satisfy the OpenGL criteria - * - * t/255 ~= (t + (t >> 8) + (t >> 15)) >> 8 - * - * note that although is faster than rounding off it doesn't give always the exact results - */ -#define GMB_LERP_GSC( MP1, MQ1, MA1, MP2, MQ2, MA2) \ - PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\ - PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\ - PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\ - ;\ -TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\ -TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\ -TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\ - ;\ - MOVQ ( MA1, MP1 ) ;\ - PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\ - ;\ -TWO(MOVQ ( MA2, MP2 )) ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\ - ;\ - PADDW ( MA1, MP1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\ - PSRLW ( CONST(7), MA1 ) /* t1 >> 15 */ ;\ - ;\ -TWO(PADDW ( MA2, MP2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\ -TWO(PSRLW ( CONST(7), MA2 )) /* t2 >> 15 */ ;\ - ;\ - PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) + (t1 >>15) ~= (t1/255) << 8 */ ;\ -TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) + (t2 >>15) ~= (t2/255) << 8 */ ;\ - ;\ - PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\ -TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\ - ;\ - PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */ - - -/* common blending setup code - * - * note that M00 is a register with 0x0000000000000000 constant which can be easily obtained making - * - * PXOR ( M00, M00 ) - */ -#define GMB_LOAD(rgba, dest, MPP, MQQ) \ -ONE(MOVD ( REGIND(rgba), MPP )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\ -ONE(MOVD ( REGIND(dest), MQQ )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\ - ;\ -TWO(MOVQ ( REGIND(rgba), MPP )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(MOVQ ( REGIND(dest), MQQ )) /* pa2 | pb2 | pg2 | pr2 | pa1 | pb1 | pg1 | pr1 */ - -#define GMB_UNPACK(MP1, MQ1, MP2, MQ2, M00) \ -TWO(MOVQ ( MP1, MP2 )) ;\ -TWO(MOVQ ( MQ1, MQ2 )) ;\ - ;\ - PUNPCKLBW ( M00, MQ1 ) /* qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(PUNPCKHBW ( M00, MQ2 )) /* qa2 | qb2 | qg2 | qr2 */ ;\ - PUNPCKLBW ( M00, MP1 ) /* pa1 | pb1 | pg1 | pr1 */ ;\ -TWO(PUNPCKHBW ( M00, MP2 )) /* pa2 | pb2 | pg2 | pr2 */ - -#define GMB_ALPHA(MP1, MA1, MP2, MA2) \ - MOVQ ( MP1, MA1 ) ;\ -TWO(MOVQ ( MP2, MA2 )) ;\ - ;\ - PUNPCKHWD ( MA1, MA1 ) /* pa1 | pa1 | | */ ;\ -TWO(PUNPCKHWD ( MA2, MA2 )) /* pa2 | pa2 | | */ ;\ - PUNPCKHDQ ( MA1, MA1 ) /* pa1 | pa1 | pa1 | pa1 */ ;\ -TWO(PUNPCKHDQ ( MA2, MA2 )) /* pa2 | pa2 | pa2 | pa2 */ - -#define GMB_PACK( MS1, MS2 ) \ - PACKUSWB ( MS2, MS1 ) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\ - -#define GMB_STORE(rgba, MSS ) \ -ONE(MOVD ( MSS, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(MOVQ ( MSS, REGIND(rgba) )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ - -/* Kevin F. Quinn 2 July 2006 - * Replace data segment constants with text-segment - * constants (via pushl/movq) - SEG_DATA - -ALIGNDATA8 -const_0080: - D_LONG 0x00800080, 0x00800080 - -const_80: - D_LONG 0x80808080, 0x80808080 -*/ -#define const_0080_l 0x00800080 -#define const_0080_h 0x00800080 -#define const_80_l 0x80808080 -#define const_80_h 0x80808080 - - SEG_TEXT - - -/* Blend transparency function - */ - -#define TAG(x) CONCAT(x,_transparency) -#define LLTAG(x) LLBL2(x,_transparency) - -#define INIT \ - PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\ - GMB_ALPHA( MM1, MM3, MM4, MM6 ) ;\ - GMB_LERP_GSC( MM1, MM2, MM3, MM4, MM5, MM6 ) ;\ - GMB_PACK( MM3, MM6 ) ;\ - GMB_STORE( rgba, MM3 ) - -#include "mmx_blendtmp.h" - - -/* Blend add function - * - * FIXME: Add some loop unrolling here... - */ - -#define TAG(x) CONCAT(x,_add) -#define LLTAG(x) LLBL2(x,_add) - -#define INIT - -#define MAIN( rgba, dest ) \ -ONE(MOVD ( REGIND(rgba), MM1 )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\ -ONE(MOVD ( REGIND(dest), MM2 )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\ -ONE(PADDUSB ( MM2, MM1 )) ;\ -ONE(MOVD ( MM1, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ - ;\ -TWO(MOVQ ( REGIND(rgba), MM1 )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\ -TWO(PADDUSB ( REGIND(dest), MM1 )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\ -TWO(MOVQ ( MM1, REGIND(rgba) )) - -#include "mmx_blendtmp.h" - - -/* Blend min function - */ - -#define TAG(x) CONCAT(x,_min) -#define LLTAG(x) LLBL2(x,_min) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_80), MM7 ) - */ -#define INIT \ - PUSH_L ( CONST(const_80_h) ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ ;\ - PUSH_L ( CONST(const_80_l) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - MOVQ ( MM1, MM3 ) ;\ - MOVQ ( MM2, MM4 ) ;\ - PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ - PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ - PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ - PAND ( MM4, MM1 ) /* q > p ? p : 0 */ ;\ - PANDN ( MM2, MM4 ) /* q > p ? 0 : q */ ;\ - POR ( MM1, MM4 ) /* q > p ? p : q */ ;\ - GMB_STORE( rgba, MM4 ) - -#include "mmx_blendtmp.h" - - -/* Blend max function - */ - -#define TAG(x) CONCAT(x,_max) -#define LLTAG(x) LLBL2(x,_max) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_80), MM7 ) - */ -#define INIT \ - PUSH_L ( CONST(const_80_l) ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ ;\ - PUSH_L ( CONST(const_80_h) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - MOVQ ( MM1, MM3 ) ;\ - MOVQ ( MM2, MM4 ) ;\ - PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ - PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ - PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ - PAND ( MM4, MM2 ) /* q > p ? q : 0 */ ;\ - PANDN ( MM1, MM4 ) /* q > p ? 0 : p */ ;\ - POR ( MM2, MM4 ) /* q > p ? p : q */ ;\ - GMB_STORE( rgba, MM4 ) - -#include "mmx_blendtmp.h" - - -/* Blend modulate function - */ - -#define TAG(x) CONCAT(x,_modulate) -#define LLTAG(x) LLBL2(x,_modulate) - -/* Kevin F. Quinn 2nd July 2006 - * Replace data segment constants with text-segment instructions -#define INIT \ - MOVQ ( CONTENT(const_0080), MM7 ) - */ -#define INIT \ - PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ ;\ - PUSH_L ( CONST(const_0080_l) ) /* 0x0080 | 0x0080 | 0x0080 | 0x0080 */ ;\ - PUSH_L ( CONST(const_0080_h) ) ;\ - MOVQ ( REGIND(ESP), MM7 ) ;\ - ADD_L ( CONST(8), ESP) - -#define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\ - GMB_MULT_GSR( MM1, MM2, MM4, MM5, MM7 ) ;\ - GMB_PACK( MM2, MM5 ) ;\ - GMB_STORE( rgba, MM2 ) - -#include "mmx_blendtmp.h" - -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif