diff options
Diffstat (limited to 'src')
1365 files changed, 63107 insertions, 41998 deletions
diff --git a/src/SConscript b/src/SConscript index 6083fcbec9..cd4896ada4 100644 --- a/src/SConscript +++ b/src/SConscript @@ -8,5 +8,6 @@ if 'mesa' in env['statetrackers']: SConscript('gallium/winsys/SConscript') -SConscript('glut/glx/SConscript') -SConscript('glew/SConscript') +if platform != 'embedded': + SConscript('glut/glx/SConscript') + SConscript('glew/SConscript') diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template new file mode 100644 index 0000000000..e9a614ce62 --- /dev/null +++ b/src/egl/drivers/Makefile.template @@ -0,0 +1,51 @@ +# src/egl/drivers/Makefile.template +# +# Drivers should define +# +# EGL_DRIVER, the driver name +# EGL_SOURCES, the driver sources +# EGL_INCLUDES, the include pathes +# EGL_CFLAGS, additional CFLAGS +# EGL_LIBS, additional LIBS +# +# before including this template. +# + + +EGL_DRIVER_PATH = $(TOP)/$(LIB_DIR)/$(EGL_DRIVER) +EGL_OBJECTS = $(EGL_SOURCES:.c=.o) + + +default: depend $(EGL_DRIVER_PATH) + +$(EGL_DRIVER_PATH): $(EGL_DRIVER) + $(INSTALL) $< $(TOP)/$(LIB_DIR) + +$(EGL_DRIVER): $(EGL_OBJECTS) Makefile $(TOP)/src/egl/drivers/Makefile.template + @$(MKLIB) -o $(EGL_DRIVER) -noprefix \ + -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -L$(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + $(EGL_OBJECTS) $(EGL_LIBS) + +.c.o: + $(CC) -c $(EGL_INCLUDES) $(CFLAGS) $(EGL_CFLAGS) $< -o $@ + + +install: $(EGL_DRIVER_PATH) + $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) + $(MINSTALL) $(EGL_DRIVER_PATH) $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) + +clean: + rm -f $(EGL_DRIVER) + rm -f $(EGL_OBJECTS) + rm -f depend depend.bak + +depend: $(EGL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(EGL_INCLUDES) $(EGL_SOURCES) \ + >/dev/null 2>/dev/null + +sinclude depend +# DO NOT DELETE diff --git a/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile deleted file mode 100644 index 444dfb35bd..0000000000 --- a/src/egl/drivers/demo/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# src/egl/drivers/demo/Makefile - -TOP = ../../../.. -include $(TOP)/configs/current - - -INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main $(X11_INCLUDES) - - -SOURCES = demo.c - -OBJECTS = $(SOURCES:.c=.o) - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - - -default: $(TOP)/$(LIB_DIR)/demodriver.so - - -$(TOP)/$(LIB_DIR)/demodriver.so: $(OBJECTS) - $(MKLIB) -o demodriver.so -noprefix -linker '$(CC)' \ - -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) - -install: - -clean: - -rm -f *.o - -rm -f *.so diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c deleted file mode 100644 index 0933c0bdaa..0000000000 --- a/src/egl/drivers/demo/demo.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Sample driver: Demo - */ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" - - -/** - * Demo driver-specific driver class derived from _EGLDriver - */ -typedef struct demo_driver -{ - _EGLDriver Base; /* base class/object */ - unsigned DemoStuff; -} DemoDriver; - -#define DEMO_DRIVER(D) ((DemoDriver *) (D)) - - -/** - * Demo driver-specific surface class derived from _EGLSurface - */ -typedef struct demo_surface -{ - _EGLSurface Base; /* base class/object */ - unsigned DemoStuff; -} DemoSurface; - - -/** - * Demo driver-specific context class derived from _EGLContext - */ -typedef struct demo_context -{ - _EGLContext Base; /* base class/object */ - unsigned DemoStuff; -} DemoContext; - - - -static EGLBoolean -demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) -{ - _EGLScreen *scrn; - EGLint i; - - /* Create a screen */ - scrn = calloc(1, sizeof(*scrn)); - _eglAddScreen(disp, scrn); - - /* Create the screen's modes - silly example */ - _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72"); - _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70"); - _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70"); - _eglAddNewMode(scrn, 1024, 768, 72 * 1000, "1024x768-72"); - - /* Create the display's visual configs - silly example */ - for (i = 0; i < 4; i++) { - _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); - _eglInitConfig(config, i + 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - if (i & 1) { - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32); - } - if (i & 2) { - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - } - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, - (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)); - _eglAddConfig(disp, config); - } - - /* enable supported extensions */ - disp->Extensions.MESA_screen_surface = EGL_TRUE; - disp->Extensions.MESA_copy_context = EGL_TRUE; - - *major = 1; - *minor = 0; - - return EGL_TRUE; -} - - -static EGLBoolean -demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - return EGL_TRUE; -} - - -static DemoContext * -LookupDemoContext(_EGLContext *c) -{ - return (DemoContext *) c; -} - - -static DemoSurface * -LookupDemoSurface(_EGLSurface *s) -{ - return (DemoSurface *) s; -} - - -static _EGLContext * -demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) -{ - DemoContext *c; - int i; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return NULL; - } - } - - c = (DemoContext *) calloc(1, sizeof(DemoContext)); - if (!c) - return NULL; - - _eglInitContext(drv, &c->Base, conf, attrib_list); - c->DemoStuff = 1; - printf("demoCreateContext\n"); - - return &c->Base; -} - - -static _EGLSurface * -demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) -{ - int i; - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface"); - return NULL; - } - } - printf("eglCreateWindowSurface()\n"); - /* XXX unfinished */ - - return NULL; -} - - -static _EGLSurface * -demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) -{ - EGLint i; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - return NULL; - } - } - - if (GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) == 0) { - _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); - return NULL; - } - - printf("eglCreatePixmapSurface()\n"); - return NULL; -} - - -static _EGLSurface * -demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface)); - - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, - conf, attrib_list)) { - free(surf); - return NULL; - } - - /* a real driver would allocate the pbuffer memory here */ - - return &surf->Base; -} - - -static EGLBoolean -demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - DemoSurface *fs = LookupDemoSurface(surface); - if (!_eglIsSurfaceBound(&fs->Base)) - free(fs); - return EGL_TRUE; -} - - -static EGLBoolean -demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) -{ - DemoContext *fc = LookupDemoContext(context); - if (!_eglIsContextBound(&fc->Base)) - free(fc); - return EGL_TRUE; -} - - -static EGLBoolean -demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx) -{ - /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx); - if (!b) - return EGL_FALSE; - - /* XXX this is where we'd do the hardware context switch */ - (void) drawSurf; - (void) readSurf; - (void) ctx; - - printf("eglMakeCurrent()\n"); - return EGL_TRUE; -} - - -static void -demoUnload(_EGLDriver *drv) -{ - free(drv); -} - - -/** - * The bootstrap function. Return a new DemoDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(const char *args) -{ - DemoDriver *demo; - - demo = (DemoDriver *) calloc(1, sizeof(DemoDriver)); - if (!demo) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&demo->Base); - /* then plug in our Demo-specific functions */ - demo->Base.API.Initialize = demoInitialize; - demo->Base.API.Terminate = demoTerminate; - demo->Base.API.CreateContext = demoCreateContext; - demo->Base.API.MakeCurrent = demoMakeCurrent; - demo->Base.API.CreateWindowSurface = demoCreateWindowSurface; - demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface; - demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface; - demo->Base.API.DestroySurface = demoDestroySurface; - demo->Base.API.DestroyContext = demoDestroyContext; - - demo->Base.Name = "egl/demo"; - demo->Base.Unload = demoUnload; - - return &demo->Base; -} diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile new file mode 100644 index 0000000000..129e67b8c6 --- /dev/null +++ b/src/egl/drivers/dri2/Makefile @@ -0,0 +1,18 @@ +# src/egl/drivers/dri2/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + +EGL_DRIVER = egl_dri2.so +EGL_SOURCES = egl_dri2.c + +EGL_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/mesa \ + -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \ + $(EGL_DRI2_CFLAGS) + +EGL_LIBS = $(EGL_DRI2_LIBS) + +include ../Makefile.template diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c new file mode 100644 index 0000000000..92378892e5 --- /dev/null +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -0,0 +1,974 @@ +/* + * 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 <krh@bitplanet.net> + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <limits.h> +#include <dlfcn.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <xf86drm.h> +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> +#include <xcb/xcb.h> +#include <xcb/dri2.h> +#include <xcb/xfixes.h> +#include <X11/Xlib-xcb.h> + +#include <glapi/glapi.h> +#include "eglconfigutil.h" +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglcurrent.h" +#include "egllog.h" +#include "eglsurface.h" + +struct dri2_egl_driver +{ + _EGLDriver base; +}; + +struct dri2_egl_display +{ + xcb_connection_t *conn; + int dri2_major; + int dri2_minor; + __DRIscreen *dri_screen; + void *driver; + __DRIcoreExtension *core; + __DRIdri2Extension *dri2; + __DRI2flushExtension *flush; + int fd; + + __DRIdri2LoaderExtension loader_extension; + const __DRIextension *extensions[2]; +}; + +struct dri2_egl_context +{ + _EGLContext base; + __DRIcontext *dri_context; +}; + +struct dri2_egl_surface +{ + _EGLSurface base; + __DRIdrawable *dri_drawable; + xcb_drawable_t drawable; + __DRIbuffer buffers[5]; + int buffer_count; + xcb_xfixes_region_t region; + int have_back; + int have_fake_front; + int swap_interval; +}; + +struct dri2_egl_config +{ + _EGLConfig base; + const __DRIconfig *dri_config; +}; + +/* standard typecasts */ +_EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl) + +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 */ + 0, /* __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 */ + 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 */ + 0, /* __DRI_ATTRIB_YINVERTED */ +}; + +static void +dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id) +{ + struct dri2_egl_config *conf; + struct dri2_egl_display *dri2_dpy; + unsigned int attrib, value, double_buffer; + EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; + int i; + + dri2_dpy = disp->DriverData; + conf = malloc(sizeof *conf); + if (conf == NULL) + return; + + conf->dri_config = dri_config; + _eglInitConfig(&conf->base, disp, id); + + i = 0; + while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { + switch (attrib) { + case 0: + break; + + 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 + /* not valid */; + _eglSetConfigKey(&conf->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(&conf->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; + + default: + key = dri2_to_egl_attribute_map[attrib]; + if (key != 0) + _eglSetConfigKey(&conf->base, key, value); + break; + } + } + + /* EGL_SWAP_BEHAVIOR_PRESERVED_BIT */ + + if (double_buffer) { + /* FIXME: Figure out how to get the visual ID and types */ + _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0x21); + _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, + XCB_VISUAL_CLASS_TRUE_COLOR); + } else { + _eglSetConfigKey(&conf->base, + EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); + _eglSetConfigKey(&conf->base, + EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb); + _eglSetConfigKey(&conf->base, + EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); + } + + /* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */ + _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT); + _eglSetConfigKey(&conf->base, EGL_CONFORMANT, EGL_OPENGL_BIT); + + if (!_eglValidateConfig(&conf->base, EGL_FALSE)) { + _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); + free(conf); + return; + } + + _eglAddConfig(disp, &conf->base); +} + +/** + * Process list of buffer received from the server + * + * Processes the list of buffers received in a reply from the server to either + * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat. + */ +static void +dri2_process_buffers(struct dri2_egl_surface *dri2_surf, + xcb_dri2_dri2_buffer_t *buffers, unsigned count) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + xcb_rectangle_t rectangle; + int i; + + dri2_surf->buffer_count = count; + dri2_surf->have_fake_front = 0; + dri2_surf->have_back = 0; + + /* This assumes the DRI2 buffer attachment tokens matches the + * __DRIbuffer tokens. */ + for (i = 0; i < count; i++) { + dri2_surf->buffers[i].attachment = buffers[i].attachment; + dri2_surf->buffers[i].name = buffers[i].name; + dri2_surf->buffers[i].pitch = buffers[i].pitch; + dri2_surf->buffers[i].cpp = buffers[i].cpp; + dri2_surf->buffers[i].flags = buffers[i].flags; + if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT) + dri2_surf->have_fake_front = 1; + if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) + dri2_surf->have_back = 1; + } + + if (dri2_surf->region != XCB_NONE) + xcb_xfixes_destroy_region(dri2_dpy->conn, dri2_surf->region); + + rectangle.x = 0; + rectangle.y = 0; + rectangle.width = dri2_surf->base.Width; + rectangle.height = dri2_surf->base.Height; + dri2_surf->region = xcb_generate_id(dri2_dpy->conn); + xcb_xfixes_create_region(dri2_dpy->conn, dri2_surf->region, 1, &rectangle); +} + +static __DRIbuffer * +dri2_get_buffers(__DRIdrawable * driDrawable, + int *width, int *height, + unsigned int *attachments, int count, + int *out_count, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + xcb_dri2_dri2_buffer_t *buffers; + xcb_dri2_get_buffers_reply_t *reply; + xcb_dri2_get_buffers_cookie_t cookie; + + cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn, + dri2_surf->drawable, + count, count, attachments); + reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL); + buffers = xcb_dri2_get_buffers_buffers (reply); + if (buffers == NULL) + return NULL; + + *out_count = reply->count; + dri2_surf->base.Width = *width = reply->width; + dri2_surf->base.Height = *height = reply->height; + dri2_process_buffers(dri2_surf, buffers, *out_count); + + free(reply); + + return dri2_surf->buffers; +} + +static void +dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) +{ + /* FIXME: Does EGL support front buffer rendering at all? */ + +#if 0 + struct dri2_egl_surface *dri2_surf = loaderPrivate; + + dri2WaitGL(dri2_surf); +#endif +} + +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; + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + xcb_dri2_dri2_buffer_t *buffers; + xcb_dri2_get_buffers_with_format_reply_t *reply; + xcb_dri2_get_buffers_with_format_cookie_t cookie; + xcb_dri2_attach_format_t *format_attachments; + + format_attachments = (xcb_dri2_attach_format_t *) attachments; + cookie = xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy->conn, + dri2_surf->drawable, + count, count, + format_attachments); + + reply = xcb_dri2_get_buffers_with_format_reply (dri2_dpy->conn, + cookie, NULL); + if (reply == NULL) + return NULL; + + buffers = xcb_dri2_get_buffers_with_format_buffers (reply); + dri2_surf->base.Width = *width = reply->width; + dri2_surf->base.Height = *height = reply->height; + *out_count = reply->count; + dri2_process_buffers(dri2_surf, buffers, *out_count); + + free(reply); + + return dri2_surf->buffers; +} + +#ifdef GLX_USE_TLS +static const char dri_driver_format[] = "%.*s/tls/%.*s_dri.so"; +#else +static const char dri_driver_format[] = "%.*s/%.*s_dri.so"; +#endif + +static const char dri_driver_path[] = DEFAULT_DRIVER_DIR; + +/** + * Called via eglInitialize(), GLX_drv->API.Initialize(). + */ +static EGLBoolean +dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp, + EGLint *major, EGLint *minor) +{ + const __DRIextension **extensions; + const __DRIconfig **driver_configs; + struct dri2_egl_display *dri2_dpy; + char path[PATH_MAX], *search_paths, *p, *next, *end; + xcb_xfixes_query_version_reply_t *xfixes_query; + xcb_xfixes_query_version_cookie_t xfixes_query_cookie; + xcb_dri2_query_version_reply_t *dri2_query; + xcb_dri2_query_version_cookie_t dri2_query_cookie; + xcb_dri2_connect_reply_t *connect; + xcb_dri2_connect_cookie_t connect_cookie; + xcb_dri2_authenticate_reply_t *authenticate; + xcb_dri2_authenticate_cookie_t authenticate_cookie; + xcb_generic_error_t *error; + drm_magic_t magic; + xcb_screen_iterator_t s; + int i; + + dri2_dpy = malloc(sizeof *dri2_dpy); + if (!dri2_dpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + disp->DriverData = (void *) dri2_dpy; + if (disp->NativeDisplay != NULL) + dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay); + else + dri2_dpy->conn = xcb_connect(0, 0); + if (!dri2_dpy->conn) { + _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed"); + goto cleanup_dpy; + } + + xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id); + xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id); + + xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn, + XCB_XFIXES_MAJOR_VERSION, + XCB_XFIXES_MINOR_VERSION); + + dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn, + XCB_DRI2_MAJOR_VERSION, + XCB_DRI2_MINOR_VERSION); + + s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); + connect_cookie = xcb_dri2_connect_unchecked (dri2_dpy->conn, + s.data->root, + XCB_DRI2_DRIVER_TYPE_DRI); + + xfixes_query = + xcb_xfixes_query_version_reply (dri2_dpy->conn, + xfixes_query_cookie, &error); + if (xfixes_query == NULL || + error != NULL || xfixes_query->major_version < 2) { + _eglLog(_EGL_FATAL, "DRI2: failed to query xfixes version"); + free(error); + goto cleanup_conn; + } + free(xfixes_query); + + dri2_query = + xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error); + if (dri2_query == NULL || error != NULL) { + _eglLog(_EGL_FATAL, "DRI2: failed to query version"); + free(error); + goto cleanup_conn; + } + dri2_dpy->dri2_major = dri2_query->major_version; + dri2_dpy->dri2_minor = dri2_query->minor_version; + free(dri2_query); + + connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL); + if (connect == NULL || + connect->driver_name_length + connect->device_name_length == 0) { + _eglLog(_EGL_FATAL, "DRI2: failed to authenticate"); + goto cleanup_connect; + } + + 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) { + next = strchr(p, ':'); + if (next == NULL) + next = end; + + snprintf(path, sizeof path, + dri_driver_format, + (int) (next - p), p, + xcb_dri2_connect_driver_name_length (connect), + xcb_dri2_connect_driver_name (connect)); + + dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + } + + if (dri2_dpy->driver == NULL) { + _eglLog(_EGL_FATAL, + "DRI2: failed to open any driver (search paths %s)", + search_paths); + goto cleanup_connect; + } + + _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); + extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + _eglLog(_EGL_FATAL, + "DRI2: driver exports no extensions (%s)", dlerror()); + goto cleanup_driver; + } + + for (i = 0; extensions[i]; i++) { + _eglLog(_EGL_DEBUG, "DRI2: found driver extension `%s'", + extensions[i]->name); + if (strcmp(extensions[i]->name, __DRI_CORE) == 0) + dri2_dpy->core = (__DRIcoreExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) + dri2_dpy->dri2 = (__DRIdri2Extension *) extensions[i]; + } + + if (dri2_dpy->core == NULL) { + _eglLog(_EGL_FATAL, "DRI2: driver has no core extension"); + goto cleanup_driver; + } + + if (dri2_dpy->dri2 == NULL) { + _eglLog(_EGL_FATAL, "DRI2: driver has no dri2 extension"); + goto cleanup_driver; + } + + snprintf(path, sizeof path, "%.*s", + xcb_dri2_connect_device_name_length (connect), + xcb_dri2_connect_device_name (connect)); + dri2_dpy->fd = open (path, O_RDWR); + if (dri2_dpy->fd == -1) { + _eglLog(_EGL_FATAL, + "DRI2: could not open %s (%s)", path, strerror(errno)); + goto cleanup_driver; + } + + if (drmGetMagic(dri2_dpy->fd, &magic)) { + _eglLog(_EGL_FATAL, "DRI2: failed to get drm magic"); + goto cleanup_fd; + } + + authenticate_cookie = xcb_dri2_authenticate_unchecked (dri2_dpy->conn, + s.data->root, magic); + authenticate = xcb_dri2_authenticate_reply (dri2_dpy->conn, + authenticate_cookie, NULL); + if (authenticate == NULL || !authenticate->authenticated) { + _eglLog(_EGL_FATAL, "DRI2: failed to authenticate"); + free(authenticate); + goto cleanup_fd; + } + + free(authenticate); + if (dri2_dpy->dri2_minor >= 1) { + dri2_dpy->loader_extension.base.name = __DRI_DRI2_LOADER; + dri2_dpy->loader_extension.base.version = 3; + dri2_dpy->loader_extension.getBuffers = dri2_get_buffers; + dri2_dpy->loader_extension.flushFrontBuffer = dri2_flush_front_buffer; + dri2_dpy->loader_extension.getBuffersWithFormat = + dri2_get_buffers_with_format; + } else { + dri2_dpy->loader_extension.base.name = __DRI_DRI2_LOADER; + dri2_dpy->loader_extension.base.version = 2; + dri2_dpy->loader_extension.getBuffers = dri2_get_buffers; + dri2_dpy->loader_extension.flushFrontBuffer = dri2_flush_front_buffer; + dri2_dpy->loader_extension.getBuffersWithFormat = NULL; + } + + dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base; + dri2_dpy->extensions[1] = NULL; + + dri2_dpy->dri_screen = + dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions, + &driver_configs, dri2_dpy); + + if (dri2_dpy->dri_screen == NULL) { + _eglLog(_EGL_FATAL, "DRI2: failed to create dri screen"); + goto cleanup_fd; + } + + extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen); + for (i = 0; extensions[i]; i++) { + _eglLog(_EGL_DEBUG, "DRI2: found core extension `%s'", + extensions[i]->name); + if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) + dri2_dpy->flush = (__DRI2flushExtension *) extensions[i]; + } + + if (dri2_dpy->flush == NULL) { + _eglLog(_EGL_FATAL, "DRI2: driver doesn't support the flush extension"); + goto cleanup_dri_screen; + } + + for (i = 0; driver_configs[i]; i++) + dri2_add_config(disp, driver_configs[i], i + 1); + if (!disp->NumConfigs) { + _eglLog(_EGL_WARNING, "DRI2: failed to create any config"); + goto cleanup_configs; + } + + disp->ClientAPIsMask = EGL_OPENGL_BIT; + + /* we're supporting EGL 1.4 */ + *major = 1; + *minor = 4; + free (connect); + return EGL_TRUE; + + cleanup_configs: + _eglCleanupDisplay(disp); + cleanup_dri_screen: + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); + cleanup_fd: + close(dri2_dpy->fd); + cleanup_driver: + dlclose(dri2_dpy->driver); + cleanup_connect: + free(connect); + cleanup_conn: + if (disp->NativeDisplay == NULL) + xcb_disconnect(dri2_dpy->conn); + cleanup_dpy: + free(dri2_dpy); + + return EGL_FALSE; +} + +/** + * 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); + + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); + close(dri2_dpy->fd); + dlclose(dri2_dpy->driver); + if (disp->NativeDisplay == NULL) + xcb_disconnect(dri2_dpy->conn); + free(dri2_dpy); + disp->DriverData = NULL; + + return EGL_TRUE; +} + + +/** + * 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); + struct dri2_egl_config *dri2_config = dri2_egl_config(conf); + + 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; + + dri2_ctx->dri_context = + dri2_dpy->dri2->createNewContext(dri2_dpy->dri_screen, + dri2_config->dri_config, + dri2_ctx_shared ? + dri2_ctx_shared->dri_context : NULL, + dri2_ctx); + + if (!dri2_ctx->dri_context) + goto cleanup; + + return &dri2_ctx->base; + + cleanup: + free(dri2_ctx); + return NULL; +} + +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); + + if (_eglIsSurfaceBound(surf)) + return EGL_TRUE; + + (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable); + + xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable); + + if (surf->Type == EGL_PBUFFER_BIT) + xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable); + + free(surf); + + 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_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); + __DRIdrawable *ddraw, *rdraw; + __DRIcontext *cctx; + + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &dsurf, &rsurf)) + return EGL_FALSE; + + ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL; + rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL; + cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; + + if ((cctx == NULL && ddraw == NULL && rdraw == NULL) || + dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { + if (dsurf && !_eglIsSurfaceLinked(dsurf)) + dri2_destroy_surface(drv, disp, dsurf); + if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(dsurf)) + dri2_destroy_surface(drv, disp, rsurf); + if (ctx != NULL && !_eglIsContextLinked(ctx)) + dri2_dpy->core->unbindContext(dri2_egl_context(ctx)->dri_context); + + return EGL_TRUE; + } else { + _eglBindContext(&ctx, &dsurf, &rsurf); + + return EGL_FALSE; + } +} + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +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; + xcb_get_geometry_cookie_t cookie; + xcb_get_geometry_reply_t *reply; + xcb_screen_iterator_t s; + xcb_generic_error_t *error; + + dri2_surf = malloc(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; + + dri2_surf->region = XCB_NONE; + if (type == EGL_PBUFFER_BIT) { + dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); + s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); + xcb_create_pixmap(dri2_dpy->conn, + _eglGetConfigKey(conf, EGL_BUFFER_SIZE), + dri2_surf->drawable, s.data->root, + dri2_surf->base.Width, dri2_surf->base.Height); + } else { + dri2_surf->drawable = window; + } + + dri2_surf->dri_drawable = + (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, + dri2_conf->dri_config, dri2_surf); + if (dri2_surf->dri_drawable == NULL) { + _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); + goto cleanup_pixmap; + } + + xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable); + + if (type != EGL_PBUFFER_BIT) { + cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); + reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); + if (reply == NULL || error != NULL) { + _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); + free(error); + goto cleanup_dri_drawable; + } + + dri2_surf->base.Width = reply->width; + dri2_surf->base.Height = reply->height; + free(reply); + } + + return &dri2_surf->base; + + cleanup_dri_drawable: + dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); + cleanup_pixmap: + if (type == EGL_PBUFFER_BIT) + xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); + cleanup_surf: + free(dri2_surf); + + return NULL; +} + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +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 _EGLSurface * +dri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativePixmapType pixmap, + const EGLint *attrib_list) +{ + return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf, + pixmap, attrib_list); +} + +static _EGLSurface * +dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, const EGLint *attrib_list) +{ + return dri2_create_surface(drv, disp, EGL_PBUFFER_BIT, conf, + XCB_WINDOW_NONE, attrib_list); +} + +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); + xcb_dri2_copy_region_cookie_t cookie; + + (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); + +#if 0 + /* FIXME: Add support for dri swapbuffers, that'll give us swap + * interval and page flipping (at least for fullscreen windows) as + * well as the page flip event. */ +#if __DRI2_FLUSH_VERSION >= 2 + if (pdraw->psc->f) + (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); +#endif +#endif + + if (!dri2_surf->have_back) + return EGL_TRUE; + + cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn, + dri2_surf->drawable, + dri2_surf->region, + XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT, + XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT); + free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL)); + + return EGL_TRUE; +} + +/* + * Called from eglGetProcAddress() via drv->API.GetProcAddress(). + */ +static _EGLProc +dri2_get_proc_address(_EGLDriver *drv, const char *procname) +{ + /* FIXME: Do we need to support lookup of EGL symbols too? */ + + return (_EGLProc) _glapi_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); + + /* FIXME: If EGL allows frontbuffer rendering for window surfaces, + * we need to copy fake to real here.*/ + + (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); + + return EGL_TRUE; +} + +static EGLBoolean +dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) +{ + if (engine != EGL_CORE_NATIVE_ENGINE) + return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); + /* glXWaitX(); */ + + return EGL_TRUE; +} + +static void +dri2_unload(_EGLDriver *drv) +{ + struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); + free(dri2_drv); +} + +static EGLBoolean +dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, + EGLNativePixmapType target) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); + xcb_gcontext_t gc; + + (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); + + gc = xcb_generate_id(dri2_dpy->conn); + xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL); + xcb_copy_area(dri2_dpy->conn, + dri2_surf->drawable, + target, + gc, + 0, 0, + 0, 0, + dri2_surf->base.Width, + dri2_surf->base.Height); + xcb_free_gc(dri2_dpy->conn, gc); + + 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 * +_eglMain(const char *args) +{ + struct dri2_egl_driver *dri2_drv; + + dri2_drv = malloc(sizeof *dri2_drv); + if (!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.MakeCurrent = dri2_make_current; + dri2_drv->base.API.CreateWindowSurface = dri2_create_window_surface; + dri2_drv->base.API.CreatePixmapSurface = dri2_create_pixmap_surface; + dri2_drv->base.API.CreatePbufferSurface = dri2_create_pbuffer_surface; + dri2_drv->base.API.DestroySurface = dri2_destroy_surface; + dri2_drv->base.API.SwapBuffers = dri2_swap_buffers; + 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.CopyBuffers = dri2_copy_buffers; + + dri2_drv->base.Name = "DRI2"; + dri2_drv->base.Unload = dri2_unload; + + return &dri2_drv->base; +} diff --git a/src/egl/drivers/glx/Makefile b/src/egl/drivers/glx/Makefile index 20ef0352ad..634638f538 100644 --- a/src/egl/drivers/glx/Makefile +++ b/src/egl/drivers/glx/Makefile @@ -1,77 +1,16 @@ # src/egl/drivers/glx/Makefile -# Build XEGL DRI driver loader library: egl_glx.so - - TOP = ../../../.. include $(TOP)/configs/current +EGL_DRIVER = egl_glx.so +EGL_SOURCES = egl_glx.c -EXTRA_DEFINES = -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" - -DRIVER_NAME = egl_glx.so - - -INCLUDE_DIRS = \ - -I. \ - -I/usr/include \ - $(shell pkg-config --cflags-only-I libdrm) \ +EGL_INCLUDES = \ -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/glx/x11 - -SOURCES = egl_glx.c - -OBJECTS = $(SOURCES:.c=.o) - -DRM_LIB = `pkg-config --libs libdrm` - -MISC_LIBS = -ldl -lXext -lGL - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ - - -.PHONY: library - - -default: depend library Makefile - - -library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) - - -# Make the egl_glx.so library -$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(DRIVER_NAME) \ - -noprefix \ - -major 1 -minor 0 \ - -L$(TOP)/$(LIB_DIR) \ - -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(MISC_LIBS) - -install: - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) - -clean: - rm -f *.o - rm -f *.so - rm -f depend depend.bak - + -I$(TOP)/src/egl/main -depend: $(SOURCES) $(HEADERS) - @ echo "running $(MKDEP)" - @ rm -f depend - @ touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ - $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null +EGL_CFLAGS = +EGL_LIBS = -lX11 -lGL -include depend -# DO NOT DELETE +include ../Makefile.template diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 96292b0e9e..3cbfebe488 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -43,7 +43,7 @@ #include "eglcontext.h" #include "egldisplay.h" #include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" #include "eglsurface.h" @@ -54,13 +54,6 @@ #error "GL/glx.h must be equal to or greater than GLX 1.4" #endif -/* - * report OpenGL ES bits because apps usually forget to specify - * EGL_RENDERABLE_TYPE when choosing configs - */ -#define GLX_EGL_APIS (EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT) - - /** subclass of _EGLDriver */ struct GLX_egl_driver { @@ -110,6 +103,8 @@ struct GLX_egl_surface Drawable drawable; GLXDrawable glx_drawable; + + void (*destroy)(Display *, GLXDrawable); }; @@ -121,35 +116,14 @@ struct GLX_egl_config int index; }; -/** cast wrapper */ -static struct GLX_egl_driver * -GLX_egl_driver(_EGLDriver *drv) -{ - return (struct GLX_egl_driver *) drv; -} - -static struct GLX_egl_display * -GLX_egl_display(_EGLDisplay *dpy) -{ - return (struct GLX_egl_display *) dpy->DriverData; -} - -static struct GLX_egl_context * -GLX_egl_context(_EGLContext *ctx) -{ - return (struct GLX_egl_context *) ctx; -} - -static struct GLX_egl_surface * -GLX_egl_surface(_EGLSurface *surf) -{ - return (struct GLX_egl_surface *) surf; -} +/* standard typecasts */ +_EGL_DRIVER_STANDARD_TYPECASTS(GLX_egl) static int GLX_egl_config_index(_EGLConfig *conf) { - return ((struct GLX_egl_config *) conf)->index; + struct GLX_egl_config *GLX_conf = GLX_egl_config(conf); + return GLX_conf->index; } @@ -244,7 +218,7 @@ convert_fbconfig(Display *dpy, GLXFBConfig fbconfig, GLX_conf->double_buffered = (mode.doubleBufferMode != 0); return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, - GLX_EGL_APIS, GLX_EGL_APIS); + EGL_OPENGL_BIT, EGL_OPENGL_BIT); } @@ -364,7 +338,7 @@ convert_visual(Display *dpy, XVisualInfo *vinfo, GLX_conf->double_buffered = (mode.doubleBufferMode != 0); return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, - GLX_EGL_APIS, GLX_EGL_APIS); + EGL_OPENGL_BIT, EGL_OPENGL_BIT); } @@ -427,7 +401,7 @@ create_configs(_EGLDisplay *dpy, struct GLX_egl_display *GLX_dpy, EGLBoolean ok; memset(&template, 0, sizeof(template)); - _eglInitConfig(&template.Base, id); + _eglInitConfig(&template.Base, dpy, id); if (GLX_dpy->have_fbconfig) ok = convert_fbconfig(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &template); else @@ -559,7 +533,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp, } disp->DriverData = (void *) GLX_dpy; - disp->ClientAPIsMask = GLX_EGL_APIS; + disp->ClientAPIsMask = EGL_OPENGL_BIT; /* we're supporting EGL 1.4 */ *major = 1; @@ -610,7 +584,7 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } - if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) { + if (!_eglInitContext(&GLX_ctx->Base, disp, conf, attrib_list)) { free(GLX_ctx); return NULL; } @@ -638,6 +612,21 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, /** + * Destroy a surface. The display is allowed to be uninitialized. + */ +static void +destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) +{ + struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); + + if (GLX_surf->destroy) + GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable); + + free(GLX_surf); +} + + +/** * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean @@ -650,8 +639,10 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx); GLXDrawable ddraw, rdraw; GLXContext cctx; + EGLBoolean ret = EGL_FALSE; - if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &dsurf, &rsurf)) return EGL_FALSE; ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None; @@ -659,11 +650,21 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, cctx = (GLX_ctx) ? GLX_ctx->context : NULL; if (GLX_dpy->have_make_current_read) - return glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); + ret = glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); else if (ddraw == rdraw) - return glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); + ret = glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); - return EGL_FALSE; + if (ret) { + if (dsurf && !_eglIsSurfaceLinked(dsurf)) + destroy_surface(disp, dsurf); + if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(rsurf)) + destroy_surface(disp, rsurf); + } + else { + _eglBindContext(&ctx, &dsurf, &rsurf); + } + + return ret; } /** Get size of given window */ @@ -684,8 +685,9 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * -GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) +GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativeWindowType window, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; @@ -697,7 +699,7 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } - if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT, + if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_WINDOW_BIT, conf, attrib_list)) { free(GLX_surf); return NULL; @@ -718,6 +720,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } + if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk) + GLX_surf->destroy = glXDestroyWindow; + get_drawable_size(GLX_dpy->dpy, window, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -726,8 +731,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } static _EGLSurface * -GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) +GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativePixmapType pixmap, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; @@ -739,7 +745,7 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } - if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT, + if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PIXMAP_BIT, conf, attrib_list)) { free(GLX_surf); return NULL; @@ -774,6 +780,9 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPixmap : glXDestroyGLXPixmap; + get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -796,7 +805,7 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } - if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT, + if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PBUFFER_BIT, conf, attrib_list)) { free(GLX_surf); return NULL; @@ -838,47 +847,18 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPbuffer : GLX_dpy->glXDestroyGLXPbufferSGIX; + return &GLX_surf->Base; } + static EGLBoolean GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { - struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); - if (!_eglIsSurfaceBound(surf)) { - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - - if (GLX_dpy->have_1_3) { - switch (surf->Type) { - case EGL_WINDOW_BIT: - if (!GLX_dpy->glx_window_quirk) - glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PBUFFER_BIT: - glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - else { - switch (surf->Type) { - case EGL_PBUFFER_BIT: - GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy, - GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - free(surf); - } + if (!_eglIsSurfaceBound(surf)) + destroy_surface(disp, surf); return EGL_TRUE; } @@ -899,7 +879,7 @@ GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) * Called from eglGetProcAddress() via drv->API.GetProcAddress(). */ static _EGLProc -GLX_eglGetProcAddress(const char *procname) +GLX_eglGetProcAddress(_EGLDriver *drv, const char *procname) { return (_EGLProc) glXGetProcAddress((const GLubyte *) procname); } diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile deleted file mode 100644 index 4c1fc9071c..0000000000 --- a/src/egl/drivers/xdri/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -# src/egl/drivers/xdri/Makefile - -# Build XEGL DRI driver loader library: egl_xdri.so - - -TOP = ../../../.. -include $(TOP)/configs/current - - -DRIVER_NAME = egl_xdri.so - - -INCLUDE_DIRS = \ - -I. \ - -I/usr/include \ - $(shell pkg-config --cflags-only-I libdrm) \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/glx/x11 - -HEADERS = glxinit.h driinit.h -SOURCES = egl_xdri.c glxinit.c driinit.c - -DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c -DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES)) - -SOURCES += $(DRI_SOURCES) - -OBJECTS = $(SOURCES:.c=.o) - -DRM_LIB = `pkg-config --libs libdrm` - -CFLAGS += -DGLX_DIRECT_RENDERING - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - -.PHONY: library - - -default: depend library Makefile - - -library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) - - -# Make the egl_xdri.so library -$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(DRIVER_NAME) \ - -noprefix \ - -major 1 -minor 0 \ - -L$(TOP)/$(LIB_DIR) \ - -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS) - -install: - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) - -clean: - rm -f *.o - rm -f *.so - rm -f depend depend.bak - - -depend: $(SOURCES) $(HEADERS) - @ echo "running $(MKDEP)" - @ rm -f depend - @ touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ - $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null - -include depend -# DO NOT DELETE diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c deleted file mode 100644 index 12da1bcd24..0000000000 --- a/src/egl/drivers/xdri/driinit.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - * DRI initialization. The DRI loaders are defined in src/glx/x11/. - */ - -#include <sys/time.h> - -#include "glxclient.h" -#include "driinit.h" - -/* for __DRI_SYSTEM_TIME extension */ -_X_HIDDEN int -__glXGetUST(int64_t * ust) -{ - struct timeval tv; - - if (ust == NULL) { - return -EFAULT; - } - - if (gettimeofday(&tv, NULL) == 0) { - ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; - return 0; - } - else { - return -errno; - } -} - -_X_HIDDEN GLboolean -__driGetMscRateOML(__DRIdrawable * draw, - int32_t * numerator, int32_t * denominator, void *private) -{ - return GL_FALSE; -} - -/* ignore glx extensions */ -_X_HIDDEN void -__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) -{ -} - -_X_HIDDEN __GLXDRIdisplay * -__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) -{ - __GLXDRIdisplay *driDisplay; - int ver = 0; - - /* try DRI2 first */ - driDisplay = dri2CreateDisplay(dpyPriv->dpy); - if (driDisplay) { - /* fill in the required field */ - dpyPriv->dri2Display = driDisplay; - ver = 2; - } - else { - /* try DRI */ - driDisplay = driCreateDisplay(dpyPriv->dpy); - if (driDisplay) { - dpyPriv->driDisplay = driDisplay; - ver = 1; - } - } - - if (version) - *version = ver; - return driDisplay; -} diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h deleted file mode 100644 index 6ea05cebef..0000000000 --- a/src/egl/drivers/xdri/driinit.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DRIINIT_INCLUDED -#define DRIINIT_INCLUDED - -#include "glxclient.h" - -extern __GLXDRIdisplay * -__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version); - -#endif /* DRIINIT_INCLUDED */ diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c deleted file mode 100644 index d2affc66dd..0000000000 --- a/src/egl/drivers/xdri/egl_xdri.c +++ /dev/null @@ -1,610 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - - -/** - * Code to interface a DRI driver to libEGL. - * Note that unlike previous DRI/EGL interfaces, this one is meant to - * be used _with_ X. Applications will use eglCreateWindowSurface() - * to render into X-created windows. - * - * This is an EGL driver that, in turn, loads a regular DRI driver. - * There are some dependencies on code in libGL, but those could be - * removed with some effort. - * - * Authors: Brian Paul - */ - -#include <assert.h> -#include <stdlib.h> -#include <X11/Xlib.h> - -#include "glxinit.h" -#include "driinit.h" -#include "glapi/glapi.h" /* for glapi functions */ - -#include "eglconfig.h" -#include "eglconfigutil.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "egllog.h" -#include "eglsurface.h" - -#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) - -/** subclass of _EGLDriver */ -struct xdri_egl_driver -{ - _EGLDriver Base; /**< base class */ -}; - - -/** driver data of _EGLDisplay */ -struct xdri_egl_display -{ - Display *dpy; - __GLXdisplayPrivate *dpyPriv; - __GLXDRIdisplay *driDisplay; - - __GLXscreenConfigs *psc; - EGLint scr; -}; - - -/** subclass of _EGLContext */ -struct xdri_egl_context -{ - _EGLContext Base; /**< base class */ - - /* just enough info to create dri contexts */ - GLXContext dummy_gc; - - __GLXDRIcontext *driContext; -}; - - -/** subclass of _EGLSurface */ -struct xdri_egl_surface -{ - _EGLSurface Base; /**< base class */ - - Drawable drawable; - __GLXDRIdrawable *driDrawable; -}; - - -/** subclass of _EGLConfig */ -struct xdri_egl_config -{ - _EGLConfig Base; /**< base class */ - - const __GLcontextModes *mode; /**< corresponding GLX mode */ - EGLint window_render_buffer; -}; - - - -/** cast wrapper */ -static INLINE struct xdri_egl_driver * -xdri_egl_driver(_EGLDriver *drv) -{ - return (struct xdri_egl_driver *) drv; -} - - -static INLINE struct xdri_egl_display * -lookup_display(_EGLDisplay *dpy) -{ - return (struct xdri_egl_display *) dpy->DriverData; -} - - -/** Map EGLSurface handle to xdri_egl_surface object */ -static INLINE struct xdri_egl_surface * -lookup_surface(_EGLSurface *surface) -{ - return (struct xdri_egl_surface *) surface; -} - - -/** Map EGLContext handle to xdri_egl_context object */ -static INLINE struct xdri_egl_context * -lookup_context(_EGLContext *context) -{ - return (struct xdri_egl_context *) context; -} - - -/** Map EGLConfig handle to xdri_egl_config object */ -static INLINE struct xdri_egl_config * -lookup_config(_EGLConfig *conf) -{ - return (struct xdri_egl_config *) conf; -} - - -/** Get size of given window */ -static Status -get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) -{ - Window root; - Status stat; - int xpos, ypos; - unsigned int w, h, bw, depth; - stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); - *width = w; - *height = h; - return stat; -} - - -static EGLBoolean -convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) -{ - static const EGLint all_apis = (EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_BIT); - EGLint val; - - _eglInitConfig(conf, id); - if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis)) - return EGL_FALSE; - - if (m->doubleBufferMode) { - /* pixmap and pbuffer surfaces are always single-buffered */ - val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); - val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); - SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val); - } - else { - /* EGL requires OpenGL ES context to be double-buffered */ - val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE); - val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT); - SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val); - } - /* skip "empty" config */ - if (!val) - return EGL_FALSE; - - val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); - if (!(val & EGL_PBUFFER_BIT)) { - /* bind-to-texture cannot be EGL_TRUE without pbuffer bit */ - SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE); - SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE); - } - - /* EGL_NATIVE_RENDERABLE is a boolean */ - val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE); - if (val != EGL_TRUE) - SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE); - - return _eglValidateConfig(conf, EGL_FALSE); -} - - -/** - * Produce a set of EGL configs. - */ -static EGLint -create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) -{ - int id = first_id; - - for (; m; m = m->next) { - struct xdri_egl_config *xdri_conf; - _EGLConfig conf; - EGLint rb; - - if (!convert_config(&conf, id, m)) - continue; - - rb = (m->doubleBufferMode) ? EGL_BACK_BUFFER : EGL_SINGLE_BUFFER; - - xdri_conf = CALLOC_STRUCT(xdri_egl_config); - if (xdri_conf) { - memcpy(&xdri_conf->Base, &conf, sizeof(conf)); - xdri_conf->mode = m; - xdri_conf->window_render_buffer = rb; - _eglAddConfig(disp, &xdri_conf->Base); - id++; - } - } - - return id; -} - - -/** - * Called via eglInitialize(), xdri_dpy->API.Initialize(). - */ -static EGLBoolean -xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *minor, EGLint *major) -{ - struct xdri_egl_display *xdri_dpy; - __GLXdisplayPrivate *dpyPriv; - __GLXDRIdisplay *driDisplay; - __GLXscreenConfigs *psc; - EGLint first_id = 1; - int scr; - - xdri_dpy = CALLOC_STRUCT(xdri_egl_display); - if (!xdri_dpy) - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - - xdri_dpy->dpy = (Display *) dpy->NativeDisplay; - if (!xdri_dpy->dpy) { - xdri_dpy->dpy = XOpenDisplay(NULL); - if (!xdri_dpy->dpy) { - free(xdri_dpy); - return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); - } - } - - dpyPriv = __glXInitialize(xdri_dpy->dpy); - if (!dpyPriv) { - _eglLog(_EGL_WARNING, "failed to create GLX display"); - free(xdri_dpy); - return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); - } - - driDisplay = __driCreateDisplay(dpyPriv, NULL); - if (!driDisplay) { - _eglLog(_EGL_WARNING, "failed to create DRI display"); - free(xdri_dpy); - return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); - } - - scr = DefaultScreen(xdri_dpy->dpy); - psc = &dpyPriv->screenConfigs[scr]; - - xdri_dpy->dpyPriv = dpyPriv; - xdri_dpy->driDisplay = driDisplay; - xdri_dpy->psc = psc; - xdri_dpy->scr = scr; - - psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv); - if (!psc->driScreen) { - _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr); - free(xdri_dpy); - return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); - } - - /* add visuals and fbconfigs */ - first_id = create_configs(dpy, psc->visuals, first_id); - create_configs(dpy, psc->configs, first_id); - - dpy->DriverData = xdri_dpy; - dpy->ClientAPIsMask = (EGL_OPENGL_BIT | - EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT); - - /* we're supporting EGL 1.4 */ - *minor = 1; - *major = 4; - - return EGL_TRUE; -} - - -/** - * Called via eglTerminate(), drv->API.Terminate(). - */ -static EGLBoolean -xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct xdri_egl_display *xdri_dpy = lookup_display(dpy); - __GLXscreenConfigs *psc; - - _eglReleaseDisplayResources(drv, dpy); - _eglCleanupDisplay(dpy); - - psc = xdri_dpy->psc; - if (psc->driver_configs) { - unsigned int i; - for (i = 0; psc->driver_configs[i]; i++) - free((__DRIconfig *) psc->driver_configs[i]); - free(psc->driver_configs); - psc->driver_configs = NULL; - } - if (psc->driScreen) { - psc->driScreen->destroyScreen(psc); - free(psc->driScreen); - psc->driScreen = NULL; - } - - xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); - __glXRelease(xdri_dpy->dpyPriv); - - free(xdri_dpy); - dpy->DriverData = NULL; - - return EGL_TRUE; -} - - -/* - * Called from eglGetProcAddress() via drv->API.GetProcAddress(). - */ -static _EGLProc -xdri_eglGetProcAddress(const char *procname) -{ - /* the symbol is defined in libGL.so */ - return (_EGLProc) _glapi_get_proc_address(procname); -} - - -/** - * Called via eglCreateContext(), drv->API.CreateContext(). - */ -static _EGLContext * -xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - _EGLContext *share_list, const EGLint *attrib_list) -{ - struct xdri_egl_display *xdri_dpy = lookup_display(dpy); - struct xdri_egl_config *xdri_config = lookup_config(conf); - struct xdri_egl_context *shared = lookup_context(share_list); - __GLXscreenConfigs *psc = xdri_dpy->psc; - int renderType = GLX_RGBA_BIT; - struct xdri_egl_context *xdri_ctx; - - xdri_ctx = CALLOC_STRUCT(xdri_egl_context); - if (!xdri_ctx) { - _eglError(EGL_BAD_ALLOC, "eglCreateContext"); - return NULL; - } - - xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec); - if (!xdri_ctx->dummy_gc) { - _eglError(EGL_BAD_ALLOC, "eglCreateContext"); - free(xdri_ctx); - return NULL; - } - - if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) { - free(xdri_ctx->dummy_gc); - free(xdri_ctx); - return NULL; - } - - /* the config decides the render buffer for the context */ - xdri_ctx->Base.WindowRenderBuffer = xdri_config->window_render_buffer; - - xdri_ctx->driContext = - psc->driScreen->createContext(psc, - xdri_config->mode, - xdri_ctx->dummy_gc, - (shared) ? shared->dummy_gc : NULL, - renderType); - if (!xdri_ctx->driContext) { - free(xdri_ctx->dummy_gc); - free(xdri_ctx); - return NULL; - } - - /* fill in the required field */ - xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext; - - return &xdri_ctx->Base; -} - - -static EGLBoolean -xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) -{ - struct xdri_egl_display *xdri_dpy = lookup_display(dpy); - struct xdri_egl_context *xdri_ctx = lookup_context(ctx); - - if (!_eglIsContextBound(ctx)) { - xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, - xdri_dpy->psc, xdri_dpy->dpy); - free(xdri_ctx->dummy_gc); - free(xdri_ctx); - } - - return EGL_TRUE; -} - - -/** - * Called via eglMakeCurrent(), drv->API.MakeCurrent(). - */ -static EGLBoolean -xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, - _EGLSurface *r, _EGLContext *context) -{ - struct xdri_egl_context *xdri_ctx = lookup_context(context); - struct xdri_egl_surface *draw = lookup_surface(d); - struct xdri_egl_surface *read = lookup_surface(r); - - if (!_eglMakeCurrent(drv, dpy, d, r, context)) - return EGL_FALSE; - - /* the symbol is defined in libGL.so */ - _glapi_check_multithread(); - - if (xdri_ctx) { - if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext, - draw->driDrawable, - read->driDrawable)) { - return EGL_FALSE; - } - } - else { - _EGLContext *old = _eglGetCurrentContext(); - if (old) { - xdri_ctx = lookup_context(old); - xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); - } - } - - return EGL_TRUE; -} - - -/** - * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). - */ -static _EGLSurface * -xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) -{ - struct xdri_egl_display *xdri_dpy = lookup_display(dpy); - struct xdri_egl_config *xdri_config = lookup_config(conf); - struct xdri_egl_surface *xdri_surf; - uint width, height; - - xdri_surf = CALLOC_STRUCT(xdri_egl_surface); - if (!xdri_surf) { - _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); - return NULL; - } - - if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT, - &xdri_config->Base, attrib_list)) { - free(xdri_surf); - return NULL; - } - - xdri_surf->driDrawable = - xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, - (XID) window, - (GLXDrawable) window, - xdri_config->mode); - if (!xdri_surf->driDrawable) { - free(xdri_surf); - return NULL; - } - - xdri_surf->drawable = (Drawable) window; - - get_drawable_size(xdri_dpy->dpy, window, &width, &height); - xdri_surf->Base.Width = width; - xdri_surf->Base.Height = height; - - return &xdri_surf->Base; -} - - -/** - * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface(). - */ -static _EGLSurface * -xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - return NULL; -} - - - -static EGLBoolean -xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - if (!_eglIsSurfaceBound(&xdri_surf->Base)) { - xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); - free(xdri_surf); - } - - return EGL_TRUE; -} - - -static EGLBoolean -xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - EGLint buffer) -{ - return EGL_FALSE; -} - - -static EGLBoolean -xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - EGLint buffer) -{ - return EGL_FALSE; -} - - -static EGLBoolean -xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) -{ - struct xdri_egl_display *xdri_dpy = lookup_display(dpy); - struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - - xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); - - return EGL_TRUE; -} - - -static void -xdri_Unload(_EGLDriver *drv) -{ - struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv); - free(xdri_drv); -} - - -/** - * This is the main entrypoint into the driver, called by libEGL. - * Create a new _EGLDriver object and init its dispatch table. - */ -_EGLDriver * -_eglMain(const char *args) -{ - struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver); - if (!xdri_drv) - return NULL; - - _eglInitDriverFallbacks(&xdri_drv->Base); - xdri_drv->Base.API.Initialize = xdri_eglInitialize; - xdri_drv->Base.API.Terminate = xdri_eglTerminate; - - xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress; - - xdri_drv->Base.API.CreateContext = xdri_eglCreateContext; - xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext; - xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent; - xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface; - xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface; - xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface; - xdri_drv->Base.API.BindTexImage = xdri_eglBindTexImage; - xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage; - xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers; - - xdri_drv->Base.Name = "X/DRI"; - xdri_drv->Base.Unload = xdri_Unload; - - return &xdri_drv->Base; -} diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index ec326a845d..31f214cf6f 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -19,6 +19,7 @@ HEADERS = \ egldisplay.h \ egldriver.h \ eglglobals.h \ + eglimage.h \ egllog.h \ eglmisc.h \ eglmode.h \ @@ -36,6 +37,7 @@ SOURCES = \ egldisplay.c \ egldriver.c \ eglglobals.c \ + eglimage.c \ egllog.c \ eglmisc.c \ eglmode.c \ @@ -47,8 +49,13 @@ OBJECTS = $(SOURCES:.c=.o) # use dl*() to load drivers -LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 +LOCAL_CFLAGS = -D_EGL_PLATFORM_POSIX=1 +EGL_DEFAULT_DISPLAY = $(word 1, $(EGL_DISPLAYS)) + +LOCAL_CFLAGS += \ + -D_EGL_DEFAULT_DISPLAY=\"$(EGL_DEFAULT_DISPLAY)\" \ + -D_EGL_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\" .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ @@ -67,7 +74,15 @@ $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME): $(OBJECTS) -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(EGL_LIB_DEPS) $(OBJECTS) -install: default +install-headers: + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/KHR + $(INSTALL) -m 644 $(TOP)/include/KHR/*.h \ + $(DESTDIR)$(INSTALL_INC_DIR)/KHR + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/EGL + $(INSTALL) -m 644 $(TOP)/include/EGL/*.h \ + $(DESTDIR)$(INSTALL_INC_DIR)/EGL + +install: default install-headers $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) $(MINSTALL) $(TOP)/$(LIB_DIR)/$(EGL_LIB_GLOB) \ $(DESTDIR)$(INSTALL_LIB_DIR) diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 14cc5fa613..364ad9c458 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -60,11 +60,13 @@ #include "egldisplay.h" #include "egltypedefs.h" #include "eglglobals.h" +#include "eglcurrent.h" #include "egldriver.h" #include "eglsurface.h" #include "eglconfig.h" #include "eglscreen.h" #include "eglmode.h" +#include "eglimage.h" /** @@ -72,7 +74,7 @@ * We initialize our global vars and create a private _EGLDisplay object. */ EGLDisplay EGLAPIENTRY -eglGetDisplay(NativeDisplayType nativeDisplay) +eglGetDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy; dpy = _eglFindDisplay(nativeDisplay); @@ -93,23 +95,24 @@ EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLDriver *drv; EGLint major_int, minor_int; if (!disp) return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); - drv = disp->Driver; - if (!drv) { - drv = _eglOpenDriver(disp); - if (!drv) - return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); + if (!disp->Initialized) { + _EGLDriver *drv = disp->Driver; + + if (!drv) { + _eglPreloadDrivers(); + drv = _eglMatchDriver(disp); + if (!drv) + return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); + } /* Initialize the particular display now */ - if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) { - _eglCloseDriver(drv, disp); + if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); - } disp->APImajor = major_int; disp->APIminor = minor_int; @@ -120,6 +123,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) disp->ClientAPIsMask &= _EGL_API_ALL_BITS; disp->Driver = drv; + disp->Initialized = EGL_TRUE; } else { major_int = disp->APImajor; minor_int = disp->APIminor; @@ -139,16 +143,16 @@ EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) { _EGLDisplay *disp = _eglLookupDisplay(dpy); - _EGLDriver *drv; if (!disp) return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); - drv = disp->Driver; - if (drv) { + if (disp->Initialized) { + _EGLDriver *drv = disp->Driver; + drv->API.Terminate(drv, disp); - _eglCloseDriver(drv, disp); - disp->Driver = NULL; + /* do not reset disp->Driver */ + disp->Initialized = EGL_FALSE; } return EGL_TRUE; @@ -165,7 +169,7 @@ _eglCheckDisplay(_EGLDisplay *disp, const char *msg) _eglError(EGL_BAD_DISPLAY, msg); return NULL; } - if (!disp->Driver) { + if (!disp->Initialized) { _eglError(EGL_NOT_INITIALIZED, msg); return NULL; } @@ -391,9 +395,19 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, _EGLSurface *read_surf = _eglLookupSurface(read, disp); _EGLDriver *drv; - drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!disp) + return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + 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 _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + } if (!drv) - return EGL_FALSE; + return EGL_TRUE; + if (!context && ctx != EGL_NO_CONTEXT) return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); if ((!draw_surf && draw != EGL_NO_SURFACE) || @@ -415,7 +429,7 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, const EGLint *attrib_list) { _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); @@ -436,7 +450,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, - NativePixmapType pixmap, const EGLint *attrib_list) + EGLNativePixmapType pixmap, const EGLint *attrib_list) { _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); @@ -524,7 +538,7 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval) _EGLSurface *surf; _EGL_DECLARE_DD(dpy); - if (!ctx || !_eglIsContextLinked(ctx) || ctx->Display != disp) + if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); surf = ctx->DrawSurface; @@ -550,7 +564,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean EGLAPIENTRY -eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target) +eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); return drv->API.CopyBuffers(drv, disp, surf, target); @@ -571,9 +585,9 @@ eglWaitClient(void) return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); /* a valid current context implies an initialized current display */ - disp = ctx->Display; + disp = ctx->Resource.Display; + assert(disp->Initialized); drv = disp->Driver; - assert(drv); return drv->API.WaitClient(drv, disp, ctx); } @@ -615,9 +629,9 @@ eglWaitNative(EGLint engine) return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); /* a valid current context implies an initialized current display */ - disp = ctx->Display; + disp = ctx->Resource.Display; + assert(disp->Initialized); drv = disp->Driver; - assert(drv); return drv->API.WaitNative(drv, disp, engine); } @@ -626,8 +640,8 @@ eglWaitNative(EGLint engine) EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) { - _EGLDisplay *dpy = _eglGetCurrentDisplay(); - return _eglGetDisplayHandle(dpy); + _EGLContext *ctx = _eglGetCurrentContext(); + return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; } @@ -676,7 +690,8 @@ eglGetError(void) } -void (* EGLAPIENTRY eglGetProcAddress(const char *procname))() +__eglMustCastToProperFunctionPointerType EGLAPIENTRY +eglGetProcAddress(const char *procname) { static const struct { const char *name; @@ -697,6 +712,10 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))() { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA }, { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA }, #endif /* EGL_MESA_screen_surface */ +#ifdef EGL_KHR_image_base + { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, + { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, +#endif /* EGL_KHR_image_base */ { NULL, NULL } }; EGLint i; @@ -710,13 +729,12 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))() } } - /* preload a driver if there isn't one */ - if (!_eglGlobal.NumDrivers) - _eglPreloadDriver(NULL); + _eglPreloadDrivers(); /* now loop over drivers to query their procs */ for (i = 0; i < _eglGlobal.NumDrivers; i++) { - _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname); + _EGLDriver *drv = _eglGlobal.Drivers[i]; + _EGLProc p = drv->API.GetProcAddress(drv, procname); if (p) return p; } @@ -977,14 +995,23 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLBoolean eglReleaseThread(void) { - /* unbind current context */ + /* unbind current contexts */ if (!_eglIsCurrentThreadDummy()) { - _EGLDisplay *disp = _eglGetCurrentDisplay(); - _EGLDriver *drv; - if (disp) { - drv = disp->Driver; - (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + _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 = disp->Driver; + t->CurrentAPIIndex = i; + (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + } } + + t->CurrentAPIIndex = api_index; } _eglDestroyCurrentThread(); @@ -993,3 +1020,52 @@ eglReleaseThread(void) #endif /* EGL_VERSION_1_2 */ + + +#ifdef EGL_KHR_image_base + + +EGLImageKHR +eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, + EGLClientBuffer buffer, const EGLint *attr_list) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLDriver *drv; + _EGLImage *img; + + drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!drv) + return EGL_NO_IMAGE_KHR; + if (!context && ctx != EGL_NO_CONTEXT) { + _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + return EGL_NO_IMAGE_KHR; + } + + img = drv->API.CreateImageKHR(drv, + disp, context, target, buffer, attr_list); + if (img) + return _eglLinkImage(img, disp); + else + return EGL_NO_IMAGE_KHR; +} + + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLImage *img = _eglLookupImage(image, disp); + _EGLDriver *drv; + + drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!drv) + return EGL_FALSE; + if (!img) + return _eglError(EGL_BAD_PARAMETER, __FUNCTION__); + + _eglUnlinkImage(img); + return drv->API.DestroyImageKHR(drv, disp, img); +} + + +#endif /* EGL_KHR_image_base */ diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index aa0abe3eb6..c3676ec56a 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -4,7 +4,7 @@ /** * A generic function ptr type */ -typedef void (*_EGLProc)(); +typedef void (*_EGLProc)(void); /** @@ -23,12 +23,13 @@ typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLC /* context funcs */ typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list); typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); +/* this is the only function (other than Initialize) that may be called with an uninitialized display */ typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); /* surface funcs */ -typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list); -typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list); +typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLNativeWindowType window, const EGLint *attrib_list); +typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLNativePixmapType pixmap, const EGLint *attrib_list); typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value); @@ -37,14 +38,14 @@ typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurf typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer); typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint interval); typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw); -typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target); +typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLNativePixmapType target); /* misc funcs */ typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name); typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine); -typedef _EGLProc (*GetProcAddress_t)(const char *procname); +typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname); @@ -69,6 +70,11 @@ typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDis #endif /* EGL_VERSION_1_2 */ +#ifdef EGL_KHR_image_base +typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list); +typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); +#endif /* EGL_KHR_image_base */ + /** * The API dispatcher jumps through these functions @@ -104,7 +110,7 @@ struct _egl_api WaitNative_t WaitNative; GetProcAddress_t GetProcAddress; - /* EGL_MESA_screen extension */ +#ifdef EGL_MESA_screen_surface ChooseModeMESA_t ChooseModeMESA; GetModesMESA_t GetModesMESA; GetModeAttribMESA_t GetModeAttribMESA; @@ -117,10 +123,16 @@ struct _egl_api QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA; QueryScreenModeMESA_t QueryScreenModeMESA; QueryModeStringMESA_t QueryModeStringMESA; +#endif /* EGL_MESA_screen_surface */ #ifdef EGL_VERSION_1_2 CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer; #endif + +#ifdef EGL_KHR_image_base + CreateImageKHR_t CreateImageKHR; + DestroyImageKHR_t DestroyImageKHR; +#endif /* EGL_KHR_image_base */ }; #endif /* EGLAPI_INCLUDED */ diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h index f7c93f14ce..d844fbb0ef 100644 --- a/src/egl/main/eglcompiler.h +++ b/src/egl/main/eglcompiler.h @@ -64,11 +64,30 @@ /** * Function visibility */ -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 +#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PUBLIC __attribute__((visibility("default"))) #else # define PUBLIC #endif +/** + * The __FUNCTION__ gcc variable is generally only used for debugging. + * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. + * Don't define it if using a newer Windows compiler. + */ +#ifndef __FUNCTION__ +# if defined(__VMS) +# define __FUNCTION__ "VMS$NL:" +# elif ((!defined __GNUC__) || (__GNUC__ < 2)) && (!defined __xlC__) && \ + (!defined(_MSC_VER) || _MSC_VER < 1300) +# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ + (defined(__SUNPRO_C) && defined(__C99FEATURES__)) +# define __FUNCTION__ __func__ +# else +# define __FUNCTION__ "<unknown>" +# endif +# endif +#endif #endif /* EGLCOMPILER_INCLUDED */ diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index 31d69a7708..1190f8cdd5 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -4,13 +4,11 @@ #include <stdlib.h> -#include <stdio.h> #include <string.h> #include <assert.h> #include "eglconfig.h" #include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" @@ -27,10 +25,12 @@ * IDs are from 1 to N respectively. */ void -_eglInitConfig(_EGLConfig *config, EGLint id) +_eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id) { memset(config, 0, sizeof(*config)); + config->Display = dpy; + /* some attributes take non-zero default values */ SET_CONFIG_ATTRIB(config, EGL_CONFIG_ID, id); SET_CONFIG_ATTRIB(config, EGL_CONFIG_CAVEAT, EGL_NONE); @@ -224,7 +224,8 @@ static const struct { { EGL_MATCH_NATIVE_PIXMAP, ATTRIB_TYPE_PSEUDO, ATTRIB_CRITERION_SPECIAL, EGL_NONE }, - { EGL_PRESERVED_RESOURCES, ATTRIB_TYPE_PSEUDO, + /* there is a gap before EGL_SAMPLES */ + { 0x3030, ATTRIB_TYPE_PSEUDO, ATTRIB_CRITERION_IGNORE, 0 }, { EGL_NONE, ATTRIB_TYPE_PSEUDO, @@ -328,6 +329,8 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + if (conf->Display->Extensions.MESA_screen_surface) + mask |= EGL_SCREEN_BIT_MESA; break; case EGL_RENDERABLE_TYPE: case EGL_CONFORMANT: @@ -363,8 +366,11 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL) valid = EGL_TRUE; } - if (!valid) + 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 */ @@ -387,10 +393,18 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) valid = EGL_FALSE; break; } + if (!valid) { + _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes"); + return EGL_FALSE; + } val = GET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS); if (!val && GET_CONFIG_ATTRIB(conf, EGL_SAMPLES)) valid = EGL_FALSE; + if (!valid) { + _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers"); + return EGL_FALSE; + } val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE); if (!(val & EGL_WINDOW_BIT)) { @@ -403,6 +417,10 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA)) valid = EGL_FALSE; } + if (!valid) { + _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding"); + return EGL_FALSE; + } return valid; } @@ -454,8 +472,14 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) break; } - if (!matched) + if (!matched) { +#ifdef DEBUG + _eglLog(_EGL_DEBUG, + "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)", + val, attr, cmp); +#endif break; + } } return matched; @@ -730,7 +754,7 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, if (!num_configs) return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); - _eglInitConfig(&criteria, 0); + _eglInitConfig(&criteria, disp, 0); if (!_eglParseConfigAttribList(&criteria, attrib_list)) return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); @@ -772,7 +796,7 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr) /* there are some holes in the range */ switch (attr) { - case EGL_PRESERVED_RESOURCES: + case 0x3030 /* a gap before EGL_SAMPLES */: case EGL_NONE: #ifdef EGL_VERSION_1_4 case EGL_MATCH_NATIVE_PIXMAP: diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index 799bf4ee24..56ec95fe9a 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -21,6 +21,9 @@ struct _egl_config }; +/** + * Macros for source level compatibility. + */ #define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) _eglSetConfigKey(CONF, ATTR, VAL) #define GET_CONFIG_ATTRIB(CONF, ATTR) _eglGetConfigKey(CONF, ATTR) @@ -55,6 +58,10 @@ _eglResetConfigKeys(_EGLConfig *conf, EGLint val) /** * Update a config for a given key. + * + * Note that a valid key is not necessarily a valid attribute. There are gaps + * in the attribute enums. The separation is to catch application errors. + * Drivers should never set a key that is an invalid attribute. */ static INLINE void _eglSetConfigKey(_EGLConfig *conf, EGLint key, EGLint val) @@ -77,22 +84,8 @@ _eglGetConfigKey(const _EGLConfig *conf, EGLint key) } -/** - * Set a given attribute. - * - * Because _eglGetConfigAttrib is already used as a fallback driver - * function, this function is not considered to have a good name. - * SET_CONFIG_ATTRIB is preferred over this function. - */ -static INLINE void -_eglSetConfigAttrib(_EGLConfig *conf, EGLint attr, EGLint val) -{ - SET_CONFIG_ATTRIB(conf, attr, val); -} - - PUBLIC void -_eglInitConfig(_EGLConfig *config, EGLint id); +_eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id); PUBLIC EGLConfig diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c index 36e94f0d2d..e416b190f0 100644 --- a/src/egl/main/eglconfigutil.c +++ b/src/egl/main/eglconfigutil.c @@ -4,10 +4,8 @@ #include <stdlib.h> -#include <stdio.h> #include <string.h> #include "eglconfigutil.h" -#include "egllog.h" /** @@ -128,210 +126,3 @@ _eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m, return EGL_TRUE; } - - -/** - * Creates a set of \c _EGLConfigs that a driver will expose. - * - * A set of \c __GLcontextModes will be created based on the supplied - * parameters. The number of modes processed will be 2 * - * \c num_depth_stencil_bits * \c num_db_modes. - * - * For the most part, data is just copied from \c depth_bits, \c stencil_bits, - * \c db_modes, and \c visType into each \c __GLcontextModes element. - * However, the meanings of \c fb_format and \c fb_type require further - * explanation. The \c fb_format specifies which color components are in - * each pixel and what the default order is. For example, \c GL_RGB specifies - * that red, green, blue are available and red is in the "most significant" - * position and blue is in the "least significant". The \c fb_type specifies - * the bit sizes of each component and the actual ordering. For example, if - * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] - * are the blue value, bits [10:5] are the green value, and bits [4:0] are - * the red value. - * - * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either - * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the - * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or - * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as - * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 - * still uses 32-bits. - * - * If in doubt, look at the tables used in the function. - * - * \param configs the array of configs generated - * \param fb_format Format of the framebuffer. Currently only \c GL_RGB, - * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported. - * \param fb_type Type of the pixels in the framebuffer. Currently only - * \c GL_UNSIGNED_SHORT_5_6_5, - * \c GL_UNSIGNED_SHORT_5_6_5_REV, - * \c GL_UNSIGNED_INT_8_8_8_8, and - * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported. - * \param depth_bits Array of depth buffer sizes to be exposed. - * \param stencil_bits Array of stencil buffer sizes to be exposed. - * \param num_depth_stencil_bits Number of entries in both \c depth_bits and - * \c stencil_bits. - * \param db_modes Array of buffer swap modes. If an element has a - * value of \c GLX_NONE, then it represents a - * single-buffered mode. Other valid values are - * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and - * \c GLX_SWAP_UNDEFINED_OML. See the - * GLX_OML_swap_method extension spec for more details. - * \param num_db_modes Number of entries in \c db_modes. - * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or - * \c GLX_DIRECT_COLOR. - * - * \returns - * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only - * cause of failure is a bad parameter (i.e., unsupported \c fb_format or - * \c fb_type). - * - * \todo - * There is currently no way to support packed RGB modes (i.e., modes with - * exactly 3 bytes per pixel) or floating-point modes. This could probably - * be done by creating some new, private enums with clever names likes - * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, - * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. - */ -EGLBoolean -_eglFillInConfigs(_EGLConfig * configs, - GLenum fb_format, GLenum fb_type, - const uint8_t * depth_bits, const uint8_t * stencil_bits, - unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes, - int visType) -{ - static const uint8_t bits_table[3][4] = { - /* R G B A */ - { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ - { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ - { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ - }; - - /* The following arrays are all indexed by the fb_type masked with 0x07. - * Given the four supported fb_type values, this results in valid array - * indices of 3, 4, 5, and 7. - */ - static const uint32_t masks_table_rgb[8][4] = { - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */ - {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */ - {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */ - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */ - }; - - static const uint32_t masks_table_rgba[8][4] = { - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */ - {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */ - {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */ - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */ - }; - -#if 0 - static const uint32_t masks_table_bgr[8][4] = { - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */ - {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */ - {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */ - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */ - }; - - static const uint32_t masks_table_bgra[8][4] = { - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */ - {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */ - {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */ - {0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */ - }; -#endif - - static const uint8_t bytes_per_pixel[8] = { - 0, 0, 0, 2, 2, 4, 0, 4 - }; - - const uint8_t * bits; - const uint32_t * masks; - const int index = fb_type & 0x07; - _EGLConfig *config; - unsigned i; - unsigned j; - unsigned k; - - if ( bytes_per_pixel[index] == 0 ) { - _eglLog(_EGL_INFO, - "[_eglFillInConfigs:%u] Framebuffer type 0x%04x has 0 bytes per pixel.", - __LINE__, fb_type); - return GL_FALSE; - } - - /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and - * the _REV versions. - * - * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. - */ - switch ( fb_format ) { - case GL_RGB: - bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1]; - masks = masks_table_rgb[index]; - break; - - case GL_RGBA: - bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2]; - masks = masks_table_rgba[index]; - break; - -#if 0 - case GL_BGR: - bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1]; - masks = masks_table_bgr[index]; - break; - - case GL_BGRA: - bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2]; - masks = masks_table_bgra[index]; - break; -#endif - - default: - _eglLog(_EGL_WARNING, - "[_eglFillInConfigs:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.", - __LINE__, fb_format); - return GL_FALSE; - } - - config = configs; - for (k = 0; k < num_depth_stencil_bits; k++) { - for (i = 0; i < num_db_modes; i++) { - for (j = 0; j < 2; j++) { - _eglSetConfigAttrib(config, EGL_RED_SIZE, bits[0]); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, bits[1]); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, bits[2]); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, bits[3]); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, - bits[0] + bits[1] + bits[2] + bits[3]); - - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, stencil_bits[k]); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, depth_bits[i]); - - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_SCREEN_BIT_MESA | - EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT); - - config++; - } - } - } - return GL_TRUE; -} - diff --git a/src/egl/main/eglconfigutil.h b/src/egl/main/eglconfigutil.h index 9f8906dedb..c6f4819960 100644 --- a/src/egl/main/eglconfigutil.h +++ b/src/egl/main/eglconfigutil.h @@ -16,14 +16,4 @@ _eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m, EGLint conformant, EGLint renderable_type); -PUBLIC EGLBoolean -_eglFillInConfigs( _EGLConfig *configs, - EGLenum fb_format, EGLenum fb_type, - const uint8_t * depth_bits, const uint8_t * stencil_bits, - unsigned num_depth_stencil_bits, - const EGLenum * db_modes, unsigned num_db_modes, - int visType ); - - - #endif /* EGLCONFIGUTIL_INCLUDED */ diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index ee4b1b59f5..012d8dfe1f 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -4,9 +4,96 @@ #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.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->ClientVersion) { + case 1: + bit = EGL_OPENGL_ES_BIT; + break; + case 2: + bit = EGL_OPENGL_ES2_BIT; + 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, const EGLint *attrib_list) +{ + EGLenum api = ctx->ClientAPI; + 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_CONTEXT_CLIENT_VERSION: + if (api != EGL_OPENGL_ES_API) { + err = EGL_BAD_ATTRIBUTE; + break; + } + if (val != 1 && val != 2) { + err = EGL_BAD_ATTRIBUTE; + break; + } + ctx->ClientVersion = val; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr); + break; + } + } + + if (err == EGL_SUCCESS) { + EGLint renderable_type, api_bit; + + renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE); + api_bit = _eglGetContextAPIBit(ctx); + if (!(renderable_type & api_bit)) + err = EGL_BAD_CONFIG; + } + + return err; +} /** @@ -14,11 +101,11 @@ * in the attrib_list. */ EGLBoolean -_eglInitContext(_EGLDriver *drv, _EGLContext *ctx, - _EGLConfig *conf, const EGLint *attrib_list) +_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, + const EGLint *attrib_list) { - EGLint i; const EGLenum api = eglQueryAPI(); + EGLint err; if (api == EGL_NONE) { _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)"); @@ -26,26 +113,16 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx, } memset(ctx, 0, sizeof(_EGLContext)); + ctx->Resource.Display = dpy; + ctx->ClientAPI = api; + ctx->Config = conf; + ctx->WindowRenderBuffer = EGL_NONE; ctx->ClientVersion = 1; /* the default, per EGL spec */ - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_CONTEXT_CLIENT_VERSION: - i++; - ctx->ClientVersion = attrib_list[i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "_eglInitContext"); - return EGL_FALSE; - } - } - - ctx->Config = conf; - ctx->DrawSurface = EGL_NO_SURFACE; - ctx->ReadSurface = EGL_NO_SURFACE; - ctx->ClientAPI = api; - ctx->WindowRenderBuffer = EGL_NONE; + err = _eglParseContextAttribList(ctx, attrib_list); + if (err != EGL_SUCCESS) + return _eglError(err, "eglCreateContext"); return EGL_TRUE; } @@ -58,20 +135,6 @@ _EGLContext * _eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) { -#if 0 /* example code */ - _EGLContext *context; - - context = (_EGLContext *) calloc(1, sizeof(_EGLContext)); - if (!context) - return NULL; - - if (!_eglInitContext(drv, context, conf, attrib_list)) { - free(context); - return NULL; - } - - return context; -#endif return NULL; } @@ -140,99 +203,169 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, /** - * Drivers will typically call this to do the error checking and - * update the various flags. - * Then, the driver will do its device-dependent Make-Current stuff. + * Bind the context to the surfaces. Return the surfaces that are "orphaned". + * That is, when the context is not NULL, return the surfaces it previously + * bound to; when the context is NULL, the same surfaces are returned. */ -EGLBoolean -_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, - _EGLSurface *read, _EGLContext *ctx) +static void +_eglBindContextToSurfaces(_EGLContext *ctx, + _EGLSurface **draw, _EGLSurface **read) +{ + _EGLSurface *newDraw = *draw, *newRead = *read; + + if (newDraw->CurrentContext) + newDraw->CurrentContext->DrawSurface = NULL; + newDraw->CurrentContext = ctx; + + if (newRead->CurrentContext) + newRead->CurrentContext->ReadSurface = NULL; + newRead->CurrentContext = ctx; + + if (ctx) { + *draw = ctx->DrawSurface; + ctx->DrawSurface = newDraw; + + *read = ctx->ReadSurface; + ctx->ReadSurface = newRead; + } +} + + +/** + * 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) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *oldContext = NULL; - _EGLSurface *oldDrawSurface = NULL; - _EGLSurface *oldReadSurface = NULL; EGLint apiIndex; + _EGLContext *oldCtx; + + apiIndex = (ctx) ? + _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex; + + oldCtx = t->CurrentContexts[apiIndex]; + if (ctx == oldCtx) + return NULL; + + 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(); + EGLint conflict_api; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); - if (ctx) { - /* error checking */ - if (ctx->Binding && ctx->Binding != t) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - if (draw == NULL || read == NULL) + /* this is easy */ + if (!ctx) { + if (draw || read) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - if (draw->Config != ctx->Config || read->Config != ctx->Config) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - if ((draw->Binding && draw->Binding->Binding != t) || - (read->Binding && read->Binding->Binding != t)) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + return EGL_TRUE; + } + + /* ctx/draw/read must be all given */ + if (draw == NULL || read == NULL) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + + /* context stealing from another thread is not allowed */ + if (ctx->Binding && ctx->Binding != t) + return _eglError(EGL_BAD_ACCESS, "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." + * + * But it also says + * + * "at most one context may be bound to a particular surface at a given + * time" + * + * The latter is more restrictive so we can check only the latter case. + */ + if ((draw->CurrentContext && draw->CurrentContext != ctx) || + (read->CurrentContext && read->CurrentContext != ctx)) + return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); + /* simply require the configs to be equal */ + if (draw->Config != ctx->Config || read->Config != ctx->Config) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + + switch (ctx->ClientAPI) { #ifdef EGL_VERSION_1_4 - /* OpenGL and OpenGL ES are conflicting */ - switch (ctx->ClientAPI) { - case EGL_OPENGL_ES_API: - if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - break; - case EGL_OPENGL_API: - if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)]) - return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); - break; - default: - break; - } + /* 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; #endif - apiIndex = _eglConvertApiToIndex(ctx->ClientAPI); - } - else { - if (draw != NULL || read != NULL) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); - apiIndex = t->CurrentAPIIndex; + default: + conflict_api = -1; + break; } - oldContext = t->CurrentContexts[apiIndex]; - if (oldContext) { - oldDrawSurface = oldContext->DrawSurface; - oldReadSurface = oldContext->ReadSurface; - assert(oldDrawSurface); - assert(oldReadSurface); - - /* break old bindings */ - t->CurrentContexts[apiIndex] = NULL; - oldContext->Binding = NULL; - oldContext->DrawSurface = NULL; - oldContext->ReadSurface = NULL; - oldDrawSurface->Binding = NULL; - oldReadSurface->Binding = NULL; + 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 + * previously bound context and the surfaces it bound to. Each argument is + * both input and output. + */ +EGLBoolean +_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read) +{ + _EGLThreadInfo *t = _eglGetCurrentThread(); + _EGLContext *newCtx = *ctx, *oldCtx; + + if (!_eglCheckMakeCurrent(newCtx, *draw, *read)) + return EGL_FALSE; + + /* bind the new context */ + oldCtx = _eglBindContextToThread(newCtx, t); + *ctx = oldCtx; + if (newCtx) + _eglBindContextToSurfaces(newCtx, draw, read); + /* unbind the old context from its binding surfaces */ + if (oldCtx) { /* - * check if the old context or surfaces need to be deleted + * If the new context replaces some old context, the new one should not + * be current before the replacement and it should not be bound to any + * surface. */ - if (!_eglIsSurfaceLinked(oldDrawSurface)) { - assert(draw != oldDrawSurface && read != oldDrawSurface); - drv->API.DestroySurface(drv, dpy, oldDrawSurface); - } - if (oldReadSurface != oldDrawSurface && - !_eglIsSurfaceLinked(oldReadSurface)) { - assert(draw != oldReadSurface && read != oldReadSurface); - drv->API.DestroySurface(drv, dpy, oldReadSurface); - } - if (!_eglIsContextLinked(oldContext)) { - assert(ctx != oldContext); - drv->API.DestroyContext(drv, dpy, oldContext); - } - } + if (newCtx) + assert(!*draw && !*read); - /* build new bindings */ - if (ctx) { - t->CurrentContexts[apiIndex] = ctx; - ctx->Binding = t; - ctx->DrawSurface = draw; - ctx->ReadSurface = read; - draw->Binding = ctx; - read->Binding = ctx; + *draw = oldCtx->DrawSurface; + *read = oldCtx->ReadSurface; + assert(*draw && *read); + + _eglBindContextToSurfaces(NULL, draw, read); } return EGL_TRUE; @@ -240,6 +373,17 @@ _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, /** + * Just a placeholder/demo function. Drivers should override this. + */ +EGLBoolean +_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, + _EGLSurface *read, _EGLContext *ctx) +{ + return EGL_FALSE; +} + + +/** * This is defined by the EGL_MESA_copy_context extension. */ EGLBoolean diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index cb9e3f4a89..cfe92dd9f5 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -1,9 +1,9 @@ - #ifndef EGLCONTEXT_INCLUDED #define EGLCONTEXT_INCLUDED #include "egltypedefs.h" +#include "egldisplay.h" /** @@ -11,9 +11,8 @@ */ struct _egl_context { - /* Managed by EGLDisplay for linking */ - _EGLDisplay *Display; - _EGLContext *Next; + /* A context is a display resource */ + _EGLResource Resource; /* The bound status of the context */ _EGLThreadInfo *Binding; @@ -31,7 +30,7 @@ struct _egl_context PUBLIC EGLBoolean -_eglInitContext(_EGLDriver *drv, _EGLContext *ctx, +_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list); @@ -48,6 +47,10 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint att PUBLIC EGLBoolean +_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read); + + +extern EGLBoolean _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); @@ -57,6 +60,9 @@ _eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLConte /** * Return true if the context is bound to a thread. + * + * The binding is considered a reference to the context. Drivers should not + * destroy a context when it is bound. */ static INLINE EGLBoolean _eglIsContextBound(_EGLContext *ctx) @@ -65,4 +71,67 @@ _eglIsContextBound(_EGLContext *ctx) } +/** + * Link a context to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLContext +_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy) +{ + _eglLinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT, dpy); + return (EGLContext) ctx; +} + + +/** + * Unlink a linked context from its display. + * Accessing an unlinked context should generate EGL_BAD_CONTEXT error. + */ +static INLINE void +_eglUnlinkContext(_EGLContext *ctx) +{ + _eglUnlinkResource(&ctx->Resource, _EGL_RESOURCE_CONTEXT); +} + + +/** + * Lookup a handle to find the linked context. + * Return NULL if the handle has no corresponding linked context. + */ +static INLINE _EGLContext * +_eglLookupContext(EGLContext context, _EGLDisplay *dpy) +{ + _EGLContext *ctx = (_EGLContext *) context; + if (!dpy || !_eglCheckResource((void *) ctx, _EGL_RESOURCE_CONTEXT, dpy)) + ctx = NULL; + return ctx; +} + + +/** + * Return the handle of a linked context, or EGL_NO_CONTEXT. + */ +static INLINE EGLContext +_eglGetContextHandle(_EGLContext *ctx) +{ + _EGLResource *res = (_EGLResource *) ctx; + return (res && _eglIsResourceLinked(res)) ? + (EGLContext) ctx : EGL_NO_CONTEXT; +} + + +/** + * Return true if the context is linked to a display. + * + * The link is considered a reference to the context (the display is owning the + * context). Drivers should not destroy a context when it is linked. + */ +static INLINE EGLBoolean +_eglIsContextLinked(_EGLContext *ctx) +{ + _EGLResource *res = (_EGLResource *) ctx; + return (res && _eglIsResourceLinked(res)); +} + + #endif /* EGLCONTEXT_INCLUDED */ diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index df506151b5..989c19a2fa 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -1,10 +1,9 @@ #include <stdlib.h> #include <string.h> -#include "eglcurrent.h" -#include "eglcontext.h" +#include "eglglobals.h" #include "egllog.h" #include "eglmutex.h" -#include "eglglobals.h" +#include "eglcurrent.h" /* This should be kept in sync with _eglInitThreadInfo() */ @@ -227,50 +226,24 @@ _eglIsCurrentThreadDummy(void) /** - * Return the currently bound context, or NULL. - */ -_EGLContext * -_eglGetCurrentContext(void) -{ - _EGLThreadInfo *t = _eglGetCurrentThread(); - return t->CurrentContexts[t->CurrentAPIIndex]; -} - - -/** - * Return the display of the currently bound context, or NULL. + * Return the currently bound context of the given API, or NULL. */ -_EGLDisplay * -_eglGetCurrentDisplay(void) +PUBLIC _EGLContext * +_eglGetAPIContext(EGLenum api) { _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; - if (ctx) - return ctx->Display; - else - return NULL; + return t->CurrentContexts[_eglConvertApiToIndex(api)]; } /** - * Return the read or write surface of the currently bound context, or NULL. + * Return the currently bound context of the current API, or NULL. */ -_EGLSurface * -_eglGetCurrentSurface(EGLint readdraw) +_EGLContext * +_eglGetCurrentContext(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContexts[t->CurrentAPIIndex]; - if (ctx) { - switch (readdraw) { - case EGL_DRAW: - return ctx->DrawSurface; - case EGL_READ: - return ctx->ReadSurface; - default: - return NULL; - } - } - return NULL; + return t->CurrentContexts[t->CurrentAPIIndex]; } diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index c4478b3891..e5c94ce60a 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -1,6 +1,7 @@ #ifndef EGLCURRENT_INCLUDED #define EGLCURRENT_INCLUDED + #include "egltypedefs.h" @@ -73,15 +74,11 @@ _eglIsCurrentThreadDummy(void); PUBLIC _EGLContext * -_eglGetCurrentContext(void); - +_eglGetAPIContext(EGLenum api); -PUBLIC _EGLDisplay * -_eglGetCurrentDisplay(void); - -PUBLIC _EGLSurface * -_eglGetCurrentSurface(EGLint readdraw); +PUBLIC _EGLContext * +_eglGetCurrentContext(void); PUBLIC EGLBoolean diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 896d60dbe1..d7a8d14292 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -10,7 +10,6 @@ #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglstring.h" #include "eglmutex.h" #include "egllog.h" @@ -26,12 +25,18 @@ _eglFiniDisplay(void) /* atexit function is called with global mutex locked */ dpyList = _eglGlobal.DisplayList; while (dpyList) { + EGLint i; + /* pop list head */ dpy = dpyList; dpyList = dpyList->Next; - if (dpy->ContextList || dpy->SurfaceList) - _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); + 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); } @@ -40,53 +45,17 @@ _eglFiniDisplay(void) /** - * If the first character is '!' we interpret it as specific driver name - * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as - * arguments. - * - * The caller may free() the returned driver name. - */ -char * -_eglSplitDisplayString(const char *dpyString, const char **args) -{ - char *drv, *p; - - if (!dpyString || dpyString[0] != '!') - return NULL; - drv = _eglstrdup(dpyString + 1); - if (!drv) - return NULL; - - p = strchr(dpyString, ':'); - if (p) { - drv[p - dpyString] = '\0'; - p++; - } - if (args) - *args = p; - - return drv; -} - - -/** * Allocate a new _EGLDisplay object for the given nativeDisplay handle. * We'll also try to determine the device driver name at this time. * * Note that nativeDisplay may be an X Display ptr, or a string. */ _EGLDisplay * -_eglNewDisplay(NativeDisplayType nativeDisplay) +_eglNewDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); if (dpy) { dpy->NativeDisplay = nativeDisplay; - - dpy->DriverName = _eglPreloadDriver(dpy); - if (!dpy->DriverName) { - free(dpy); - return NULL; - } } return dpy; } @@ -144,7 +113,7 @@ _eglUnlinkDisplay(_EGLDisplay *dpy) * linked displays. */ _EGLDisplay * -_eglFindDisplay(NativeDisplayType nativeDisplay) +_eglFindDisplay(EGLNativeDisplayType nativeDisplay) { _EGLDisplay *dpy; @@ -171,29 +140,27 @@ _eglFindDisplay(NativeDisplayType nativeDisplay) void _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) { - _EGLContext *contexts; - _EGLSurface *surfaces; - - contexts = display->ContextList; - surfaces = display->SurfaceList; + _EGLResource *list; - while (contexts) { - _EGLContext *ctx = contexts; - contexts = contexts->Next; + 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->ContextList); + assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); - while (surfaces) { - _EGLSurface *surf = surfaces; - surfaces = surfaces->Next; + 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->SurfaceList); + assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); } @@ -212,97 +179,13 @@ _eglCleanupDisplay(_EGLDisplay *disp) free(disp->Configs); disp->Configs = NULL; disp->NumConfigs = 0; + disp->MaxConfigs = 0; } /* XXX incomplete */ } -/** - * Link a context to a display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLContext -_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy) -{ - ctx->Display = dpy; - ctx->Next = dpy->ContextList; - dpy->ContextList = ctx; - return (EGLContext) ctx; -} - - -/** - * Unlink a linked context from its display. - * Accessing an unlinked context should generate EGL_BAD_CONTEXT error. - */ -void -_eglUnlinkContext(_EGLContext *ctx) -{ - _EGLContext *prev; - - prev = ctx->Display->ContextList; - if (prev != ctx) { - while (prev) { - if (prev->Next == ctx) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = ctx->Next; - } - else { - ctx->Display->ContextList = ctx->Next; - } - - ctx->Next = NULL; - ctx->Display = NULL; -} - - -/** - * Link a surface to a display and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLSurface -_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) -{ - surf->Display = dpy; - surf->Next = dpy->SurfaceList; - dpy->SurfaceList = surf; - return (EGLSurface) surf; -} - - -/** - * Unlink a linked surface from its display. - * Accessing an unlinked surface should generate EGL_BAD_SURFACE error. - */ -void -_eglUnlinkSurface(_EGLSurface *surf) -{ - _EGLSurface *prev; - - prev = surf->Display->SurfaceList; - if (prev != surf) { - while (prev) { - if (prev->Next == surf) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = surf->Next; - } - else { - prev = NULL; - surf->Display->SurfaceList = surf->Next; - } - - surf->Next = NULL; - surf->Display = NULL; -} - - #ifndef _EGL_SKIP_HANDLE_CHECK @@ -327,45 +210,70 @@ _eglCheckDisplayHandle(EGLDisplay dpy) /** - * Return EGL_TRUE if the given handle is a valid handle to a context. + * Return EGL_TRUE if the given resource is valid. That is, the display does + * own the resource. */ EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) +_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy) { - _EGLContext *cur = NULL; - - if (dpy) - cur = dpy->ContextList; - while (cur) { - if (cur == (_EGLContext *) ctx) { - assert(cur->Display == dpy); + _EGLResource *list = dpy->ResourceLists[type]; + + if (!res) + return EGL_FALSE; + + while (list) { + if (res == (void *) list) { + assert(list->Display == dpy); break; } - cur = cur->Next; + list = list->Next; } - return (cur != NULL); + + return (list != NULL); } +#endif /* !_EGL_SKIP_HANDLE_CHECK */ + + /** - * Return EGL_TRUE if the given handle is a valid handle to a surface. + * Link a resource to a display. */ -EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) +void +_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy) { - _EGLSurface *cur = NULL; + assert(!res->Display || res->Display == dpy); - if (dpy) - cur = dpy->SurfaceList; - while (cur) { - if (cur == (_EGLSurface *) surf) { - assert(cur->Display == dpy); - break; - } - cur = cur->Next; - } - return (cur != NULL); + res->Display = dpy; + res->IsLinked = EGL_TRUE; + res->Next = dpy->ResourceLists[type]; + dpy->ResourceLists[type] = res; } -#endif /* !_EGL_SKIP_HANDLE_CHECK */ +/** + * 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; + /* do not reset res->Display */ + res->IsLinked = EGL_FALSE; +} diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 4f619e5371..03903290fd 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -1,10 +1,32 @@ #ifndef EGLDISPLAY_INCLUDED #define EGLDISPLAY_INCLUDED + #include "egltypedefs.h" #include "egldefines.h" -#include "eglcontext.h" -#include "eglsurface.h" + + +enum _egl_resource_type { + _EGL_RESOURCE_CONTEXT, + _EGL_RESOURCE_SURFACE, + _EGL_RESOURCE_IMAGE, + + _EGL_NUM_RESOURCES +}; + + +/** + * A resource of a display. + */ +struct _egl_resource +{ + /* which display the resource belongs to */ + _EGLDisplay *Display; + EGLBoolean IsLinked; + + /* used to link resources of the same type */ + _EGLResource *Next; +}; /** @@ -14,6 +36,13 @@ struct _egl_extensions { EGLBoolean MESA_screen_surface; EGLBoolean MESA_copy_context; + EGLBoolean KHR_image_base; + EGLBoolean KHR_image_pixmap; + EGLBoolean KHR_vg_parent_image; + EGLBoolean KHR_gl_texture_2D_image; + EGLBoolean KHR_gl_texture_cubemap_image; + EGLBoolean KHR_gl_texture_3D_image; + EGLBoolean KHR_gl_renderbuffer_image; char String[_EGL_MAX_EXTENSIONS_LEN]; }; @@ -26,7 +55,7 @@ struct _egl_display EGLNativeDisplayType NativeDisplay; - const char *DriverName; + EGLBoolean Initialized; /**< True if the display is initialized */ _EGLDriver *Driver; void *DriverData; /* private to driver */ @@ -39,8 +68,6 @@ struct _egl_display _EGLExtensions Extensions; - int LargestPbuffer; - EGLint NumScreens; _EGLScreen **Screens; /* array [NumScreens] */ @@ -48,9 +75,8 @@ struct _egl_display EGLint NumConfigs; _EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */ - /* lists of linked contexts and surface */ - _EGLContext *ContextList; - _EGLSurface *SurfaceList; + /* lists of resources */ + _EGLResource *ResourceLists[_EGL_NUM_RESOURCES]; }; @@ -58,12 +84,8 @@ extern void _eglFiniDisplay(void); -extern char * -_eglSplitDisplayString(const char *dpyString, const char **args); - - extern _EGLDisplay * -_eglNewDisplay(NativeDisplayType displayName); +_eglNewDisplay(EGLNativeDisplayType displayName); extern EGLDisplay @@ -75,7 +97,7 @@ _eglUnlinkDisplay(_EGLDisplay *dpy); extern _EGLDisplay * -_eglFindDisplay(NativeDisplayType nativeDisplay); +_eglFindDisplay(EGLNativeDisplayType nativeDisplay); PUBLIC void @@ -86,22 +108,6 @@ PUBLIC void _eglCleanupDisplay(_EGLDisplay *disp); -extern EGLContext -_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy); - - -extern void -_eglUnlinkContext(_EGLContext *ctx); - - -extern EGLSurface -_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy); - - -extern void -_eglUnlinkSurface(_EGLSurface *surf); - - #ifndef _EGL_SKIP_HANDLE_CHECK @@ -109,12 +115,8 @@ extern EGLBoolean _eglCheckDisplayHandle(EGLDisplay dpy); -extern EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy); - - -extern EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy); +PUBLIC EGLBoolean +_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy); #else /* !_EGL_SKIP_HANDLE_CHECK */ @@ -129,18 +131,9 @@ _eglCheckDisplayHandle(EGLDisplay dpy) static INLINE EGLBoolean -_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) +_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy); { - _EGLContext *c = (_EGLContext *) ctx; - return (dpy && c && c->Display == dpy); -} - - -static INLINE EGLBoolean -_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) -{ - _EGLSurface *s = (_EGLSurface *) surf; - return (dpy && s && s->Display == dpy); + return (((_EGLResource *) res)->Display == dpy); } @@ -181,92 +174,21 @@ _eglIsDisplayLinked(_EGLDisplay *dpy) } -/** - * Lookup a handle to find the linked context. - * Return NULL if the handle has no corresponding linked context. - */ -static INLINE _EGLContext * -_eglLookupContext(EGLContext context, _EGLDisplay *dpy) -{ - _EGLContext *ctx = (_EGLContext *) context; - if (!_eglCheckContextHandle(context, dpy)) - ctx = NULL; - return ctx; -} - - -/** - * Return the handle of a linked context, or EGL_NO_CONTEXT. - */ -static INLINE EGLContext -_eglGetContextHandle(_EGLContext *ctx) -{ - return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT); -} - - -/** - * Return true if the context is linked to a display. - */ -static INLINE EGLBoolean -_eglIsContextLinked(_EGLContext *ctx) -{ - return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT); -} - - -/** - * 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 (!_eglCheckSurfaceHandle(surf, dpy)) - surf = NULL; - return surf; -} +extern void +_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy); -/** - * Return the handle of a linked surface, or EGL_NO_SURFACE. - */ -static INLINE EGLSurface -_eglGetSurfaceHandle(_EGLSurface *surf) -{ - return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE); -} +extern void +_eglUnlinkResource(_EGLResource *res, _EGLResourceType type); /** - * Return true if the surface is linked to a display. + * Return true if the resource is linked. */ static INLINE EGLBoolean -_eglIsSurfaceLinked(_EGLSurface *surf) -{ - return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE); -} - - -/** - * Cast an unsigned int to a pointer. - */ -static INLINE void * -_eglUIntToPointer(unsigned int v) -{ - return (void *) ((uintptr_t) v); -} - - -/** - * Cast a pointer to an unsigned int. The pointer must be one that is - * returned by _eglUIntToPointer. - */ -static INLINE unsigned int -_eglPointerToUInt(const void *p) +_eglIsResourceLinked(_EGLResource *res) { - return (unsigned int) ((uintptr_t) p); + return res->IsLinked; } diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 018b06d3be..a87c697b11 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -19,9 +19,13 @@ #include "eglscreen.h" #include "eglstring.h" #include "eglsurface.h" +#include "eglimage.h" -#if defined(_EGL_PLATFORM_X) +#if defined(_EGL_PLATFORM_POSIX) #include <dlfcn.h> +#include <sys/types.h> +#include <dirent.h> +#include <unistd.h> #endif @@ -49,10 +53,17 @@ close_library(HMODULE lib) } -#elif defined(_EGL_PLATFORM_X) +static const char * +library_suffix(void) +{ + return ".dll"; +} + + +#elif defined(_EGL_PLATFORM_POSIX) -static const char DefaultDriverName[] = "egl_softpipe"; +static const char DefaultDriverName[] = "egl_glx"; typedef void * lib_handle; @@ -68,8 +79,17 @@ close_library(void *lib) dlclose(lib); } + +static const char * +library_suffix(void) +{ + return ".so"; +} + + #else /* _EGL_PLATFORM_NO_OS */ + static const char DefaultDriverName[] = "builtin"; typedef void *lib_handle; @@ -86,67 +106,21 @@ close_library(void *lib) } -#endif +static const char * +library_suffix(void) +{ + return NULL; +} -/** - * Choose a driver for a given display. - * The caller may free() the returned strings. - */ -static char * -_eglChooseDriver(_EGLDisplay *dpy, char **argsRet) -{ - char *path = NULL; - const char *args = NULL; - const char *suffix = NULL; - const char *p; - - path = getenv("EGL_DRIVER"); - if (path) - path = _eglstrdup(path); - -#if defined(_EGL_PLATFORM_X) - if (!path && dpy && dpy->NativeDisplay) { - /* assume (wrongly!) that the native display is a display string */ - path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args); - } - suffix = "so"; -#elif defined(_EGL_PLATFORM_WINDOWS) - suffix = "dll"; -#else /* _EGL_PLATFORM_NO_OS */ - if (path) { - /* force the use of the default driver */ - _eglLog(_EGL_DEBUG, "ignore EGL_DRIVER"); - free(path); - path = NULL; - } - suffix = NULL; #endif - if (!path) - path = _eglstrdup(DefaultDriverName); - - /* append suffix if there isn't */ - p = strrchr(path, '.'); - if (!p && suffix) { - size_t len = strlen(path); - char *tmp = malloc(len + strlen(suffix) + 2); - if (tmp) { - memcpy(tmp, path, len); - tmp[len++] = '.'; - tmp[len] = '\0'; - strcat(tmp + len, suffix); - - free(path); - path = tmp; - } - } - - if (argsRet) - *argsRet = (args) ? _eglstrdup(args) : NULL; - return path; -} +#define NUM_PROBE_CACHE_SLOTS 8 +static struct { + EGLint keys[NUM_PROBE_CACHE_SLOTS]; + const void *values[NUM_PROBE_CACHE_SLOTS]; +} _eglProbeCache; /** @@ -168,7 +142,7 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle) /* XXX untested */ if (lib) mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); -#elif defined(_EGL_PLATFORM_X) +#elif defined(_EGL_PLATFORM_POSIX) if (lib) { mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain"); if (!mainFunc) @@ -208,11 +182,10 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle) /** - * Load the named driver. The path and args passed will be - * owned by the driver and freed. + * Load the named driver. */ static _EGLDriver * -_eglLoadDriver(char *path, char *args) +_eglLoadDriver(const char *path, const char *args) { _EGLMain_t mainFunc; lib_handle lib; @@ -234,8 +207,19 @@ _eglLoadDriver(char *path, char *args) drv->Name = "UNNAMED"; } - drv->Path = path; - drv->Args = args; + drv->Path = _eglstrdup(path); + drv->Args = (args) ? _eglstrdup(args) : NULL; + if (!drv->Path || (args && !drv->Args)) { + if (drv->Path) + free((char *) drv->Path); + if (drv->Args) + free((char *) drv->Args); + drv->Unload(drv); + if (lib) + close_library(lib); + return NULL; + } + drv->LibHandle = lib; return drv; @@ -244,89 +228,316 @@ _eglLoadDriver(char *path, char *args) /** * Match a display to a preloaded driver. + * + * The matching is done by finding the driver with the highest score. */ -static _EGLDriver * +_EGLDriver * _eglMatchDriver(_EGLDisplay *dpy) { - _EGLDriver *defaultDriver = NULL; - EGLint i; + _EGLDriver *best_drv = NULL; + EGLint best_score = -1, i; for (i = 0; i < _eglGlobal.NumDrivers; i++) { _EGLDriver *drv = _eglGlobal.Drivers[i]; + EGLint score; + + score = (drv->Probe) ? drv->Probe(drv, dpy) : 0; + if (score > best_score) { + if (best_drv) { + _eglLog(_EGL_DEBUG, "driver %s has higher score than %s", + drv->Name, best_drv->Name); + } + + best_drv = drv; + best_score = score; + /* perfect match */ + if (score >= 100) + break; + } + } + + return best_drv; +} - /* display specifies a driver */ - if (dpy->DriverName) { - if (strcmp(dpy->DriverName, drv->Name) == 0) - return drv; + +/** + * 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) +{ + _EGLDriver *drv; + 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'; + + drv = _eglLoadDriver(path, NULL); + /* fix the path and load again */ + if (!drv && 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 && len + slen + 1 <= sizeof(path)) { + strcpy(path + len, suffix); + drv = _eglLoadDriver(path, NULL); } - else if (drv->Probe) { - if (drv->Probe(drv, dpy)) - return drv; + } + if (!drv) + return EGL_TRUE; + + /* remember the driver and stop */ + _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; + return EGL_FALSE; +} + + +/** + * A loader function for use with _eglPreloadForEach. The loader data is the + * pattern (prefix) of the files to look for. + */ +static EGLBoolean +_eglLoaderPattern(const char *dir, size_t len, void *loader_data) +{ +#if defined(_EGL_PLATFORM_POSIX) + const char *prefix, *suffix; + size_t prefix_len, suffix_len; + DIR *dirp; + struct dirent *dirent; + char path[1024]; + + if (len + 2 > sizeof(path)) + return EGL_TRUE; + if (len) { + memcpy(path, dir, len); + path[len++] = '/'; + } + path[len] = '\0'; + + dirp = opendir(path); + if (!dirp) + return EGL_TRUE; + + prefix = (const char *) loader_data; + prefix_len = strlen(prefix); + suffix = library_suffix(); + suffix_len = (suffix) ? strlen(suffix) : 0; + + while ((dirent = readdir(dirp))) { + _EGLDriver *drv; + size_t dirent_len = strlen(dirent->d_name); + const char *p; + + /* match the prefix */ + if (strncmp(dirent->d_name, prefix, prefix_len) != 0) + continue; + /* match the suffix */ + if (suffix) { + p = dirent->d_name + dirent_len - suffix_len; + if (p < dirent->d_name || strcmp(p, suffix) != 0) + continue; } - else { - if (!defaultDriver) - defaultDriver = drv; + + /* make a full path and load the driver */ + if (len + dirent_len + 1 <= sizeof(path)) { + strcpy(path + len, dirent->d_name); + drv = _eglLoadDriver(path, NULL); + if (drv) + _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; } } - return defaultDriver; + closedir(dirp); + + return EGL_TRUE; +#else /* _EGL_PLATFORM_POSIX */ + /* stop immediately */ + return EGL_FALSE; +#endif } /** - * Load a driver and save it. + * Run the preload function on each driver directory and return the number of + * drivers loaded. + * + * The process may end prematurely if the callback function returns false. */ -const char * -_eglPreloadDriver(_EGLDisplay *dpy) +static EGLint +_eglPreloadForEach(const char *search_path, + EGLBoolean (*loader)(const char *, size_t, void *), + void *loader_data) { - char *path, *args; - _EGLDriver *drv; - EGLint i; + const char *cur, *next; + size_t len; + EGLint num_drivers = _eglGlobal.NumDrivers; - path = _eglChooseDriver(dpy, &args); - if (!path) - return NULL; + cur = search_path; + while (cur) { + next = strchr(cur, ':'); + len = (next) ? next - cur : strlen(cur); - for (i = 0; i < _eglGlobal.NumDrivers; i++) { - drv = _eglGlobal.Drivers[i]; - if (strcmp(drv->Path, path) == 0) { - _eglLog(_EGL_DEBUG, "Driver %s is already preloaded", - drv->Name); - free(path); - if (args) - free(args); - return drv->Name; + if (!loader(cur, len, loader_data)) + break; + + cur = (next) ? next + 1 : NULL; + } + + return (_eglGlobal.NumDrivers - num_drivers); +} + + +/** + * Return a list of colon-separated driver directories. + */ +static const char * +_eglGetSearchPath(void) +{ + static const char *search_path; + +#if defined(_EGL_PLATFORM_POSIX) || defined(_EGL_PLATFORM_WINDOWS) + if (!search_path) { + static char buffer[1024]; + const char *p; + int ret; + + p = getenv("EGL_DRIVERS_PATH"); +#if defined(_EGL_PLATFORM_POSIX) + if (p && (geteuid() != getuid() || getegid() != getgid())) { + _eglLog(_EGL_DEBUG, + "ignore EGL_DRIVERS_PATH for setuid/setgid binaries"); + p = NULL; + } +#endif /* _EGL_PLATFORM_POSIX */ + + if (p) { + ret = snprintf(buffer, sizeof(buffer), + "%s:%s", p, _EGL_DRIVER_SEARCH_DIR); + if (ret > 0 && ret < sizeof(buffer)) + search_path = buffer; } } + if (!search_path) + search_path = _EGL_DRIVER_SEARCH_DIR; +#else + search_path = ""; +#endif - drv = _eglLoadDriver(path, args); - if (!drv) - return NULL; + return search_path; +} - _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; - return drv->Name; +/** + * Preload a user driver. + * + * A user driver can be specified by EGL_DRIVER. + */ +static EGLBoolean +_eglPreloadUserDriver(void) +{ + const char *search_path = _eglGetSearchPath(); + char *env; + + env = getenv("EGL_DRIVER"); +#if defined(_EGL_PLATFORM_POSIX) + if (env && strchr(env, '/')) { + search_path = ""; + if ((geteuid() != getuid() || getegid() != getgid())) { + _eglLog(_EGL_DEBUG, + "ignore EGL_DRIVER for setuid/setgid binaries"); + env = NULL; + } + } +#endif /* _EGL_PLATFORM_POSIX */ + if (!env) + return EGL_FALSE; + + if (!_eglPreloadForEach(search_path, _eglLoaderFile, (void *) env)) { + _eglLog(_EGL_WARNING, "EGL_DRIVER is set to an invalid driver"); + return EGL_FALSE; + } + + return EGL_TRUE; } /** - * Open a preloaded driver. + * Preload display drivers. + * + * Display drivers are a set of drivers that support a certain display system. + * The display system may be specified by EGL_DISPLAY. + * + * FIXME This makes libEGL a memory hog if an user driver is not specified and + * there are many display drivers. */ -_EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy) +static EGLBoolean +_eglPreloadDisplayDrivers(void) { - _EGLDriver *drv = _eglMatchDriver(dpy); - return drv; + const char *dpy; + char prefix[32]; + int ret; + + dpy = getenv("EGL_DISPLAY"); + if (!dpy || !dpy[0]) + dpy = _EGL_DEFAULT_DISPLAY; + if (!dpy || !dpy[0]) + return EGL_FALSE; + + ret = snprintf(prefix, sizeof(prefix), "egl_%s_", dpy); + if (ret < 0 || ret >= sizeof(prefix)) + return EGL_FALSE; + + return (_eglPreloadForEach(_eglGetSearchPath(), + _eglLoaderPattern, (void *) prefix) > 0); +} + + +/** + * Preload the default driver. + */ +static EGLBoolean +_eglPreloadDefaultDriver(void) +{ + return (_eglPreloadForEach(_eglGetSearchPath(), + _eglLoaderFile, (void *) DefaultDriverName) > 0); } /** - * Close a preloaded driver. + * Preload drivers. + * + * This function loads the driver modules and creates the corresponding + * _EGLDriver objects. */ EGLBoolean -_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy) +_eglPreloadDrivers(void) { - return EGL_TRUE; + EGLBoolean loaded; + + /* already preloaded */ + if (_eglGlobal.NumDrivers) + return EGL_TRUE; + + loaded = (_eglPreloadUserDriver() || + _eglPreloadDisplayDrivers() || + _eglPreloadDefaultDriver()); + + return loaded; } @@ -360,20 +571,6 @@ _eglUnloadDrivers(void) /** - * Given a display handle, return the _EGLDriver for that display. - */ -_EGLDriver * -_eglLookupDriver(EGLDisplay dpy) -{ - _EGLDisplay *d = _eglLookupDisplay(dpy); - if (d) - return d->Driver; - else - return NULL; -} - - -/** * Plug all the available fallback routines into the given driver's * dispatch table. */ @@ -428,56 +625,50 @@ _eglInitDriverFallbacks(_EGLDriver *drv) #ifdef EGL_VERSION_1_2 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer; #endif /* EGL_VERSION_1_2 */ -} +#ifdef EGL_KHR_image_base + drv->API.CreateImageKHR = _eglCreateImageKHR; + drv->API.DestroyImageKHR = _eglDestroyImageKHR; +#endif /* EGL_KHR_image_base */ +} /** - * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc) - * are supported on the system by looking for standard library names. + * Set the probe cache at the given key. + * + * A key, instead of a _EGLDriver, is used to allow the probe cache to be share + * by multiple drivers. */ -EGLint -_eglFindAPIs(void) +void +_eglSetProbeCache(EGLint key, const void *val) { - EGLint mask = 0x0; - lib_handle lib; -#if defined(_EGL_PLATFORM_WINDOWS) - /* XXX not sure about these names */ - const char *es1_libname = "libGLESv1_CM.dll"; - const char *es2_libname = "libGLESv2.dll"; - const char *gl_libname = "OpenGL32.dll"; - const char *vg_libname = "libOpenVG.dll"; -#elif defined(_EGL_PLATFORM_X) - const char *es1_libname = "libGLESv1_CM.so"; - const char *es2_libname = "libGLESv2.so"; - const char *gl_libname = "libGL.so"; - const char *vg_libname = "libOpenVG.so"; -#else /* _EGL_PLATFORM_NO_OS */ - const char *es1_libname = NULL; - const char *es2_libname = NULL; - const char *gl_libname = NULL; - const char *vg_libname = NULL; -#endif + EGLint idx; - if ((lib = open_library(es1_libname))) { - close_library(lib); - mask |= EGL_OPENGL_ES_BIT; + for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) { + if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key) + break; } + assert(key > 0); + assert(idx < NUM_PROBE_CACHE_SLOTS); - if ((lib = open_library(es2_libname))) { - close_library(lib); - mask |= EGL_OPENGL_ES2_BIT; - } + _eglProbeCache.keys[idx] = key; + _eglProbeCache.values[idx] = val; +} - if ((lib = open_library(gl_libname))) { - close_library(lib); - mask |= EGL_OPENGL_BIT; - } - if ((lib = open_library(vg_libname))) { - close_library(lib); - mask |= EGL_OPENVG_BIT; +/** + * Return the probe cache at the given key. + */ +const void * +_eglGetProbeCache(EGLint key) +{ + EGLint idx; + + for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) { + if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key) + break; } - return mask; + return (idx < NUM_PROBE_CACHE_SLOTS && _eglProbeCache.keys[idx] == key) ? + _eglProbeCache.values[idx] : NULL; } diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 59bd1954aa..55686681dc 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -7,6 +7,36 @@ /** + * Define an inline driver typecast function. + * + * Note that this macro defines a function and should not be ended with a + * semicolon when used. + */ +#define _EGL_DRIVER_TYPECAST(drvtype, egltype, code) \ + static INLINE struct drvtype *drvtype(const egltype *obj) \ + { return (struct drvtype *) code; } + + +/** + * Define the driver typecast functions for _EGLDriver, _EGLDisplay, + * _EGLContext, _EGLSurface, and _EGLConfig. + * + * Note that this macro defines several functions and should not be ended with + * a semicolon when used. + */ +#define _EGL_DRIVER_STANDARD_TYPECASTS(drvname) \ + _EGL_DRIVER_TYPECAST(drvname ## _driver, _EGLDriver, obj) \ + /* note that this is not a direct cast */ \ + _EGL_DRIVER_TYPECAST(drvname ## _display, _EGLDisplay, obj->DriverData) \ + _EGL_DRIVER_TYPECAST(drvname ## _context, _EGLContext, obj) \ + _EGL_DRIVER_TYPECAST(drvname ## _surface, _EGLSurface, obj) \ + _EGL_DRIVER_TYPECAST(drvname ## _config, _EGLConfig, obj) + + +typedef _EGLDriver *(*_EGLMain_t)(const char *args); + + +/** * Base class for device drivers. */ struct _egl_driver @@ -16,9 +46,22 @@ struct _egl_driver const char *Args; /**< args to load this driver */ const char *Name; /**< name of this driver */ - /**< probe a display to see if it is supported */ - EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy); - /**< called before dlclose to release this driver */ + + /** + * Probe a display and return a score. + * + * Roughly, + * 50 means the driver supports the display; + * 90 means the driver can accelerate the display; + * 100 means a perfect match. + */ + EGLint (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy); + + /** + * Release the driver resource. + * + * It is called before dlclose(). + */ void (*Unload)(_EGLDriver *drv); _EGLAPI API; /**< EGL API dispatch table */ @@ -29,32 +72,28 @@ PUBLIC _EGLDriver * _eglMain(const char *args); -extern const char * -_eglPreloadDriver(_EGLDisplay *dpy); - - extern _EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy); +_eglMatchDriver(_EGLDisplay *dpy); extern EGLBoolean -_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy); +_eglPreloadDrivers(void); -void +extern void _eglUnloadDrivers(void); -extern _EGLDriver * -_eglLookupDriver(EGLDisplay d); +PUBLIC void +_eglInitDriverFallbacks(_EGLDriver *drv); PUBLIC void -_eglInitDriverFallbacks(_EGLDriver *drv); +_eglSetProbeCache(EGLint key, const void *val); -PUBLIC EGLint -_eglFindAPIs(void); +PUBLIC const void * +_eglGetProbeCache(EGLint key); #endif /* EGLDRIVER_INCLUDED */ diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 443d0f072c..5182b18e22 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,8 +1,8 @@ #include <stdlib.h> #include <assert.h> #include "eglglobals.h" +#include "egldisplay.h" #include "egldriver.h" -#include "egllog.h" #include "eglmutex.h" diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index 5ebb914ca7..cd1dd5851b 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -1,9 +1,8 @@ #ifndef EGLGLOBALS_INCLUDED #define EGLGLOBALS_INCLUDED + #include "egltypedefs.h" -#include "egldisplay.h" -#include "eglcurrent.h" #include "eglmutex.h" diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c new file mode 100644 index 0000000000..5732ef35ec --- /dev/null +++ b/src/egl/main/eglimage.c @@ -0,0 +1,90 @@ +#include <assert.h> +#include <string.h> + +#include "eglimage.h" +#include "eglcurrent.h" +#include "egllog.h" + + +#ifdef EGL_KHR_image_base + + +/** + * Parse the list of image attributes and return the proper error code. + */ +static EGLint +_eglParseImageAttribList(_EGLImage *img, 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_IMAGE_PRESERVED_KHR: + img->Preserved = val; + break; + case EGL_GL_TEXTURE_LEVEL_KHR: + img->GLTextureLevel = val; + break; + case EGL_GL_TEXTURE_ZOFFSET_KHR: + img->GLTextureZOffset = val; + break; + default: + /* unknown attrs are ignored */ + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_DEBUG, "bad image attribute 0x%04x", attr); + break; + } + } + + return err; +} + + +EGLBoolean +_eglInitImage(_EGLImage *img, _EGLDisplay *dpy, const EGLint *attrib_list) +{ + EGLint err; + + memset(img, 0, sizeof(_EGLImage)); + img->Resource.Display = dpy; + + img->Preserved = EGL_FALSE; + img->GLTextureLevel = 0; + img->GLTextureZOffset = 0; + + err = _eglParseImageAttribList(img, attrib_list); + if (err != EGL_SUCCESS) + return _eglError(err, "eglCreateImageKHR"); + + return EGL_TRUE; +} + + +_EGLImage * +_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, + const EGLint *attr_list) +{ + /* driver should override this function */ + return NULL; +} + + +EGLBoolean +_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image) +{ + /* driver should override this function */ + return EGL_FALSE; +} + + +#endif /* EGL_KHR_image_base */ diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h new file mode 100644 index 0000000000..2c0fb16d1d --- /dev/null +++ b/src/egl/main/eglimage.h @@ -0,0 +1,96 @@ +#ifndef EGLIMAGE_INCLUDED +#define EGLIMAGE_INCLUDED + + +#include "egltypedefs.h" +#include "egldisplay.h" + + +/** + * "Base" class for device driver images. + */ +struct _egl_image +{ + /* An image is a display resource */ + _EGLResource Resource; + + EGLBoolean Preserved; + EGLint GLTextureLevel; + EGLint GLTextureZOffset; +}; + + +PUBLIC EGLBoolean +_eglInitImage(_EGLImage *img, _EGLDisplay *dpy, const EGLint *attrib_list); + + +extern _EGLImage * +_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, + EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list); + + +extern EGLBoolean +_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); + + +/** + * Link an image to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLImageKHR +_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy) +{ + _eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE, dpy); + return (EGLImageKHR) img; +} + + +/** + * Unlink a linked image from its display. + * Accessing an unlinked image should generate EGL_BAD_PARAMETER error. + */ +static INLINE void +_eglUnlinkImage(_EGLImage *img) +{ + _eglUnlinkResource(&img->Resource, _EGL_RESOURCE_IMAGE); +} + + +/** + * Lookup a handle to find the linked image. + * Return NULL if the handle has no corresponding linked image. + */ +static INLINE _EGLImage * +_eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy) +{ + _EGLImage *img = (_EGLImage *) image; + if (!dpy || !_eglCheckResource((void *) img, _EGL_RESOURCE_IMAGE, dpy)) + img = NULL; + return img; +} + + +/** + * Return the handle of a linked image, or EGL_NO_IMAGE_KHR. + */ +static INLINE EGLImageKHR +_eglGetImageHandle(_EGLImage *img) +{ + _EGLResource *res = (_EGLResource *) img; + return (res && _eglIsResourceLinked(res)) ? + (EGLImageKHR) img : EGL_NO_IMAGE_KHR; +} + + +/** + * Return true if the image is linked to a display. + */ +static INLINE EGLBoolean +_eglIsImageLinked(_EGLImage *img) +{ + _EGLResource *res = (_EGLResource *) img; + return (res && _eglIsResourceLinked(res)); +} + + +#endif /* EGLIMAGE_INCLUDED */ diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 3a99bfea4b..03bef2670f 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -1,8 +1,10 @@ #ifndef EGLLOG_INCLUDED #define EGLLOG_INCLUDED + #include "egltypedefs.h" + #define _EGL_FATAL 0 /* unrecoverable error */ #define _EGL_WARNING 1 /* recoverable error/problem */ #define _EGL_INFO 2 /* just useful info */ diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index e66913320b..984e426686 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -33,28 +33,70 @@ #include <assert.h> #include <string.h> -#include "eglglobals.h" +#include "eglcurrent.h" #include "eglmisc.h" #include "egldisplay.h" /** + * Copy the extension into the string and update the string pointer. + */ +static EGLint +_eglAppendExtension(char **str, const char *ext) +{ + char *s = *str; + EGLint len = strlen(ext); + + if (s) { + memcpy(s, ext, len); + s[len++] = ' '; + s[len] = '\0'; + + *str += len; + } + else { + len++; + } + + return len; +} + + +/** * Examine the individual extension enable/disable flags and recompute * the driver's Extensions string. */ static void _eglUpdateExtensionsString(_EGLDisplay *dpy) { +#define _EGL_CHECK_EXTENSION(ext) \ + do { \ + if (dpy->Extensions.ext) { \ + _eglAppendExtension(&exts, "EGL_" #ext); \ + assert(exts <= dpy->Extensions.String + _EGL_MAX_EXTENSIONS_LEN); \ + } \ + } while (0) + char *exts = dpy->Extensions.String; if (exts[0]) return; - if (dpy->Extensions.MESA_screen_surface) - strcat(exts, "EGL_MESA_screen_surface "); - if (dpy->Extensions.MESA_copy_context) - strcat(exts, "EGL_MESA_copy_context "); - assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN); + _EGL_CHECK_EXTENSION(MESA_screen_surface); + _EGL_CHECK_EXTENSION(MESA_copy_context); + + _EGL_CHECK_EXTENSION(KHR_image_base); + _EGL_CHECK_EXTENSION(KHR_image_pixmap); + if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap) + _eglAppendExtension(&exts, "EGL_KHR_image"); + + _EGL_CHECK_EXTENSION(KHR_vg_parent_image); + _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image); + _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image); + _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); + _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); + +#undef _EGL_CHECK_EXTENSION } diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h index 829d4cde79..5e6a2d41df 100644 --- a/src/egl/main/eglmisc.h +++ b/src/egl/main/eglmisc.h @@ -29,7 +29,8 @@ #ifndef EGLMISC_INCLUDED #define EGLMISC_INCLUDED -#include "egldriver.h" + +#include "egltypedefs.h" extern const char * diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c index 0f3ba6e5c0..66446c0495 100644 --- a/src/egl/main/eglmode.c +++ b/src/egl/main/eglmode.c @@ -1,4 +1,3 @@ -#include <stdio.h> #include <assert.h> #include <stdlib.h> #include <string.h> @@ -6,29 +5,14 @@ #include "egldisplay.h" #include "egldriver.h" #include "eglmode.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "eglscreen.h" +#include "eglstring.h" #define MIN2(A, B) (((A) < (B)) ? (A) : (B)) -static char * -my_strdup(const char *s) -{ - if (s) { - int l = strlen(s); - char *s2 = malloc(l + 1); - if (s2) - strcpy(s2, s); - return s2; - } - else { - return NULL; - } -} - - /** * Given an EGLModeMESA handle, return the corresponding _EGLMode object * or null if non-existant. @@ -82,7 +66,7 @@ _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height, screen->Modes[n].RefreshRate = refreshRate; screen->Modes[n].Optimal = EGL_FALSE; screen->Modes[n].Interlaced = EGL_FALSE; - screen->Modes[n].Name = my_strdup(name); + screen->Modes[n].Name = _eglstrdup(name); screen->NumModes++; return screen->Modes + n; } @@ -366,41 +350,3 @@ _eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m) { return m->Name; } - - -#if 0 -static int -_eglRand(int max) -{ - return rand() % max; -} - -void -_eglTestModeModule(void) -{ - EGLint count = 30; - _EGLMode *modes = (_EGLMode *) malloc(count * sizeof(_EGLMode)); - _EGLMode **modeList = (_EGLMode **) malloc(count * sizeof(_EGLMode*)); - EGLint i; - - for (i = 0; i < count; i++) { - modes[i].Handle = _eglRand(20); - modes[i].Width = 512 + 256 * _eglRand(2); - modes[i].Height = 512 + 256 * _eglRand(2); - modes[i].RefreshRate = 50 + 5 * _eglRand(3); - modes[i].Interlaced = _eglRand(2); - modes[i].Optimal = _eglRand(4) == 0; - modeList[i] = modes + i; - } - - /* sort array of pointers */ - qsort(modeList, count, sizeof(_EGLMode *), compareModes); - - for (i = 0; i < count; i++) { - _EGLMode *m = modeList[i]; - printf("%2d: %3d %4d x %4d @ %3d opt %d int %d\n", i, - m->Handle, m->Width, m->Height, m->RefreshRate, - m->Optimal, m->Interlaced); - } -} -#endif diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 14a1e9f8fe..97a405a4b4 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -17,6 +17,7 @@ #include "egldisplay.h" #include "eglglobals.h" +#include "eglcurrent.h" #include "eglmode.h" #include "eglconfig.h" #include "eglsurface.h" @@ -110,27 +111,12 @@ _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA, - conf, attrib_list)) { - free(surf); - return NULL; - } - - return surf; -#endif return NULL; } diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index d52e5388c3..c400ac3d15 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -2,6 +2,9 @@ #define EGLSCREEN_INCLUDED +#include "egltypedefs.h" + + /** * Per-screen information. * Note that an EGL screen doesn't have a size. A screen may be set to diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index 940a1b760c..8026a6314d 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -9,8 +9,7 @@ #include "egldisplay.h" #include "eglcontext.h" #include "eglconfig.h" -#include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" #include "eglsurface.h" @@ -32,23 +31,168 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval) /** + * Parse the list of surface attributes and return the proper error code. + */ +static EGLint +_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) +{ + EGLint type = surf->Type; + 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) { + /* common (except for screen surfaces) attributes */ + case EGL_VG_COLORSPACE: + if (type == EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + 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: + if (type == EGL_SCREEN_BIT_MESA) { + err = EGL_BAD_ATTRIBUTE; + break; + } + 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; + /* pbuffer surface attributes */ + case EGL_WIDTH: + if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { + 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 && type != EGL_SCREEN_BIT_MESA) { + 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; + case EGL_TEXTURE_FORMAT: + if (type != EGL_PBUFFER_BIT) { + 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 != EGL_PBUFFER_BIT) { + 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 != EGL_PBUFFER_BIT) { + 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(_EGLDriver *drv, _EGLSurface *surf, EGLint type, +_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, _EGLConfig *conf, const EGLint *attrib_list) { const char *func; - EGLint width = 0, height = 0, largest = 0; - EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE; - EGLint mipmapTex = EGL_FALSE; EGLint renderBuffer = EGL_BACK_BUFFER; -#ifdef EGL_VERSION_1_2 - EGLint colorspace = EGL_COLORSPACE_sRGB; - EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE; -#endif - EGLint i; + EGLint err; switch (type) { case EGL_WINDOW_BIT: @@ -70,158 +214,41 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, return EGL_FALSE; } - if (!conf) { - _eglError(EGL_BAD_CONFIG, func); - return EGL_FALSE; - } - if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) { /* The config can't be used to create a surface of this type */ _eglError(EGL_BAD_CONFIG, func); return EGL_FALSE; } - /* - * Parse attribute list. Different kinds of surfaces support different - * attributes. - */ - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { - width = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_HEIGHT: - if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) { - height = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_LARGEST_PBUFFER: - if (type == EGL_PBUFFER_BIT) { - largest = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_TEXTURE_FORMAT: - if (type == EGL_PBUFFER_BIT) { - texFormat = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_TEXTURE_TARGET: - if (type == EGL_PBUFFER_BIT) { - texTarget = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_MIPMAP_TEXTURE: - if (type == EGL_PBUFFER_BIT) { - mipmapTex = attrib_list[++i]; - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; -#ifdef EGL_VERSION_1_2 - case EGL_RENDER_BUFFER: - if (type == EGL_WINDOW_BIT) { - renderBuffer = attrib_list[++i]; - if (renderBuffer != EGL_BACK_BUFFER && - renderBuffer != EGL_SINGLE_BUFFER) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_COLORSPACE: - if (type == EGL_WINDOW_BIT || - type == EGL_PBUFFER_BIT || - type == EGL_PIXMAP_BIT) { - colorspace = attrib_list[++i]; - if (colorspace != EGL_COLORSPACE_sRGB && - colorspace != EGL_COLORSPACE_LINEAR) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - case EGL_ALPHA_FORMAT: - if (type == EGL_WINDOW_BIT || - type == EGL_PBUFFER_BIT || - type == EGL_PIXMAP_BIT) { - alphaFormat = attrib_list[++i]; - if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE && - alphaFormat != EGL_ALPHA_FORMAT_PRE) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - else { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - break; - -#endif /* EGL_VERSION_1_2 */ - default: - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - } - - if (width < 0 || height < 0) { - _eglError(EGL_BAD_ATTRIBUTE, func); - return EGL_FALSE; - } - memset(surf, 0, sizeof(_EGLSurface)); - surf->Config = conf; + surf->Resource.Display = dpy; surf->Type = type; - surf->Width = width; - surf->Height = height; - surf->TextureFormat = texFormat; - surf->TextureTarget = texTarget; - surf->MipmapTexture = mipmapTex; + 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 = EGL_BUFFER_DESTROYED; + + surf->HorizontalResolution = EGL_UNKNOWN; + surf->VerticalResolution = EGL_UNKNOWN; + surf->AspectRatio = EGL_UNKNOWN; + /* the default swap interval is 1 */ _eglClampSwapInterval(surf, 1); -#ifdef EGL_VERSION_1_2 - surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */ - surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */ - surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */ - surf->AspectRatio = EGL_UNKNOWN; /* set by caller */ - surf->RenderBuffer = renderBuffer; - surf->AlphaFormat = alphaFormat; - surf->Colorspace = colorspace; -#endif + err = _eglParseSurfaceAttribList(surf, attrib_list); + if (err != EGL_SUCCESS) + return _eglError(err, func); return EGL_TRUE; } @@ -237,7 +264,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) EGLBoolean _eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, - NativePixmapType target) + EGLNativePixmapType target) { /* copy surface to native pixmap */ /* All implementation burdon for this is in the device driver */ @@ -252,139 +279,95 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, switch (attribute) { case EGL_WIDTH: *value = surface->Width; - return EGL_TRUE; + break; case EGL_HEIGHT: *value = surface->Height; - return EGL_TRUE; + break; case EGL_CONFIG_ID: *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID); - return EGL_TRUE; + break; case EGL_LARGEST_PBUFFER: - *value = dpy->LargestPbuffer; - return EGL_TRUE; - case EGL_SURFACE_TYPE: - *value = surface->Type; - return EGL_TRUE; -#ifdef EGL_VERSION_1_1 + *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; - return EGL_TRUE; + break; case EGL_TEXTURE_TARGET: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->TextureTarget; - return EGL_TRUE; + break; case EGL_MIPMAP_TEXTURE: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->MipmapTexture; - return EGL_TRUE; + break; case EGL_MIPMAP_LEVEL: if (surface->Type == EGL_PBUFFER_BIT) *value = surface->MipmapLevel; - return EGL_TRUE; -#endif /* EGL_VERSION_1_1 */ -#ifdef EGL_VERSION_1_2 + break; case EGL_SWAP_BEHAVIOR: *value = surface->SwapBehavior; - return EGL_TRUE; + break; case EGL_RENDER_BUFFER: *value = surface->RenderBuffer; - return EGL_TRUE; + break; case EGL_PIXEL_ASPECT_RATIO: *value = surface->AspectRatio; - return EGL_TRUE; + break; case EGL_HORIZONTAL_RESOLUTION: *value = surface->HorizontalResolution; - return EGL_TRUE; + break; case EGL_VERTICAL_RESOLUTION: *value = surface->VerticalResolution; - return EGL_TRUE; - case EGL_ALPHA_FORMAT: - *value = surface->AlphaFormat; - return EGL_TRUE; - case EGL_COLORSPACE: - *value = surface->Colorspace; - return EGL_TRUE; -#endif /* EGL_VERSION_1_2 */ + 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; default: _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface"); return EGL_FALSE; } + + return EGL_TRUE; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return surf; -#endif return NULL; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) + EGLNativePixmapType pixmap, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return surf; -#endif return NULL; } /** - * Example function - drivers should do a proper implementation. + * Drivers should do a proper implementation. */ _EGLSurface * _eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list) { -#if 0 /* THIS IS JUST EXAMPLE CODE */ - _EGLSurface *surf; - - surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) { - free(surf); - return NULL; - } - - return NULL; -#endif return NULL; } @@ -408,14 +391,59 @@ EGLBoolean _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value) { + EGLint confval; + EGLint err = EGL_SUCCESS; + switch (attribute) { case EGL_MIPMAP_LEVEL: + confval = GET_CONFIG_ATTRIB(surface->Config, EGL_RENDERABLE_TYPE); + if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) { + 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 = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE); + 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 = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE); + 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: - _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib"); - return EGL_FALSE; + err = EGL_BAD_ATTRIBUTE; + break; } + + if (err != EGL_SUCCESS) + return _eglError(err, "eglSurfaceAttrib"); return EGL_TRUE; } diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index dacdf7e63c..0a00035730 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -3,6 +3,7 @@ #include "egltypedefs.h" +#include "egldisplay.h" /** @@ -10,38 +11,43 @@ */ struct _egl_surface { - /* Managed by EGLDisplay for linking */ - _EGLDisplay *Display; - _EGLSurface *Next; + /* A surface is a display resource */ + _EGLResource Resource; - /* The bound status of the surface */ - _EGLContext *Binding; - EGLBoolean BoundToTexture; + /* 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 */ - EGLint Width, Height; - EGLint TextureFormat, TextureTarget; - EGLint MipmapTexture, MipmapLevel; - EGLint SwapInterval; - /* If type == EGL_SCREEN_BIT: */ - EGLint VisibleRefCount; /* number of screens I'm displayed on */ + /* 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; -#ifdef EGL_VERSION_1_2 - EGLint SwapBehavior; /* one of EGL_BUFFER_PRESERVED/DESTROYED */ EGLint HorizontalResolution, VerticalResolution; EGLint AspectRatio; - EGLint RenderBuffer; /* EGL_BACK_BUFFER or EGL_SINGLE_BUFFER */ - EGLint AlphaFormat; /* EGL_ALPHA_FORMAT_NONPRE or EGL_ALPHA_FORMAT_PRE */ - EGLint Colorspace; /* EGL_COLORSPACE_sRGB or EGL_COLORSPACE_LINEAR */ -#endif /* EGL_VERSION_1_2 */ + + EGLint SwapInterval; + + /* True if the surface is bound to an OpenGL ES texture */ + EGLBoolean BoundToTexture; }; PUBLIC EGLBoolean -_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, +_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, _EGLConfig *config, const EGLint *attrib_list); @@ -50,7 +56,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf); extern EGLBoolean -_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target); +_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLNativePixmapType target); extern EGLBoolean @@ -58,11 +64,11 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint at extern _EGLSurface * -_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list); +_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list); extern _EGLSurface * -_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); +_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLNativePixmapType pixmap, const EGLint *attrib_list); extern _EGLSurface * @@ -100,14 +106,78 @@ _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy, /** - * Return true if the surface is bound to a thread. - * A surface bound to a texutre is not considered bound by - * this function. + * Return true if there is a context bound to the surface. + * + * The binding is considered a reference to the surface. Drivers should not + * destroy a surface when it is bound. */ static INLINE EGLBoolean _eglIsSurfaceBound(_EGLSurface *surf) { - return (surf->Binding != NULL); + return (surf->CurrentContext != NULL); +} + + +/** + * Link a surface to a display and return the handle of the link. + * The handle can be passed to client directly. + */ +static INLINE EGLSurface +_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) +{ + _eglLinkResource(&surf->Resource, _EGL_RESOURCE_SURFACE, dpy); + 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; +} + + +/** + * Return true if the surface is linked to a display. + * + * The link is considered a reference to the surface (the display is owning the + * surface). Drivers should not destroy a surface when it is linked. + */ +static INLINE EGLBoolean +_eglIsSurfaceLinked(_EGLSurface *surf) +{ + _EGLResource *res = (_EGLResource *) surf; + return (res && _eglIsResourceLinked(res)); } diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 4461440b9b..e0c95762c6 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -8,6 +8,8 @@ #include "eglcompiler.h" +typedef enum _egl_resource_type _EGLResourceType; + typedef struct _egl_api _EGLAPI; typedef struct _egl_config _EGLConfig; @@ -20,16 +22,16 @@ typedef struct _egl_driver _EGLDriver; typedef struct _egl_extensions _EGLExtensions; +typedef struct _egl_image _EGLImage; + typedef struct _egl_mode _EGLMode; +typedef struct _egl_resource _EGLResource; + typedef struct _egl_screen _EGLScreen; typedef struct _egl_surface _EGLSurface; typedef struct _egl_thread_info _EGLThreadInfo; - -typedef _EGLDriver *(*_EGLMain_t)(const char *args); - - #endif /* EGLTYPEDEFS_INCLUDED */ diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 136423513c..5d9d2db786 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -53,13 +53,16 @@ install: ##### RULES ##### -.c.o: +%.s: %.c + $(CC) -S $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@ + +%.o: %.c $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@ -.cpp.o: +%.o: %.cpp $(CXX) -c $(INCLUDES) $(DEFINES) $(CXXFLAGS) $(LIBRARY_DEFINES) $< -o $@ -.S.o: +%.o: %.S $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@ diff --git a/src/gallium/SConscript b/src/gallium/SConscript index eea32b1314..d56c5c8461 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -8,9 +8,10 @@ for driver in env['drivers']: SConscript(os.path.join('drivers', driver, 'SConscript')) SConscript('state_trackers/python/SConscript') -SConscript('state_trackers/glx/xlib/SConscript') -SConscript('state_trackers/dri/SConscript') -SConscript('state_trackers/xorg/SConscript') +if platform != 'embedded': + SConscript('state_trackers/glx/xlib/SConscript') + SConscript('state_trackers/dri/SConscript') + SConscript('state_trackers/xorg/SConscript') if platform == 'windows': SConscript('state_trackers/wgl/SConscript') diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index e3af41c6e0..02c65a9b2d 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -48,12 +48,14 @@ C_SOURCES = \ draw/draw_vs_sse.c \ indices/u_indices_gen.c \ indices/u_unfilled_gen.c \ - pipebuffer/pb_buffer_fenced.c \ + os/os_misc.c \ + os/os_stream_stdc.c \ + os/os_stream_wd.c \ + os/os_time.c \ pipebuffer/pb_buffer_malloc.c \ pipebuffer/pb_bufmgr_alt.c \ pipebuffer/pb_bufmgr_cache.c \ pipebuffer/pb_bufmgr_debug.c \ - pipebuffer/pb_bufmgr_fenced.c \ pipebuffer/pb_bufmgr_mm.c \ pipebuffer/pb_bufmgr_ondemand.c \ pipebuffer/pb_bufmgr_pool.c \ @@ -92,6 +94,7 @@ C_SOURCES = \ util/u_debug_dump.c \ util/u_debug_symbol.c \ util/u_debug_stack.c \ + util/u_bitmask.c \ util/u_blit.c \ util/u_blitter.c \ util/u_cache.c \ @@ -111,14 +114,12 @@ C_SOURCES = \ util/u_math.c \ util/u_mm.c \ util/u_rect.c \ + util/u_ringbuffer.c \ util/u_simple_shaders.c \ util/u_snprintf.c \ - util/u_stream_stdc.c \ - util/u_stream_wd.c \ util/u_surface.c \ util/u_texture.c \ util/u_tile.c \ - util/u_time.c \ util/u_timed_winsys.c \ util/u_upload_mgr.c \ util/u_simple_screen.c \ @@ -129,39 +130,43 @@ C_SOURCES = \ vl/vl_shader_build.c GALLIVM_SOURCES = \ - gallivm/gallivm.cpp \ - gallivm/gallivm_cpu.cpp \ - gallivm/instructions.cpp \ - gallivm/loweringpass.cpp \ - gallivm/tgsitollvm.cpp \ - gallivm/storage.cpp \ - gallivm/storagesoa.cpp \ - gallivm/instructionssoa.cpp + gallivm/lp_bld_alpha.c \ + gallivm/lp_bld_arit.c \ + gallivm/lp_bld_blend_aos.c \ + gallivm/lp_bld_blend_logicop.c \ + gallivm/lp_bld_blend_soa.c \ + gallivm/lp_bld_const.c \ + gallivm/lp_bld_conv.c \ + gallivm/lp_bld_debug.c \ + gallivm/lp_bld_depth.c \ + gallivm/lp_bld_flow.c \ + gallivm/lp_bld_format_aos.c \ + gallivm/lp_bld_format_query.c \ + gallivm/lp_bld_format_soa.c \ + gallivm/lp_bld_interp.c \ + gallivm/lp_bld_intr.c \ + gallivm/lp_bld_logic.c \ + gallivm/lp_bld_pack.c \ + gallivm/lp_bld_sample.c \ + gallivm/lp_bld_sample_soa.c \ + gallivm/lp_bld_struct.c \ + gallivm/lp_bld_swizzle.c \ + gallivm/lp_bld_tgsi_soa.c \ + gallivm/lp_bld_type.c -INC_SOURCES = \ - gallivm/gallivm_builtins.cpp \ - gallivm/gallivmsoabuiltins.cpp +GALLIVM_CPP_SOURCES = \ + gallivm/lp_bld_misc.cpp -# XXX: gallivm doesn't build correctly so disable for now -#ifeq ($(MESA_LLVM),1) -#DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -#CPP_SOURCES += \ -# $(GALLIVM_SOURCES) -#endif - -include ../Makefile.template +ifeq ($(MESA_LLVM),1) +C_SOURCES += \ + $(GALLIVM_SOURCES) +CPP_SOURCES += \ + $(GALLIVM_CPP_SOURCES) +endif -gallivm/gallivm_builtins.cpp: gallivm/llvm_builtins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin - (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@ - rm temp1.bin - -gallivm/gallivmsoabuiltins.cpp: gallivm/soabuiltins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin - (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@ - rm temp2.bin +include ../Makefile.template indices/u_indices_gen.c: indices/u_indices_gen.py diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 782eb53386..9709344b54 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -82,12 +82,15 @@ source = [ #'indices/u_unfilled_indices.c', 'indices/u_indices_gen.c', 'indices/u_unfilled_gen.c', + 'os/os_misc.c', + 'os/os_stream_stdc.c', + 'os/os_stream_wd.c', + 'os/os_time.c', 'pipebuffer/pb_buffer_fenced.c', 'pipebuffer/pb_buffer_malloc.c', 'pipebuffer/pb_bufmgr_alt.c', 'pipebuffer/pb_bufmgr_cache.c', 'pipebuffer/pb_bufmgr_debug.c', - 'pipebuffer/pb_bufmgr_fenced.c', 'pipebuffer/pb_bufmgr_mm.c', 'pipebuffer/pb_bufmgr_ondemand.c', 'pipebuffer/pb_bufmgr_pool.c', @@ -106,7 +109,6 @@ source = [ 'rtasm/rtasm_ppc_spe.c', 'tgsi/tgsi_build.c', 'tgsi/tgsi_dump.c', - 'tgsi/tgsi_dump_c.c', 'tgsi/tgsi_exec.c', 'tgsi/tgsi_info.c', 'tgsi/tgsi_iterate.c', @@ -147,14 +149,12 @@ source = [ 'util/u_math.c', 'util/u_mm.c', 'util/u_rect.c', + 'util/u_ringbuffer.c', 'util/u_simple_shaders.c', 'util/u_snprintf.c', - 'util/u_stream_stdc.c', - 'util/u_stream_wd.c', 'util/u_surface.c', 'util/u_texture.c', 'util/u_tile.c', - 'util/u_time.c', 'util/u_timed_winsys.c', 'util/u_upload_mgr.c', 'util/u_simple_screen.c', @@ -165,16 +165,32 @@ source = [ 'vl/vl_shader_build.c', ] -if env['llvm']: +if drawllvm: source += [ - 'gallivm/gallivm.cpp', - 'gallivm/gallivm_cpu.cpp', - 'gallivm/instructions.cpp', - 'gallivm/loweringpass.cpp', - 'gallivm/tgsitollvm.cpp', - 'gallivm/storage.cpp', - 'gallivm/storagesoa.cpp', - 'gallivm/instructionssoa.cpp', + 'gallivm/lp_bld_alpha.c', + 'gallivm/lp_bld_arit.c', + 'gallivm/lp_bld_blend_aos.c', + 'gallivm/lp_bld_blend_logicop.c', + 'gallivm/lp_bld_blend_soa.c', + 'gallivm/lp_bld_const.c', + 'gallivm/lp_bld_conv.c', + 'gallivm/lp_bld_debug.c', + 'gallivm/lp_bld_depth.c', + 'gallivm/lp_bld_flow.c', + 'gallivm/lp_bld_format_aos.c', + 'gallivm/lp_bld_format_query.c', + 'gallivm/lp_bld_format_soa.c', + 'gallivm/lp_bld_interp.c', + 'gallivm/lp_bld_intr.c', + 'gallivm/lp_bld_logic.c', + 'gallivm/lp_bld_misc.cpp', + 'gallivm/lp_bld_pack.c', + 'gallivm/lp_bld_sample.c', + 'gallivm/lp_bld_sample_soa.c', + 'gallivm/lp_bld_struct.c', + 'gallivm/lp_bld_swizzle.c', + 'gallivm/lp_bld_tgsi_soa.c', + 'gallivm/lp_bld_type.c', ] gallium = env.ConvenienceLibrary( diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index e6dce3f0e5..a6a07e72c2 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -113,26 +113,6 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_ return hash; } -static int _cso_size_for_type(enum cso_cache_type type) -{ - switch(type) { - case CSO_BLEND: - return sizeof(struct pipe_blend_state); - case CSO_SAMPLER: - return sizeof(struct pipe_sampler_state); - case CSO_DEPTH_STENCIL_ALPHA: - return sizeof(struct pipe_depth_stencil_alpha_state); - case CSO_RASTERIZER: - return sizeof(struct pipe_rasterizer_state); - case CSO_FRAGMENT_SHADER: - return sizeof(struct pipe_shader_state); - case CSO_VERTEX_SHADER: - return sizeof(struct pipe_shader_state); - } - return 0; -} - - static void delete_blend_state(void *state, void *data) { struct cso_blend *cso = (struct cso_blend *)state; @@ -282,10 +262,9 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash, struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, - void *templ) + void *templ, unsigned size) { struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); - int size = _cso_size_for_type(type); while (!cso_hash_iter_is_null(iter)) { void *iter_data = cso_hash_iter_data(iter); if (!memcmp(iter_data, templ, size)) diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 6b5c230e8f..eea60b940b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -160,7 +160,7 @@ struct cso_hash_iter cso_find_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type); struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, - void *templ); + void *templ, unsigned size); void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, cso_state_callback func, void *user_data); void * cso_take_state(struct cso_cache *sc, unsigned hash_key, diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 2b16332e14..c638239e80 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -36,6 +36,7 @@ */ #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "tgsi/tgsi_parse.h" @@ -310,18 +311,21 @@ void cso_destroy_context( struct cso_context *ctx ) enum pipe_error cso_set_blend(struct cso_context *ctx, const struct pipe_blend_state *templ) { - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_BLEND, - (void*)templ); + unsigned key_size, hash_key; + struct cso_hash_iter iter; void *handle; + key_size = templ->independent_blend_enable ? sizeof(struct pipe_blend_state) : + (char *)&(templ->rt[1]) - (char *)templ; + hash_key = cso_construct_key((void*)templ, key_size); + iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND, (void*)templ, key_size); + if (cso_hash_iter_is_null(iter)) { struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - memcpy(&cso->state, templ, sizeof(*templ)); + memcpy(&cso->state, templ, key_size); cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; cso->context = ctx->pipe; @@ -369,10 +373,11 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, void *handle = NULL; if (templ != NULL) { - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); + unsigned key_size = sizeof(struct pipe_sampler_state); + unsigned hash_key = cso_construct_key((void*)templ, key_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, CSO_SAMPLER, - (void*)templ); + (void*)templ, key_size); if (cso_hash_iter_is_null(iter)) { struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); @@ -409,10 +414,11 @@ cso_single_vertex_sampler(struct cso_context *ctx, void *handle = NULL; if (templ != NULL) { - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); + unsigned key_size = sizeof(struct pipe_sampler_state); + unsigned hash_key = cso_construct_key((void*)templ, key_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, CSO_SAMPLER, - (void*)templ); + (void*)templ, key_size); if (cso_hash_iter_is_null(iter)) { struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); @@ -539,6 +545,38 @@ void cso_restore_samplers(struct cso_context *ctx) cso_single_sampler_done( ctx ); } +/* + * If the function encouters any errors it will return the + * last one. Done to always try to set as many samplers + * as possible. + */ +enum pipe_error cso_set_vertex_samplers(struct cso_context *ctx, + unsigned nr, + const struct pipe_sampler_state **templates) +{ + unsigned i; + enum pipe_error temp, error = PIPE_OK; + + /* TODO: fastpath + */ + + for (i = 0; i < nr; i++) { + temp = cso_single_vertex_sampler( ctx, i, templates[i] ); + if (temp != PIPE_OK) + error = temp; + } + + for ( ; i < ctx->nr_samplers; i++) { + temp = cso_single_vertex_sampler( ctx, i, NULL ); + if (temp != PIPE_OK) + error = temp; + } + + cso_single_vertex_sampler_done( ctx ); + + return error; +} + void cso_save_vertex_samplers(struct cso_context *ctx) { @@ -666,12 +704,12 @@ cso_restore_vertex_sampler_textures(struct cso_context *ctx) enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_depth_stencil_alpha_state)); + unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state); + unsigned hash_key = cso_construct_key((void*)templ, key_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, - CSO_DEPTH_STENCIL_ALPHA, - (void*)templ); + CSO_DEPTH_STENCIL_ALPHA, + (void*)templ, key_size); void *handle; if (cso_hash_iter_is_null(iter)) { @@ -723,11 +761,11 @@ void cso_restore_depth_stencil_alpha(struct cso_context *ctx) enum pipe_error cso_set_rasterizer(struct cso_context *ctx, const struct pipe_rasterizer_state *templ) { - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_rasterizer_state)); + unsigned key_size = sizeof(struct pipe_rasterizer_state); + unsigned hash_key = cso_construct_key((void*)templ, key_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, CSO_RASTERIZER, - (void*)templ); + (void*)templ, key_size); void *handle = NULL; if (cso_hash_iter_is_null(iter)) { @@ -809,7 +847,8 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, - (void*)tokens); + (void*)tokens, + sizeof(*templ)); /* XXX correct? tokens_size? */ void *handle = NULL; if (cso_hash_iter_is_null(iter)) { @@ -888,7 +927,8 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, sizeof(struct pipe_shader_state)); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, hash_key, CSO_VERTEX_SHADER, - (void*)templ); + (void*)templ, + sizeof(*templ)); void *handle = NULL; if (cso_hash_iter_is_null(iter)) { diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index b9e313e32d..d2089b1c88 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -84,6 +84,10 @@ enum pipe_error cso_single_sampler( struct cso_context *cso, void cso_single_sampler_done( struct cso_context *cso ); +enum pipe_error cso_set_vertex_samplers(struct cso_context *cso, + unsigned count, + const struct pipe_sampler_state **states); + void cso_save_vertex_samplers(struct cso_context *cso); diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 667aa46b20..d5ddc4a6a9 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -34,11 +34,8 @@ #include "util/u_memory.h" #include "util/u_math.h" #include "draw_context.h" -#include "draw_vbuf.h" #include "draw_vs.h" #include "draw_gs.h" -#include "draw_pt.h" -#include "draw_pipe.h" struct draw_context *draw_create( void ) @@ -95,6 +92,7 @@ void draw_destroy( struct draw_context *draw ) draw_pipeline_destroy( draw ); draw_pt_destroy( draw ); draw_vs_destroy( draw ); + draw_gs_destroy( draw ); FREE( draw ); } @@ -236,17 +234,20 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, unsigned shader_type, + unsigned slot, const void *buffer, unsigned size ) { debug_assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_GEOMETRY); + debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); + if (shader_type == PIPE_SHADER_VERTEX) { - draw->pt.user.vs_constants = buffer; - draw_vs_set_constants( draw, (const float (*)[4])buffer, size ); + draw->pt.user.vs_constants[slot] = buffer; + draw_vs_set_constants(draw, slot, buffer, size); } else if (shader_type == PIPE_SHADER_GEOMETRY) { - draw->pt.user.gs_constants = buffer; - draw_gs_set_constants( draw, (const float (*)[4])buffer, size ); + draw->pt.user.gs_constants[slot] = buffer; + draw_gs_set_constants(draw, slot, buffer, size); } } @@ -351,7 +352,10 @@ draw_find_shader_output(const struct draw_context *draw, /** - * Return number of the shader outputs. + * Return total number of the shader outputs. This function is similar to + * draw_current_shader_outputs() but this function also counts any extra + * vertex/geometry output attributes that may be filled in by some draw + * stages (such as AA point, AA line). * * If geometry shader is present, its output will be returned, * if not vertex shader is used. @@ -361,8 +365,9 @@ draw_num_shader_outputs(const struct draw_context *draw) { uint count = draw->vs.vertex_shader->info.num_outputs; - /* if geometry shader is present, its outputs go to te - * driver, not the vertex shaders */ + /* If a geometry shader is present, its outputs go to the + * driver, else the vertex shader's outputs. + */ if (draw->gs.geometry_shader) count = draw->gs.geometry_shader->info.num_outputs; @@ -373,7 +378,8 @@ draw_num_shader_outputs(const struct draw_context *draw) /** - * Provide TGSI sampler objects for vertex/geometry shaders that use texture fetches. + * Provide TGSI sampler objects for vertex/geometry shaders that use + * texture fetches. * This might only be used by software drivers for the time being. */ void @@ -453,14 +459,27 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) } -int draw_current_shader_outputs(struct draw_context *draw) +/** + * Return the number of output attributes produced by the geometry + * shader, if present. If no geometry shader, return the number of + * outputs from the vertex shader. + * \sa draw_num_shader_outputs + */ +uint +draw_current_shader_outputs(const struct draw_context *draw) { if (draw->gs.geometry_shader) return draw->gs.num_gs_outputs; return draw->vs.num_vs_outputs; } -int draw_current_shader_position_output(struct draw_context *draw) + +/** + * Return the index of the shader output which will contain the + * vertex position. + */ +uint +draw_current_shader_position_output(const struct draw_context *draw) { if (draw->gs.geometry_shader) return draw->gs.position_output; diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index b716209df2..acd81b9712 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -151,10 +151,12 @@ void draw_set_mapped_element_buffer( struct draw_context *draw, void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer); -void draw_set_mapped_constant_buffer(struct draw_context *draw, - unsigned shader_type, - const void *buffer, - unsigned size ); +void +draw_set_mapped_constant_buffer(struct draw_context *draw, + unsigned shader_type, + unsigned slot, + const void *buffer, + unsigned size); /*********************************************************************** @@ -164,6 +166,14 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, void draw_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count); +void +draw_arrays_instanced(struct draw_context *draw, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + void draw_flush(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 5db2e75542..7069aa6b18 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -59,10 +59,21 @@ draw_gs_init( struct draw_context *draw ) return TRUE; } +void draw_gs_destroy( struct draw_context *draw ) +{ + if (!draw->gs.machine) + return; + + align_free(draw->gs.machine->Primitives); -void draw_gs_set_constants( struct draw_context *draw, - const float (*constants)[4], - unsigned size ) + tgsi_exec_machine_destroy(draw->gs.machine); +} + +void +draw_gs_set_constants(struct draw_context *draw, + unsigned slot, + const void *constants, + unsigned size) { } @@ -282,7 +293,7 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader, void draw_geometry_shader_run(struct draw_geometry_shader *shader, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned vertex_size) @@ -293,7 +304,9 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader, unsigned num_primitives = count/num_vertices; unsigned inputs_from_vs = 0; - machine->Consts = constants; + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->Consts[i] = constants[i]; + } for (i = 0; i < shader->info.num_inputs; ++i) { if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID) diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index d6a97d9c4e..d8eb210343 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -62,7 +62,7 @@ struct draw_geometry_shader { void draw_geometry_shader_run(struct draw_geometry_shader *shader, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride); diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 1c6d657297..83dc1a35f4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -32,6 +32,7 @@ #include "draw/draw_private.h" #include "draw/draw_pipe.h" +#include "util/u_debug.h" @@ -106,10 +107,9 @@ void draw_pipeline_destroy( struct draw_context *draw ) - - - - +/** + * Build primitive to render a point with vertex at v0. + */ static void do_point( struct draw_context *draw, const char *v0 ) { @@ -123,6 +123,10 @@ static void do_point( struct draw_context *draw, } +/** + * Build primitive to render a line with vertices at v0, v1. + * \param flags bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE + */ static void do_line( struct draw_context *draw, ushort flags, const char *v0, @@ -139,6 +143,10 @@ static void do_line( struct draw_context *draw, } +/** + * Build primitive to render a triangle with vertices at v0, v1, v2. + * \param flags bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE + */ static void do_triangle( struct draw_context *draw, ushort flags, char *v0, @@ -157,7 +165,10 @@ static void do_triangle( struct draw_context *draw, } - +/* + * Set up macros for draw_pt_decompose.h template code. + * This code uses vertex indexes / elements. + */ #define QUAD(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ @@ -175,16 +186,16 @@ static void do_triangle( struct draw_context *draw, #define TRIANGLE(flags,i0,i1,i2) \ do_triangle( draw, \ - elts[i0], /* flags */ \ + elts[i0], /* flags */ \ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * elts[i1], \ - verts + stride * elts[i2]) + verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) ); #define LINE(flags,i0,i1) \ do_line( draw, \ - elts[i0], \ + elts[i0], \ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * elts[i1]) + verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) ); #define POINT(i0) \ do_point( draw, \ @@ -213,7 +224,9 @@ static void do_triangle( struct draw_context *draw, -/* Code to run the pipeline on a fairly arbitary collection of vertices. +/** + * Code to run the pipeline on a fairly arbitary collection of vertices. + * For drawing indexed primitives. * * Vertex headers must be pre-initialized with the * UNDEFINED_VERTEX_ID, this code will cause that id to become @@ -243,6 +256,12 @@ void draw_pipeline_run( struct draw_context *draw, draw->pipeline.vertex_count = 0; } + + +/* + * Set up macros for draw_pt_decompose.h template code. + * This code is for non-indexed rendering (no elts). + */ #define QUAD(i0,i1,i2,i3) \ do_triangle( draw, \ ( DRAW_PIPE_RESET_STIPPLE | \ @@ -293,6 +312,10 @@ void draw_pipeline_run( struct draw_context *draw, #include "draw_pt_decompose.h" + +/* + * For drawing non-indexed primitives. + */ void draw_pipeline_run_linear( struct draw_context *draw, unsigned prim, struct vertex_header *vertices, diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 4585dcdb48..8f6ca15dfa 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" @@ -48,6 +49,10 @@ #include "draw_pipe.h" +/** Approx number of new tokens for instructions in aa_transform_inst() */ +#define NUM_NEW_TOKENS 50 + + /** * Max texture level for the alpha texture used for antialiasing */ @@ -178,12 +183,7 @@ aa_transform_decl(struct tgsi_transform_context *ctx, static int free_bit(uint bitfield) { - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; + return ffs(~bitfield) - 1; } @@ -342,11 +342,10 @@ generate_aaline_fs(struct aaline_stage *aaline) const struct pipe_shader_state *orig_fs = &aaline->fs->state; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; - -#define MAX 1000 + const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS; aaline_fs = *orig_fs; /* copy to init */ - aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + aaline_fs.tokens = tgsi_alloc_tokens(newLen); if (aaline_fs.tokens == NULL) return FALSE; @@ -362,7 +361,7 @@ generate_aaline_fs(struct aaline_stage *aaline) tgsi_transform_shader(orig_fs->tokens, (struct tgsi_token *) aaline_fs.tokens, - MAX, &transform.base); + newLen, &transform.base); #if 0 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index d86717e518..97f3480879 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -53,6 +53,10 @@ #include "draw_pipe.h" +/** Approx number of new tokens for instructions in aa_transform_inst() */ +#define NUM_NEW_TOKENS 200 + + /* * Enabling NORMALIZE might give _slightly_ better results. * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or @@ -81,16 +85,19 @@ struct aapoint_stage { struct draw_stage stage; - int psize_slot; + /** half of pipe_rasterizer_state::point_size */ float radius; + /** vertex attrib slot containing point size */ + int psize_slot; + /** this is the vertex attrib slot for the new texcoords */ uint tex_slot; + + /** vertex attrib slot containing position */ uint pos_slot; - /* - * Currently bound state - */ + /** Currently bound fragment shader */ struct aapoint_fragment_shader *fs; /* @@ -491,11 +498,10 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) const struct pipe_shader_state *orig_fs = &aapoint->fs->state; struct pipe_shader_state aapoint_fs; struct aa_transform_context transform; - -#define MAX 1000 + const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS; aapoint_fs = *orig_fs; /* copy to init */ - aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + aapoint_fs.tokens = tgsi_alloc_tokens(newLen); if (aapoint_fs.tokens == NULL) return FALSE; @@ -511,7 +517,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) tgsi_transform_shader(orig_fs->tokens, (struct tgsi_token *) aapoint_fs.tokens, - MAX, &transform.base); + newLen, &transform.base); #if 0 /* DEBUG */ printf("draw_aapoint, orig shader:\n"); @@ -575,8 +581,8 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) const struct aapoint_stage *aapoint = aapoint_stage(stage); struct prim_header tri; struct vertex_header *v[4]; - uint texPos = aapoint->tex_slot; - uint pos_slot = aapoint->pos_slot; + const uint tex_slot = aapoint->tex_slot; + const uint pos_slot = aapoint->pos_slot; float radius, *pos, *tex; uint i; float k; @@ -643,16 +649,16 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) pos[1] += radius; /* new texcoords */ - tex = v[0]->data[texPos]; + tex = v[0]->data[tex_slot]; ASSIGN_4V(tex, -1, -1, k, 1); - tex = v[1]->data[texPos]; + tex = v[1]->data[tex_slot]; ASSIGN_4V(tex, 1, -1, k, 1); - tex = v[2]->data[texPos]; + tex = v[2]->data[tex_slot]; ASSIGN_4V(tex, 1, 1, k, 1); - tex = v[3]->data[texPos]; + tex = v[3]->data[tex_slot]; ASSIGN_4V(tex, -1, 1, k, 1); /* emit 2 tris for the quad strip */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 205cda5eab..51a6115ebf 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -55,7 +55,7 @@ -struct clipper { +struct clip_stage { struct draw_stage stage; /**< base class */ /* Basically duplicate some of the flatshading logic here: @@ -70,9 +70,9 @@ struct clipper { /* This is a bit confusing: */ -static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) +static INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) { - return (struct clipper *)stage; + return (struct clip_stage *)stage; } @@ -92,11 +92,12 @@ static void interp_attr( float *fdst, fdst[3] = LINTERP( t, fout[3], fin[3] ); } + static void copy_colors( struct draw_stage *stage, struct vertex_header *dst, const struct vertex_header *src ) { - const struct clipper *clipper = clipper_stage(stage); + const struct clip_stage *clipper = clip_stage(stage); uint i; for (i = 0; i < clipper->num_color_attribs; i++) { const uint attr = clipper->color_attribs[i]; @@ -108,7 +109,7 @@ static void copy_colors( struct draw_stage *stage, /* Interpolate between two vertices to produce a third. */ -static void interp( const struct clipper *clip, +static void interp( const struct clip_stage *clip, struct vertex_header *dst, float t, const struct vertex_header *out, @@ -179,7 +180,7 @@ static void emit_poly( struct draw_stage *stage, header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ if (i == n-1) - header.flags |= edge_last; + header.flags |= edge_last; if (0) { const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; @@ -200,13 +201,14 @@ static void emit_poly( struct draw_stage *stage, } } + static INLINE float dot4(const float *a, const float *b) { - return (a[0]*b[0] + - a[1]*b[1] + - a[2]*b[2] + - a[3]*b[3]); + return (a[0] * b[0] + + a[1] * b[1] + + a[2] * b[2] + + a[3] * b[3]); } @@ -217,7 +219,7 @@ do_clip_tri( struct draw_stage *stage, struct prim_header *header, unsigned clipmask ) { - struct clipper *clipper = clipper_stage( stage ); + struct clip_stage *clipper = clip_stage( stage ); struct vertex_header *a[MAX_CLIPPED_VERTICES]; struct vertex_header *b[MAX_CLIPPED_VERTICES]; struct vertex_header **inlist = a; @@ -280,6 +282,7 @@ do_clip_tri( struct draw_stage *stage, dp_prev = dp; } + /* swap in/out lists */ { struct vertex_header **tmp = inlist; inlist = outlist; @@ -291,15 +294,11 @@ do_clip_tri( struct draw_stage *stage, /* If flat-shading, copy color to new provoking vertex. */ if (clipper->flat && inlist[0] != header->v[2]) { - if (1) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - } + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); copy_colors(stage, inlist[0], header->v[2]); } - - /* Emit the polygon as triangles to the setup stage: */ if (n >= 3) @@ -314,7 +313,7 @@ do_clip_line( struct draw_stage *stage, struct prim_header *header, unsigned clipmask ) { - const struct clipper *clipper = clipper_stage( stage ); + const struct clip_stage *clipper = clip_stage( stage ); struct vertex_header *v0 = header->v[0]; struct vertex_header *v1 = header->v[1]; const float *pos0 = v0->clip; @@ -416,13 +415,14 @@ clip_tri( struct draw_stage *stage, } } + /* Update state. Could further delay this until we hit the first * primitive that really requires clipping. */ static void clip_init_state( struct draw_stage *stage ) { - struct clipper *clipper = clipper_stage( stage ); + struct clip_stage *clipper = clip_stage( stage ); clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; @@ -488,7 +488,7 @@ static void clip_destroy( struct draw_stage *stage ) */ struct draw_stage *draw_clip_stage( struct draw_context *draw ) { - struct clipper *clipper = CALLOC_STRUCT(clipper); + struct clip_stage *clipper = CALLOC_STRUCT(clip_stage); if (clipper == NULL) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 11b39db599..dc66c65a56 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -50,8 +50,6 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) } - - static void cull_tri( struct draw_stage *stage, struct prim_header *header ) { @@ -62,7 +60,7 @@ static void cull_tri( struct draw_stage *stage, const float *v1 = header->v[1]->data[pos]; const float *v2 = header->v[2]->data[pos]; - /* edge vectors e = v0 - v2, f = v1 - v2 */ + /* edge vectors: e = v0 - v2, f = v1 - v2 */ const float ex = v0[0] - v2[0]; const float ey = v0[1] - v2[1]; const float fx = v1[0] - v2[0]; @@ -72,7 +70,7 @@ static void cull_tri( struct draw_stage *stage, header->det = ex * fy - ey * fx; if (header->det != 0) { - /* if (det < 0 then Z points toward camera and triangle is + /* if det < 0 then Z points toward the camera and the triangle is * counter-clockwise winding. */ unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; @@ -84,6 +82,7 @@ static void cull_tri( struct draw_stage *stage, } } + static void cull_first_tri( struct draw_stage *stage, struct prim_header *header ) { @@ -96,13 +95,13 @@ static void cull_first_tri( struct draw_stage *stage, } - static void cull_flush( struct draw_stage *stage, unsigned flags ) { stage->tri = cull_first_tri; stage->next->flush( stage->next, flags ); } + static void cull_reset_stipple_counter( struct draw_stage *stage ) { stage->next->reset_stipple_counter( stage->next ); @@ -140,7 +139,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) return &cull->stage; - fail: +fail: if (cull) cull->stage.destroy( &cull->stage ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 0cc2b71864..d0d99aa331 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -37,6 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" @@ -49,6 +50,9 @@ #include "draw_pipe.h" +/** Approx number of new tokens for instructions in pstip_transform_inst() */ +#define NUM_NEW_TOKENS 50 + /** * Subclass of pipe_shader_state to carry extra fragment shader info. @@ -171,12 +175,7 @@ pstip_transform_immed(struct tgsi_transform_context *ctx, static int free_bit(uint bitfield) { - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; + return ffs(~bitfield) - 1; } @@ -332,11 +331,10 @@ generate_pstip_fs(struct pstip_stage *pstip) /*struct draw_context *draw = pstip->stage.draw;*/ struct pipe_shader_state pstip_fs; struct pstip_transform_context transform; - -#define MAX 1000 + const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS; pstip_fs = *orig_fs; /* copy to init */ - pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + pstip_fs.tokens = tgsi_alloc_tokens(newLen); if (pstip_fs.tokens == NULL) return FALSE; @@ -351,7 +349,7 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_transform_shader(orig_fs->tokens, (struct tgsi_token *) pstip_fs.tokens, - MAX, &transform.base); + newLen, &transform.base); #if 0 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index ac29634d67..153097e543 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -151,8 +151,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) { struct draw_context *draw = stage->draw; struct draw_stage *next = draw->pipeline.rasterize; - int need_det = 0; - int precalc_flat = 0; + boolean need_det = FALSE; + boolean precalc_flat = FALSE; boolean wide_lines, wide_points; /* Set the validate's next stage to the rasterize stage, so that it @@ -194,7 +194,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) if (wide_lines) { draw->pipeline.wide_line->next = next; next = draw->pipeline.wide_line; - precalc_flat = 1; + precalc_flat = TRUE; } if (wide_points || draw->rasterizer->sprite_coord_enable) { @@ -205,7 +205,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) { draw->pipeline.stipple->next = next; next = draw->pipeline.stipple; - precalc_flat = 1; /* only needed for lines really */ + precalc_flat = TRUE; /* only needed for lines really */ } if (draw->rasterizer->poly_stipple_enable @@ -218,8 +218,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { draw->pipeline.unfilled->next = next; next = draw->pipeline.unfilled; - precalc_flat = 1; /* only needed for triangles really */ - need_det = 1; + precalc_flat = TRUE; /* only needed for triangles really */ + need_det = TRUE; } if (draw->rasterizer->flatshade && precalc_flat) { @@ -231,13 +231,13 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) draw->rasterizer->offset_ccw) { draw->pipeline.offset->next = next; next = draw->pipeline.offset; - need_det = 1; + need_det = TRUE; } if (draw->rasterizer->light_twoside) { draw->pipeline.twoside->next = next; next = draw->pipeline.twoside; - need_det = 1; + need_det = TRUE; } /* Always run the cull stage as we calculate determinant there diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 1a5269c0de..d40c035240 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -138,7 +138,7 @@ emit_vertex( struct vbuf_stage *vbuf, /* Note: we really do want data[0] here, not data[pos]: */ vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); - vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); + vbuf->translate->run(vbuf->translate, 0, 1, 0, vbuf->vertex_ptr); if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); @@ -271,10 +271,12 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) emit_sz = 0; break; } - + + hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; hw_key.element[i].input_buffer = src_buffer; hw_key.element[i].input_offset = src_offset; + hw_key.element[i].instance_divisor = 0; hw_key.element[i].output_format = output_format; hw_key.element[i].output_offset = dst_offset; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index e49041556b..1e6e01af9e 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -48,8 +48,6 @@ struct pipe_context; -struct gallivm_prog; -struct gallivm_cpu_engine; struct draw_vertex_shader; struct draw_context; struct draw_stage; @@ -153,8 +151,8 @@ struct draw_context const void *vbuffer[PIPE_MAX_ATTRIBS]; /** constant buffer (for vertex/geometry shader) */ - const void *vs_constants; - const void *gs_constants; + const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; + const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; } user; boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ @@ -172,6 +170,8 @@ struct draw_context boolean force_passthrough; /**< never clip or shade */ + boolean dump_vs; + double mrd; /**< minimum resolvable depth value, for polygon offset */ /* pipe state that we need: */ @@ -191,19 +191,15 @@ struct draw_context uint num_samplers; struct tgsi_sampler **samplers; - /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. - */ - struct gallivm_cpu_engine *engine; - /* Here's another one: */ struct aos_machine *aos_machine; - const float (*aligned_constants)[4]; + const void *aligned_constants[PIPE_MAX_CONSTANT_BUFFERS]; - const float (*aligned_constant_storage)[4]; - unsigned const_storage_size; + const void *aligned_constant_storage[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned const_storage_size[PIPE_MAX_CONSTANT_BUFFERS]; struct translate *fetch; @@ -239,6 +235,8 @@ struct draw_context unsigned reduced_prim; + unsigned instance_id; + void *driver_private; }; @@ -252,9 +250,11 @@ void draw_vs_destroy( struct draw_context *draw ); void draw_vs_set_viewport( struct draw_context *, const struct pipe_viewport_state * ); -void draw_vs_set_constants( struct draw_context *, - const float (*constants)[4], - unsigned size ); +void +draw_vs_set_constants(struct draw_context *, + unsigned slot, + const void *constants, + unsigned size); @@ -262,15 +262,20 @@ void draw_vs_set_constants( struct draw_context *, * Geometry shading code: */ boolean draw_gs_init( struct draw_context *draw ); -void draw_gs_set_constants( struct draw_context *, - const float (*constants)[4], - unsigned size ); + +void +draw_gs_set_constants(struct draw_context *, + unsigned slot, + const void *constants, + unsigned size); + +void draw_gs_destroy( struct draw_context *draw ); /******************************************************************************* * Common shading code: */ -int draw_current_shader_outputs(struct draw_context *draw); -int draw_current_shader_position_output(struct draw_context *draw); +uint draw_current_shader_outputs(const struct draw_context *draw); +uint draw_current_shader_position_output(const struct draw_context *draw); /******************************************************************************* * Vertex processing (was passthrough) code: diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 2801dbafe4..f5ed32d0b0 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -33,7 +33,6 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" -#include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" #include "util/u_math.h" #include "util/u_prim.h" @@ -280,20 +279,33 @@ void draw_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count) { - unsigned reduced_prim = u_reduced_prim(prim); + draw_arrays_instanced(draw, prim, start, count, 0, 1); +} + +void +draw_arrays_instanced(struct draw_context *draw, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount) +{ + unsigned reduced_prim = u_reduced_prim(mode); + unsigned instance; + if (reduced_prim != draw->reduced_prim) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); draw->reduced_prim = reduced_prim; } if (0) - draw_print_arrays(draw, prim, start, MIN2(count, 20)); + draw_print_arrays(draw, mode, start, MIN2(count, 20)); #if 0 { int i; - debug_printf("draw_arrays(prim=%u start=%u count=%u):\n", - prim, start, count); + debug_printf("draw_arrays(mode=%u start=%u count=%u):\n", + mode, start, count); tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { @@ -311,6 +323,8 @@ draw_arrays(struct draw_context *draw, unsigned prim, } #endif - /* drawing done here: */ - draw_pt_arrays(draw, prim, start, count); + for (instance = 0; instance < instanceCount; instance++) { + draw->instance_id = instance + startInstance; + draw_pt_arrays(draw, mode, start, count); + } } diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 20edf7a227..d5e0d92a60 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -183,7 +183,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); struct pt_fetch; void draw_pt_fetch_prepare( struct pt_fetch *fetch, unsigned vertex_input_count, - unsigned vertex_size ); + unsigned vertex_size, + unsigned instance_id_index ); void draw_pt_fetch_run( struct pt_fetch *fetch, const unsigned *elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 064e16c295..4fb53276bb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -121,10 +121,12 @@ void draw_pt_emit_prepare( struct pt_emit *emit, emit_sz = 0; break; } - + + hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; hw_key.element[i].input_buffer = src_buffer; hw_key.element[i].input_offset = src_offset; + hw_key.element[i].instance_divisor = 0; hw_key.element[i].output_format = output_format; hw_key.element[i].output_offset = dst_offset; @@ -204,6 +206,7 @@ void draw_pt_emit( struct pt_emit *emit, translate->run( translate, 0, vertex_count, + draw->instance_id, hw_verts ); render->unmap_vertices( render, @@ -263,6 +266,7 @@ void draw_pt_emit_linear(struct pt_emit *emit, translate->run(translate, 0, count, + draw->instance_id, hw_verts); if (0) { diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 305bfef435..252be5053e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -30,7 +30,6 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" -#include "draw/draw_vertex.h" #include "draw/draw_pt.h" #include "translate/translate.h" #include "translate/translate_cache.h" @@ -58,12 +57,14 @@ struct pt_fetch { */ void draw_pt_fetch_prepare( struct pt_fetch *fetch, unsigned vs_input_count, - unsigned vertex_size ) + unsigned vertex_size, + unsigned instance_id_index ) { struct draw_context *draw = fetch->draw; unsigned nr_inputs; - unsigned i, nr = 0; + unsigned i, nr = 0, ei = 0; unsigned dst_offset = 0; + unsigned num_extra_inputs = 0; struct translate_key key; fetch->vertex_size = vertex_size; @@ -78,9 +79,11 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, { /* Need to set header->vertex_id = 0xffff somehow. */ + key.element[nr].type = TRANSLATE_ELEMENT_NORMAL; key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; key.element[nr].input_buffer = draw->pt.nr_vertex_buffers; key.element[nr].input_offset = 0; + key.element[nr].instance_divisor = 0; key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; key.element[nr].output_offset = dst_offset; dst_offset += 1 * sizeof(float); @@ -91,19 +94,36 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, */ dst_offset += 4 * sizeof(float); } - - assert( draw->pt.nr_vertex_elements >= vs_input_count ); - nr_inputs = MIN2( vs_input_count, draw->pt.nr_vertex_elements ); + if (instance_id_index != ~0) { + num_extra_inputs++; + } + + assert(draw->pt.nr_vertex_elements + num_extra_inputs >= vs_input_count); + + nr_inputs = MIN2(vs_input_count, draw->pt.nr_vertex_elements + num_extra_inputs); for (i = 0; i < nr_inputs; i++) { - key.element[nr].input_format = draw->pt.vertex_element[i].src_format; - key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index; - key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset; - key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - key.element[nr].output_offset = dst_offset; + if (i == instance_id_index) { + key.element[nr].type = TRANSLATE_ELEMENT_INSTANCE_ID; + key.element[nr].input_format = PIPE_FORMAT_R32_USCALED; + key.element[nr].output_format = PIPE_FORMAT_R32_USCALED; + key.element[nr].output_offset = dst_offset; + + dst_offset += sizeof(uint); + } else { + key.element[nr].type = TRANSLATE_ELEMENT_NORMAL; + key.element[nr].input_format = draw->pt.vertex_element[ei].src_format; + key.element[nr].input_buffer = draw->pt.vertex_element[ei].vertex_buffer_index; + key.element[nr].input_offset = draw->pt.vertex_element[ei].src_offset; + key.element[nr].instance_divisor = draw->pt.vertex_element[ei].instance_divisor; + key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + key.element[nr].output_offset = dst_offset; + + ei++; + dst_offset += 4 * sizeof(float); + } - dst_offset += 4 * sizeof(float); nr++; } @@ -158,6 +178,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, translate->run_elts( translate, elts, count, + draw->instance_id, verts ); } @@ -183,6 +204,7 @@ void draw_pt_fetch_run_linear( struct pt_fetch *fetch, translate->run( translate, start, count, + draw->instance_id, verts ); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index e7fe6b3b76..2a604470e9 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -166,9 +166,11 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, continue; } + key.element[i].type = TRANSLATE_ELEMENT_NORMAL; key.element[i].input_format = input_format; key.element[i].input_buffer = input_buffer; key.element[i].input_offset = input_offset; + key.element[i].instance_divisor = src->instance_divisor; key.element[i].output_format = output_format; key.element[i].output_offset = dst_offset; @@ -256,6 +258,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, feme->translate->run_elts( feme->translate, fetch_elts, fetch_count, + draw->instance_id, hw_verts ); if (0) { @@ -314,6 +317,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, feme->translate->run( feme->translate, start, count, + draw->instance_id, hw_verts ); if (0) { @@ -374,6 +378,7 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, feme->translate->run( feme->translate, start, count, + draw->instance_id, hw_verts ); draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 734c05f068..c5dfbcfa3c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -40,7 +40,6 @@ #include "draw/draw_pt.h" #include "draw/draw_vs.h" -#include "translate/translate.h" struct fetch_shade_emit; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 1a9df4cac5..56b69354b2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -33,7 +33,6 @@ #include "draw/draw_pt.h" #include "draw/draw_vs.h" #include "draw/draw_gs.h" -#include "translate/translate.h" struct fetch_pipeline_middle_end { @@ -59,6 +58,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vs = draw->vs.vertex_shader; + unsigned i; + unsigned instance_id_index = ~0; /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. @@ -66,6 +67,15 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned nr = MAX2( vs->info.num_inputs, vs->info.num_outputs + 1 ); + /* Scan for instanceID system value. + */ + for (i = 0; i < vs->info.num_inputs; i++) { + if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) { + instance_id_index = i; + break; + } + } + fpme->prim = prim; fpme->opt = opt; @@ -79,7 +89,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, draw_pt_fetch_prepare( fpme->fetch, vs->info.num_inputs, - fpme->vertex_size ); + fpme->vertex_size, + instance_id_index ); /* XXX: it's not really gl rasterization rules we care about here, * but gl vs dx9 clip spaces. */ @@ -152,7 +163,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, vshader->run_linear(vshader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.vs_constants, + draw->pt.user.vs_constants, fetch_count, fpme->vertex_size, fpme->vertex_size); @@ -160,7 +171,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_geometry_shader_run(gshader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.gs_constants, + draw->pt.user.gs_constants, fetch_count, fpme->vertex_size, fpme->vertex_size); @@ -237,7 +248,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.vs_constants, + draw->pt.user.vs_constants, count, fpme->vertex_size, fpme->vertex_size); @@ -246,7 +257,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, draw_geometry_shader_run(geometry_shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.gs_constants, + draw->pt.user.gs_constants, count, fpme->vertex_size, fpme->vertex_size); @@ -317,7 +328,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.vs_constants, + draw->pt.user.vs_constants, count, fpme->vertex_size, fpme->vertex_size); @@ -326,7 +337,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle draw_geometry_shader_run(geometry_shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->pt.user.gs_constants, + draw->pt.user.gs_constants, count, fpme->vertex_size, fpme->vertex_size); diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 55151823a1..9728d5c2bd 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -30,7 +30,6 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" -#include "draw/draw_vertex.h" #include "draw/draw_pt.h" struct pt_post_vs { diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c index 17c3b8cec2..3236d38e6a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_util.c +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -33,6 +33,7 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" +#include "util/u_debug.h" void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) { diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 554f4ac3c1..8c3c7befbc 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -39,7 +39,9 @@ #define DRAW_VERTEX_H +#include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "util/u_debug.h" /** diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 3553689532..6bdd612e6f 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -43,29 +43,32 @@ #include "translate/translate.h" #include "translate/translate_cache.h" +#include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_exec.h" - -void draw_vs_set_constants( struct draw_context *draw, - const float (*constants)[4], - unsigned size ) +void +draw_vs_set_constants(struct draw_context *draw, + unsigned slot, + const void *constants, + unsigned size) { if (((uintptr_t)constants) & 0xf) { - if (size > draw->vs.const_storage_size) { - if (draw->vs.aligned_constant_storage) - align_free((void *)draw->vs.aligned_constant_storage); - draw->vs.aligned_constant_storage = align_malloc( size, 16 ); + if (size > draw->vs.const_storage_size[slot]) { + if (draw->vs.aligned_constant_storage[slot]) { + align_free((void *)draw->vs.aligned_constant_storage[slot]); + } + draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16); } - memcpy( (void*)draw->vs.aligned_constant_storage, - constants, - size ); - constants = draw->vs.aligned_constant_storage; + memcpy((void *)draw->vs.aligned_constant_storage[slot], + constants, + size); + constants = draw->vs.aligned_constant_storage[slot]; } - - draw->vs.aligned_constants = constants; - draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); + + draw->vs.aligned_constants[slot] = constants; + draw_vs_aos_machine_constants(draw->vs.aos_machine, slot, constants); } @@ -83,6 +86,10 @@ draw_create_vertex_shader(struct draw_context *draw, { struct draw_vertex_shader *vs; + if (draw->dump_vs) { + tgsi_dump(shader->tokens, 0); + } + vs = draw_create_vs_llvm( draw, shader ); if (!vs) { vs = draw_create_vs_sse( draw, shader ); @@ -152,6 +159,8 @@ draw_delete_vertex_shader(struct draw_context *draw, boolean draw_vs_init( struct draw_context *draw ) { + draw->dump_vs = debug_get_bool_option("GALLIUM_DUMP_VS", FALSE); + draw->vs.machine = tgsi_exec_machine_create(); if (!draw->vs.machine) return FALSE; @@ -176,6 +185,8 @@ draw_vs_init( struct draw_context *draw ) void draw_vs_destroy( struct draw_context *draw ) { + uint i; + if (draw->vs.fetch_cache) translate_cache_destroy(draw->vs.fetch_cache); @@ -185,8 +196,11 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.aos_machine) draw_vs_aos_machine_destroy(draw->vs.aos_machine); - if (draw->vs.aligned_constant_storage) - align_free((void*)draw->vs.aligned_constant_storage); + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + if (draw->vs.aligned_constant_storage[i]) { + align_free((void *)draw->vs.aligned_constant_storage[i]); + } + } tgsi_exec_machine_destroy(draw->vs.machine); } diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index e3b807ebd0..d095c9bad1 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -43,6 +43,7 @@ struct draw_varient_input enum pipe_format format; unsigned buffer; unsigned offset; + unsigned instance_divisor; }; struct draw_varient_output @@ -131,7 +132,7 @@ struct draw_vertex_shader { void (*run_linear)( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ); @@ -211,8 +212,10 @@ static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key struct aos_machine *draw_vs_aos_machine( void ); void draw_vs_aos_machine_destroy( struct aos_machine *machine ); -void draw_vs_aos_machine_constants( struct aos_machine *machine, - const float (*constants)[4] ); +void +draw_vs_aos_machine_constants(struct aos_machine *machine, + unsigned slot, + const void *constants); void draw_vs_aos_machine_viewport( struct aos_machine *machine, const struct pipe_viewport_state *viewport ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1aaae4ab7a..e7121f3654 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2114,11 +2114,14 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; struct aos_machine *machine = vaos->draw->vs.aos_machine; + unsigned i; if (0) debug_printf("%s %d\n", __FUNCTION__, count); machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = vaos->draw->vs.aligned_constants; + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->constants[i] = vaos->draw->vs.aligned_constants[i]; + } machine->immediates = vaos->base.vs->immediates; machine->buffer = vaos->buffer; @@ -2135,12 +2138,15 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; struct aos_machine *machine = vaos->draw->vs.aos_machine; + unsigned i; if (0) debug_printf("%s %d %d const: %x\n", __FUNCTION__, start, count, vaos->base.key.const_vbuffers); machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = vaos->draw->vs.aligned_constants; + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->constants[i] = vaos->draw->vs.aligned_constants[i]; + } machine->immediates = vaos->base.vs->immediates; machine->buffer = vaos->buffer; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 2cf72ddf7b..1911242f82 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -122,7 +122,7 @@ struct aos_machine { ushort fpucntl; /* one of FPU_* above */ const float (*immediates)[4]; /* points to shader data */ - const float (*constants)[4]; /* points to draw data */ + const void *constants[PIPE_MAX_CONSTANT_BUFFERS]; /* points to draw data */ const struct aos_buffer *buffer; /* points to ? */ }; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index 3240e3745d..0eda414ee6 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -219,10 +219,12 @@ static void PIPE_CDECL populate_lut( struct aos_machine *machine, } -void draw_vs_aos_machine_constants( struct aos_machine *machine, - const float (*constants)[4] ) +void +draw_vs_aos_machine_constants(struct aos_machine *machine, + unsigned slot, + const void *constants) { - machine->constants = constants; + machine->constants[slot] = constants; { unsigned i; @@ -307,8 +309,10 @@ void draw_vs_aos_machine_viewport( struct aos_machine *machine, { } -void draw_vs_aos_machine_constants( struct aos_machine *machine, - const float (*constants)[4] ) +void +draw_vs_aos_machine_constants(struct aos_machine *machine, + unsigned slot, + const void *constants) { } diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 41cc802613..7deca2b69d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -85,7 +85,7 @@ static void vs_exec_run_linear( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) @@ -95,7 +95,9 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, unsigned int i, j; unsigned slot; - machine->Consts = constants; + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->Consts[i] = constants[i]; + } for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index b3535c0e48..5f7a645f5d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -42,11 +42,8 @@ #ifdef MESA_LLVM -#include "gallivm/gallivm.h" - struct draw_llvm_vertex_shader { struct draw_vertex_shader base; - struct gallivm_prog *llvm_prog; struct tgsi_exec_machine *machine; }; @@ -58,23 +55,17 @@ vs_llvm_prepare( struct draw_vertex_shader *base, } - - static void vs_llvm_run_linear( struct draw_vertex_shader *base, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) { struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - - gallivm_cpu_vs_exec(shader->llvm_prog, shader->machine, - input, base->info.num_inputs, output, base->info.num_outputs, - constants, count, input_stride, output_stride); } @@ -121,27 +112,6 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.delete = vs_llvm_delete; vs->machine = draw->vs.machine; - { - struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); - gallivm_ir_set_layout(ir, GALLIVM_SOA); - gallivm_ir_set_components(ir, 4); - gallivm_ir_fill_from_tgsi(ir, vs->base.state.tokens); - vs->llvm_prog = gallivm_ir_compile(ir); - gallivm_ir_delete(ir); - } - - draw->vs.engine = gallivm_global_cpu_engine(); - - /* XXX: Why are there two versions of this? Shouldn't creating the - * engine be a separate operation to compiling a shader? - */ - if (!draw->vs.engine) { - draw->vs.engine = gallivm_cpu_engine_create(vs->llvm_prog); - } - else { - gallivm_cpu_jit_compile(draw->vs.engine, vs->llvm_prog); - } - return &vs->base; } diff --git a/src/gallium/auxiliary/draw/draw_vs_ppc.c b/src/gallium/auxiliary/draw/draw_vs_ppc.c index ad184bd696..d869eecec5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_ppc.c +++ b/src/gallium/auxiliary/draw/draw_vs_ppc.c @@ -85,7 +85,7 @@ static void vs_ppc_run_linear( struct draw_vertex_shader *base, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) @@ -98,9 +98,9 @@ vs_ppc_run_linear( struct draw_vertex_shader *base, /* loop over verts */ for (i = 0; i < count; i += MAX_VERTICES) { const uint max_vertices = MIN2(MAX_VERTICES, count - i); - float inputs_soa[PIPE_MAX_SHADER_INPUTS][4][4] ALIGN16_ATTRIB; - float outputs_soa[PIPE_MAX_SHADER_OUTPUTS][4][4] ALIGN16_ATTRIB; - float temps_soa[TGSI_EXEC_NUM_TEMPS][4][4] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) float inputs_soa[PIPE_MAX_SHADER_INPUTS][4][4]; + PIPE_ALIGN_VAR(16) float outputs_soa[PIPE_MAX_SHADER_OUTPUTS][4][4]; + PIPE_ALIGN_VAR(16) float temps_soa[TGSI_EXEC_NUM_TEMPS][4][4]; uint attr; /* convert (up to) four input verts to SoA format */ @@ -125,7 +125,7 @@ vs_ppc_run_linear( struct draw_vertex_shader *base, */ shader->func(inputs_soa, outputs_soa, temps_soa, (float (*)[4]) shader->base.immediates, - (float (*)[4]) constants, + (const float (*)[4])constants[0], ppc_builtin_constants); /* convert (up to) four output verts from SoA back to AoS format */ diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 702051387a..54e6423388 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -83,7 +83,7 @@ static void vs_sse_run_linear( struct draw_vertex_shader *base, const float (*input)[4], float (*output)[4], - const float (*constants)[4], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) @@ -112,7 +112,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base, /* run compiled shader */ shader->func(machine, - constants, + (const float (*)[4])constants[0], shader->base.immediates, input, base->info.num_inputs, diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d16692584e..5ed706cb4f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -38,7 +38,6 @@ #include "draw/draw_vertex.h" #include "draw/draw_vs.h" #include "translate/translate.h" -#include "translate/translate_cache.h" /* A first pass at incorporating vertex fetch/emit functionality into */ @@ -142,12 +141,13 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->fetch->run_elts( vsvg->fetch, elts, count, + vsvg->draw->instance_id, temp_buffer ); vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, count, temp_vertex_stride, temp_vertex_stride); @@ -181,6 +181,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->emit->run( vsvg->emit, 0, count, + vsvg->draw->instance_id, output_buffer ); FREE(temp_buffer); @@ -203,12 +204,13 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->fetch->run( vsvg->fetch, start, count, + vsvg->draw->instance_id, temp_buffer ); vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, count, temp_vertex_stride, temp_vertex_stride); @@ -239,6 +241,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->emit->run( vsvg->emit, 0, count, + vsvg->draw->instance_id, output_buffer ); FREE(temp_buffer); @@ -281,9 +284,11 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, fetch.nr_elements = key->nr_inputs; fetch.output_stride = vsvg->temp_vertex_stride; for (i = 0; i < key->nr_inputs; i++) { + fetch.element[i].type = TRANSLATE_ELEMENT_NORMAL; fetch.element[i].input_format = key->element[i].in.format; fetch.element[i].input_buffer = key->element[i].in.buffer; fetch.element[i].input_offset = key->element[i].in.offset; + fetch.element[i].instance_divisor = 0; fetch.element[i].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; fetch.element[i].output_offset = i * 4 * sizeof(float); assert(fetch.element[i].output_offset < fetch.output_stride); @@ -295,17 +300,21 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, for (i = 0; i < key->nr_outputs; i++) { if (key->element[i].out.format != EMIT_1F_PSIZE) { + emit.element[i].type = TRANSLATE_ELEMENT_NORMAL; emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit.element[i].input_buffer = 0; emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float); + emit.element[i].instance_divisor = 0; emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format); emit.element[i].output_offset = key->element[i].out.offset; assert(emit.element[i].input_offset <= fetch.output_stride); } else { + emit.element[i].type = TRANSLATE_ELEMENT_NORMAL; emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; emit.element[i].input_buffer = 1; emit.element[i].input_offset = 0; + emit.element[i].instance_divisor = 0; emit.element[i].output_format = PIPE_FORMAT_R32_FLOAT; emit.element[i].output_offset = key->element[i].out.offset; } diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp deleted file mode 100644 index f4af5cc8ad..0000000000 --- a/src/gallium/auxiliary/gallivm/gallivm.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/tgsi_exec.h" -#include "tgsi/tgsi_dump.h" - -#include <llvm/Module.h> -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/Instructions.h> -#include <llvm/ModuleProvider.h> -#include <llvm/Pass.h> -#include <llvm/PassManager.h> -#include <llvm/Attributes.h> -#include <llvm/Support/PatternMatch.h> -#include <llvm/ExecutionEngine/JIT.h> -#include <llvm/ExecutionEngine/Interpreter.h> -#include <llvm/ExecutionEngine/GenericValue.h> -#include <llvm/Support/MemoryBuffer.h> -#include <llvm/LinkAllPasses.h> -#include <llvm/Analysis/Verifier.h> -#include <llvm/Analysis/LoopPass.h> -#include <llvm/Target/TargetData.h> -#include <llvm/Bitcode/ReaderWriter.h> -#include <llvm/Transforms/Utils/Cloning.h> - -#include <sstream> -#include <fstream> -#include <iostream> - -static int GLOBAL_ID = 0; - -using namespace llvm; - -static inline -void AddStandardCompilePasses(PassManager &PM) -{ - PM.add(new LoweringPass()); - PM.add(createVerifierPass()); // Verify that input is correct - - PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - - //PM.add(createStripSymbolsPass(true)); - - PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM.add(createCFGSimplificationPass()); // Clean up disgusting code - PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas - PM.add(createGlobalOptimizerPass()); // Optimize out global vars - PM.add(createGlobalDCEPass()); // Remove unused fns and globs - PM.add(createIPConstantPropagationPass());// IP Constant Propagation - PM.add(createDeadArgEliminationPass()); // Dead argument elimination - PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - - PM.add(createPruneEHPass()); // Remove dead EH info - - PM.add(createFunctionInliningPass()); // Inline small functions - PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - PM.add(createTailDuplicationPass()); // Simplify cfg by copying code - PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM.add(createInstructionCombiningPass()); // Combine silly seq's - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createTailCallEliminationPass()); // Eliminate tail calls - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createReassociatePass()); // Reassociate expressions - PM.add(createLoopRotatePass()); - PM.add(createLICMPass()); // Hoist loop invariants - PM.add(createLoopUnswitchPass()); // Unswitch loops. - PM.add(createLoopIndexSplitPass()); // Index split loops. - PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc - PM.add(createIndVarSimplifyPass()); // Canonicalize indvars - PM.add(createLoopUnrollPass()); // Unroll small loops - PM.add(createInstructionCombiningPass()); // Clean up after the unroller - PM.add(createGVNPass()); // Remove redundancies - PM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM.add(createInstructionCombiningPass()); - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createDeadStoreEliminationPass()); // Delete dead stores - PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM.add(createDeadTypeEliminationPass()); // Eliminate dead types - PM.add(createConstantMergePass()); // Merge dup global constants -} - -void gallivm_prog_delete(struct gallivm_prog *prog) -{ - delete prog->module; - prog->module = 0; - prog->function = 0; - free(prog); -} - -static inline void -constant_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for (i = 0; i < QUAD_SIZE; ++i) { - inputs[i][attrib][chan] = coefs[attrib].a0[chan]; - } -} - -static inline void -linear_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - - inputs[i][attrib][chan] = - coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y; - } -} - -static inline void -perspective_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - /* WPOS.w here is really 1/w */ - const float w = 1.0f / inputs[i][0][3]; - assert(inputs[i][0][3] != 0.0); - - inputs[i][attrib][chan] = - (coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y) * w; - } -} - -void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) -{ - if (!ir || !ir->module) - return; - - if (file_prefix) { - std::ostringstream stream; - stream << file_prefix; - stream << ir->id; - stream << ".ll"; - std::string name = stream.str(); - std::ofstream out(name.c_str()); - if (!out) { - std::cerr<<"Can't open file : "<<stream.str()<<std::endl;; - return; - } - out << (*ir->module); - out.close(); - } else { - const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); - llvm::Module::FunctionListType::const_iterator itr; - std::cout<<"; ---------- Start shader "<<ir->id<<std::endl; - for (itr = funcs.begin(); itr != funcs.end(); ++itr) { - const llvm::Function &func = (*itr); - std::string name = func.getName(); - const llvm::Function *found = 0; - if (name.find("vs_shader") != std::string::npos || - name.find("fs_shader") != std::string::npos || - name.find("function") != std::string::npos) - found = &func; - if (found) { - std::cout<<*found<<std::endl; - } - } - std::cout<<"; ---------- End shader "<<ir->id<<std::endl; - } -} - - -void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, - float (*inputs)[16][4], - const struct tgsi_interp_coef *coef) -{ - for (int i = 0; i < prog->num_interp; ++i) { - const gallivm_interpolate &interp = prog->interpolators[i]; - switch (interp.type) { - case TGSI_INTERPOLATE_CONSTANT: - constant_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_LINEAR: - linear_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - perspective_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - default: - assert( 0 ); - } - } -} - - -struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) -{ - struct gallivm_ir *ir = - (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); - ++GLOBAL_ID; - ir->id = GLOBAL_ID; - ir->type = type; - - return ir; -} - -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout) -{ - ir->layout = layout; -} - -void gallivm_ir_set_components(struct gallivm_ir *ir, int num) -{ - ir->num_components = num; -} - -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - std::cout << "Creating llvm from: " <<std::endl; - tgsi_dump(tokens, 0); - - llvm::Module *mod = tgsi_to_llvmir(ir, tokens); - ir->module = mod; - gallivm_ir_dump(ir, 0); -} - -void gallivm_ir_delete(struct gallivm_ir *ir) -{ - delete ir->module; - free(ir); -} - -struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) -{ - struct gallivm_prog *prog = - (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); - - std::cout << "Before optimizations:"<<std::endl; - ir->module->dump(); - std::cout<<"-------------------------------"<<std::endl; - - PassManager veri; - veri.add(createVerifierPass()); - veri.run(*ir->module); - llvm::Module *mod = llvm::CloneModule(ir->module); - prog->num_consts = ir->num_consts; - memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); - prog->num_interp = ir->num_interp; - - /* Run optimization passes over it */ - PassManager passes; - passes.add(new TargetData(mod)); - AddStandardCompilePasses(passes); - passes.run(*mod); - prog->module = mod; - - std::cout << "After optimizations:"<<std::endl; - mod->dump(); - - return prog; -} - -#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h deleted file mode 100644 index 36a64a7747..0000000000 --- a/src/gallium/auxiliary/gallivm/gallivm.h +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef GALLIVM_H -#define GALLIVM_H - -/* - LLVM representation consists of two stages - layout independent - intermediate representation gallivm_ir and driver specific - gallivm_prog. TGSI is first being translated into gallivm_ir - after that driver can set number of options on gallivm_ir and - have it compiled into gallivm_prog. gallivm_prog can be either - executed (assuming there's LLVM JIT backend for the current - target) or machine code generation can be done (assuming there's - a LLVM code generator for thecurrent target) - */ -#if defined __cplusplus -extern "C" { -#endif - -#include "pipe/p_state.h" - -#ifdef MESA_LLVM - -struct tgsi_token; - -struct gallivm_ir; -struct gallivm_prog; -struct gallivm_cpu_engine; -struct tgsi_interp_coef; -struct tgsi_sampler; -struct tgsi_exec_vector; - -enum gallivm_shader_type { - GALLIVM_VS, - GALLIVM_FS -}; - -enum gallivm_vector_layout { - GALLIVM_AOS, - GALLIVM_SOA -}; - -struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout); -void gallivm_ir_set_components(struct gallivm_ir *ir, int num); -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens); -void gallivm_ir_delete(struct gallivm_ir *ir); - - -struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); - -void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - const struct tgsi_interp_coef *coefs); -void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); - - -struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); -struct gallivm_cpu_engine *gallivm_global_cpu_engine(); -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_machine *machine, - const float (*input)[4], - unsigned num_inputs, - float (*output)[4], - unsigned num_outputs, - const float (*constants)[4], - unsigned count, - unsigned input_stride, - unsigned output_stride); -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float x, float y, - float (*dests)[PIPE_MAX_SHADER_INPUTS][4], - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - float (*consts)[4], - struct tgsi_sampler *samplers); -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); - - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} -#endif - -#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp deleted file mode 100644 index 634bac0150..0000000000 --- a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp +++ /dev/null @@ -1,140 +0,0 @@ -static const unsigned char llvm_builtins_data[] = { -0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0x27,0x02,0x00,0x00,0x01,0x10,0x00,0x00, -0x10,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,0x39, -0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,0x02, -0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,0x24, -0x48,0x0a,0x90,0x21,0x23,0x44,0x72,0x80,0x8c,0x14,0x21,0x86,0x0a,0x8a,0x0a,0x64, -0x0c,0x1f,0x00,0x00,0x49,0x18,0x00,0x00,0x03,0x00,0x00,0x00,0x0b,0x84,0xff,0xff, -0xff,0xff,0x1f,0xc0,0x00,0x00,0x00,0x00,0x51,0x20,0x00,0x00,0x12,0x00,0x00,0x00, -0x32,0x22,0x48,0x09,0x20,0x65,0x82,0x84,0x00,0x26,0x45,0x48,0x05,0x09,0x26,0x45, -0xc6,0x05,0x42,0x52,0x26,0x08,0xae,0x19,0x80,0x61,0x04,0x02,0x98,0x23,0x00,0x83, -0x29,0x80,0x21,0x00,0xb2,0x73,0x04,0x01,0x51,0x8a,0xf4,0x08,0x92,0xa4,0x39,0x47, -0x80,0x50,0x2b,0x03,0x00,0xa0,0x08,0x21,0x5c,0x46,0x2b,0x44,0x08,0x21,0xd4,0x40, -0x14,0x01,0x80,0x11,0x80,0x22,0x88,0x00,0x13,0x30,0x7c,0xc0,0x03,0x3b,0xf8,0x05, -0x3b,0xa0,0x83,0x36,0xa8,0x07,0x77,0x58,0x07,0x77,0x78,0x87,0x7b,0x70,0x87,0x36, -0x60,0x87,0x74,0x70,0x87,0x7a,0xc0,0x87,0x36,0x38,0x07,0x77,0xa8,0x87,0x0d,0xf7, -0x50,0x0e,0x6d,0x00,0x0f,0x7a,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60, -0x07,0x74,0xd0,0x06,0xe9,0x10,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e, -0x78,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06,0xe9,0x10,0x07,0x76,0xa0,0x07,0x71, -0x60,0x07,0x7a,0x10,0x07,0x76,0xd0,0x06,0xe9,0x30,0x07,0x72,0xa0,0x07,0x73,0x20, -0x07,0x7a,0x30,0x07,0x72,0xd0,0x06,0xe9,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07, -0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x7a, -0x30,0x07,0x72,0xd0,0x06,0xe6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60, -0x07,0x74,0xd0,0x06,0xf6,0x60,0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x7a,0x60,0x07, -0x74,0xd0,0x06,0xf6,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a, -0x10,0x07,0x72,0x80,0x07,0x6d,0x10,0x0e,0x70,0xa0,0x07,0x70,0xa0,0x07,0x76,0x40, -0x07,0x6d,0x60,0x0e,0x78,0x00,0x07,0x7a,0x10,0x07,0x72,0x80,0x07,0x7a,0x10,0x07, -0x72,0x80,0x07,0x3a,0x0f,0x84,0x48,0x20,0x23,0x24,0x40,0x00,0x62,0x67,0x88,0x9f, -0x19,0x92,0x24,0x00,0x10,0x04,0x00,0x00,0x00,0x43,0x92,0x04,0x08,0x00,0x00,0x00, -0x00,0x60,0x48,0xa2,0x00,0x40,0x10,0x00,0x00,0x00,0x0c,0x49,0x16,0x00,0x08,0x02, -0x00,0x00,0x80,0x21,0x89,0x02,0x00,0x41,0x00,0x00,0x00,0x30,0x24,0x61,0x80,0x00, -0x00,0x00,0x00,0x00,0x86,0x24,0x07,0x10,0x00,0x00,0x00,0x00,0xc0,0x90,0x44,0x01, -0x80,0x20,0x00,0x00,0x00,0x18,0x92,0x1c,0x40,0x00,0x00,0x00,0x00,0x00,0x43,0x12, -0x05,0x00,0x82,0x00,0x00,0x00,0x60,0x48,0x52,0x00,0x40,0x10,0x00,0x00,0x00,0x64, -0x81,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90, -0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x8a,0x8a,0x59,0x8b,0x43,0x50,0xd2,0x09,0x02, -0x81,0xd2,0x73,0x50,0xc9,0x0c,0x2a,0x99,0x41,0x25,0x33,0xa8,0x64,0x56,0x28,0x66, -0x2d,0x0e,0x41,0xcf,0x2a,0x15,0x04,0x4a,0xcf,0x41,0x25,0x33,0xa8,0x64,0x06,0x95, -0xcc,0xa0,0x92,0x59,0x01,0x00,0x00,0x00,0x53,0x82,0x26,0x0c,0x04,0x00,0x00,0x00, -0x22,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00, -0x04,0xc6,0x08,0x40,0x10,0x04,0xe1,0x70,0x18,0x23,0x00,0x41,0x10,0x84,0xc3,0x60, -0x04,0x00,0x00,0x00,0xc3,0x0d,0xce,0x43,0x4c,0x37,0x3c,0x8e,0x34,0xdc,0x30,0x41, -0xc2,0x74,0x03,0x34,0x51,0xc3,0x0d,0x4d,0x44,0x4c,0x37,0x44,0x8d,0x35,0x56,0x01, -0x04,0xc3,0x55,0x21,0x16,0x0e,0x04,0x00,0x0f,0x00,0x00,0x00,0xd6,0x10,0x00,0xe6, -0x10,0x04,0x76,0x81,0x00,0x3e,0x30,0x0c,0x91,0x4f,0x1b,0x05,0x21,0x30,0x8f,0x6d, -0x13,0x48,0xe0,0x03,0xc3,0x10,0xf9,0xb4,0x55,0x20,0x81,0x0f,0x0c,0x43,0xe4,0xd7, -0x66,0x41,0x08,0xcc,0xa3,0x1f,0x40,0x41,0x34,0x53,0x84,0x99,0xc4,0x20,0x30,0x8f, -0x61,0x10,0x02,0xb0,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, -0x27,0x00,0x00,0x00,0x13,0x04,0x43,0x2c,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00, -0x24,0x8a,0xa0,0x0c,0x46,0x00,0x4a,0x80,0xc2,0x1c,0x84,0x55,0x55,0xd6,0x1c,0x84, -0x45,0x51,0x16,0x81,0x19,0x80,0x11,0x80,0x31,0x02,0x10,0x04,0x41,0xfc,0x03,0x00, -0x63,0x08,0x0d,0x34,0xdc,0x70,0x55,0xc2,0x2c,0x43,0x20,0x60,0x73,0x0c,0xd3,0x15, -0x8d,0x21,0x34,0xd1,0x18,0x42,0xf3,0x8c,0x55,0x00,0x81,0xa0,0x6d,0x73,0x0c,0x19, -0xe7,0x60,0x87,0x52,0x38,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x27,0x50,0x20,0x05, -0xd1,0x0c,0x17,0x60,0x20,0xc5,0x74,0x10,0x8d,0x65,0x14,0x13,0xf3,0xd4,0xb4,0x6d, -0x14,0x13,0xf3,0xd4,0xb8,0x69,0x14,0x13,0xf3,0xd4,0xb6,0x75,0x14,0x13,0xf3,0xd4, -0xba,0x35,0x0c,0x13,0xf3,0xd8,0x05,0x31,0x31,0x8f,0x6e,0x1c,0x84,0x00,0x2c,0xcb, -0x01,0x14,0x44,0x33,0x45,0x98,0x61,0x0c,0x02,0xf3,0x00,0x00,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x81,0x00,0x00,0x00,0x13,0x04,0x4d,0x2c,0x10,0x00,0x00,0x00, -0x04,0x00,0x00,0x00,0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x91, -0x11,0x00,0x00,0x00,0x63,0x08,0x4d,0x64,0x16,0xc1,0xe1,0x86,0xab,0x22,0x66,0x19, -0x02,0x01,0x1b,0x43,0x70,0xa2,0x59,0x82,0x61,0x0c,0xe1,0x89,0x66,0x09,0x86,0x81, -0x0a,0x20,0x0b,0x34,0x61,0x8e,0x81,0xda,0xa2,0x31,0x84,0x46,0xb2,0x8e,0xe0,0x70, -0x83,0x57,0x11,0xb3,0x0c,0x44,0xf1,0x8d,0x21,0x38,0xd2,0x2c,0x81,0x31,0x86,0xf0, -0x48,0xb3,0x04,0xc6,0x40,0x05,0x00,0x06,0x44,0x18,0x14,0x73,0x0c,0x9c,0x18,0x48, -0x63,0x08,0xcd,0x64,0x64,0x40,0x70,0xb8,0xa1,0x0c,0x2a,0x62,0x96,0xe1,0x40,0xcc, -0x60,0x0c,0xc1,0x99,0x66,0x09,0x92,0x31,0x84,0x67,0x9a,0x25,0x48,0x06,0x2a,0x80, -0x33,0x38,0xd0,0x00,0x99,0x63,0x18,0x83,0x34,0x98,0xc6,0x10,0x1a,0xc8,0xd6,0x80, -0xe0,0x70,0x03,0x1b,0x54,0xc4,0x2c,0x83,0xb2,0xb4,0xc1,0x18,0x82,0x03,0xcd,0x12, -0x30,0x63,0x08,0x0f,0x34,0x4b,0xc0,0x0c,0x54,0x00,0x6e,0xa0,0xbc,0xc1,0x32,0xc7, -0xa0,0x06,0x70,0x00,0x61,0x1c,0x84,0x03,0x01,0x00,0x00,0x00,0x4e,0x00,0x00,0x00, -0x76,0x52,0x4c,0xcc,0x73,0xd3,0x24,0x05,0x64,0xec,0xcd,0x8d,0xcc,0xe5,0x87,0x46, -0xc6,0x50,0x8a,0x89,0x79,0xee,0xdb,0x54,0x8a,0x89,0x79,0xee,0xdd,0x1a,0x88,0x89, -0x79,0x68,0x73,0x20,0x26,0xe6,0xa9,0xed,0x81,0x98,0x98,0xc7,0x36,0x0b,0x62,0x62, -0x9e,0xdb,0x32,0x88,0x89,0x79,0x72,0xd3,0x20,0x26,0xe6,0xd9,0x8d,0x83,0x98,0x98, -0xa7,0xb7,0x95,0x62,0x62,0x9e,0xbb,0x27,0x2d,0x20,0x63,0x6f,0x6e,0x64,0x2e,0x3a, -0x34,0x35,0x56,0x62,0x08,0x4e,0x53,0xd9,0xba,0xb5,0x14,0x02,0xf3,0xe0,0xf5,0x25, -0x2c,0x82,0xd3,0x0c,0xbe,0xe0,0x34,0xd3,0x8d,0x9b,0x88,0x21,0x38,0xcd,0x60,0xd7, -0x24,0x01,0x63,0xec,0xcd,0x8d,0xcc,0x45,0x87,0x44,0x80,0x8c,0xbd,0xb9,0x91,0xb9, -0xfc,0xc4,0xd0,0x90,0x02,0x8c,0xb1,0x37,0x37,0x32,0x97,0x1f,0x73,0x29,0x26,0xe6, -0xc1,0x71,0x7b,0x29,0x26,0xe6,0xc1,0x77,0xfb,0x28,0x04,0xe6,0xa9,0x6f,0x52,0x01, -0x32,0xf6,0xe6,0x46,0xe6,0xa2,0x13,0x73,0x63,0x18,0x83,0xc0,0x3c,0xb6,0x41,0x08, -0x4e,0x33,0x58,0x47,0x31,0x31,0x4f,0x5d,0x1f,0xc3,0x22,0x38,0xcd,0xe0,0x0b,0x4e, -0x33,0xe1,0xbc,0xa5,0x18,0x82,0xd3,0x0c,0x77,0x6e,0x20,0xc5,0xc4,0x3c,0xb5,0x4e, -0x3a,0x40,0xc6,0xde,0xdc,0xc8,0x5c,0x7e,0x64,0x70,0x2c,0xa4,0x98,0x98,0xa7,0xee, -0x6f,0x20,0x11,0x9c,0x66,0xf0,0x05,0xa7,0x99,0xec,0x82,0x10,0x9c,0xa6,0x32,0x93, -0x42,0x60,0x1e,0x7b,0xb7,0x98,0x62,0x62,0x9e,0xbc,0x36,0x16,0x43,0x70,0x9a,0x0a, -0xa7,0x6d,0xa4,0x98,0x98,0xc7,0xbe,0x8d,0xa4,0x98,0x98,0xc7,0xce,0x0d,0xc6,0x10, -0x9c,0x66,0xc0,0x7b,0x12,0x02,0x32,0xf6,0xe6,0x46,0xe6,0xa2,0x33,0x13,0x73,0x06, -0x8b,0xe0,0x34,0x83,0x2f,0x38,0xcd,0x64,0xd3,0x07,0x50,0x10,0xcd,0x14,0x61,0xe6, -0x61,0x08,0x4e,0x53,0xd5,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, -0x4a,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0xb9,0x61,0x0c,0x04,0x10, -0x1e,0xe1,0x19,0xc6,0x40,0x02,0xe1,0x11,0x1e,0x00,0x00,0x00,0x63,0x08,0xcd,0x63, -0x15,0xc1,0x31,0x84,0x06,0xb2,0x8b,0xe0,0x18,0x42,0x13,0x59,0x46,0x70,0x0c,0xa1, -0x71,0x6c,0x23,0x38,0x16,0x02,0x04,0xc7,0x64,0x61,0x1a,0x37,0x16,0x01,0x04,0x48, -0x35,0xc7,0x20,0x79,0xcf,0x58,0x04,0x10,0x20,0xd5,0x1c,0xc3,0x07,0x06,0xd0,0x58, -0x04,0x10,0x20,0xd5,0x1c,0x43,0x18,0x88,0x41,0x34,0x16,0x01,0x04,0x48,0x35,0xc7, -0x30,0x06,0x64,0xe0,0x98,0x47,0xd0,0xc0,0x80,0xa0,0x89,0x01,0x41,0x23,0x03,0x82, -0x63,0x21,0x40,0x70,0x50,0x66,0x70,0x06,0x68,0x90,0x06,0x58,0x06,0xe1,0x40,0x00, -0x25,0x00,0x00,0x00,0x56,0x52,0x4c,0xcc,0x73,0xd3,0x56,0x41,0x4c,0xcc,0x53,0xdb, -0x05,0x31,0x31,0xcf,0x6d,0x19,0xc4,0xc4,0x3c,0xba,0x6d,0x10,0x13,0xf3,0xf4,0xd6, -0x41,0x08,0xc0,0xb2,0x18,0x46,0x21,0x38,0x4d,0x85,0x9b,0x46,0x21,0x38,0x4d,0xb5, -0x9b,0x8a,0x21,0x00,0xcb,0x82,0xdf,0x66,0x62,0x08,0x4e,0x53,0xdd,0xb7,0x9d,0x18, -0x82,0xd3,0x54,0xb7,0x6e,0x28,0x86,0xe0,0x34,0xd5,0xdd,0xdb,0x47,0x31,0x31,0x4f, -0x9d,0x9b,0x87,0x21,0x00,0xcb,0x52,0xdf,0x06,0x62,0x08,0xc0,0xb2,0xd4,0xbc,0x59, -0x10,0x82,0xd3,0x54,0x96,0x62,0x08,0x4e,0x53,0xe1,0xb6,0x85,0x14,0x13,0xf3,0xd8, -0xb4,0x8d,0x14,0x13,0xf3,0xd8,0xb9,0x89,0x18,0x02,0xb0,0x2c,0xf6,0x6d,0x24,0x86, -0x00,0x2c,0x8b,0xcd,0x1b,0x87,0x21,0x38,0x4d,0x55,0xd3,0xd6,0x30,0x54,0xc0,0x72, -0x00,0x05,0xd1,0x4c,0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, -0x19,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00, -0x24,0x4a,0x60,0x04,0x80,0xc2,0x0c,0x00,0x00,0x00,0x00,0x00,0x63,0x08,0xcd,0x33, -0x16,0x01,0x04,0x48,0x34,0xc7,0x00,0x49,0xcf,0x58,0x04,0x10,0x28,0xd1,0x1c,0xc3, -0x44,0x39,0x58,0x85,0x03,0x01,0x00,0x00,0x0a,0x00,0x00,0x00,0x26,0x41,0x08,0xc0, -0xb2,0x18,0x45,0x21,0x00,0xcb,0xb2,0x5b,0x04,0x31,0x31,0x8f,0x6d,0x13,0xc4,0xc4, -0x3c,0xb9,0x35,0x0c,0x15,0xb0,0x58,0x05,0x31,0x31,0x4f,0x7f,0x00,0x05,0xd1,0x4c, -0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x1b,0x00,0x00,0x00, -0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x24,0xca,0x60,0x04, -0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x00,0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0xca, -0x34,0xc7,0x20,0x51,0xcf,0x1c,0x43,0x45,0x41,0x73,0x0c,0x16,0x15,0xcd,0x31,0x5c, -0x94,0x83,0x58,0x38,0x10,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x76,0x51,0x4c,0xcc, -0x53,0xdb,0x86,0x51,0x4c,0xcc,0x53,0xe7,0x36,0x41,0x4c,0xcc,0x63,0x5b,0x05,0x31, -0x31,0x8f,0x6e,0x16,0xc4,0xc4,0x3c,0xbd,0x51,0x10,0x02,0xb0,0x2c,0xd6,0x30,0x54, -0xc0,0x72,0x00,0x05,0xd1,0x4c,0x11,0x06,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, -0x2c,0x00,0x00,0x00,0x13,0x04,0x45,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00, -0x24,0xca,0xa0,0x04,0x46,0x00,0x8a,0x80,0xc0,0x08,0x00,0x00,0x63,0x08,0x0d,0x34, -0xdc,0x30,0x49,0xc4,0x2c,0x03,0x11,0x50,0x63,0x08,0xcd,0x33,0xdc,0x50,0x49,0xc4, -0x2c,0x03,0x21,0x58,0x63,0x08,0x4d,0x34,0xdc,0x70,0x49,0xc4,0x2c,0x03,0x31,0x60, -0x63,0x08,0x8d,0x33,0xdc,0x90,0x49,0x84,0x69,0x22,0x70,0xc3,0x27,0x1c,0x08,0x00, -0x17,0x00,0x00,0x00,0x96,0x51,0x4c,0xcc,0x53,0xdf,0x66,0x41,0x08,0xcc,0x83,0xdb, -0x04,0x31,0x31,0x4f,0x6d,0x15,0xc4,0xc4,0x3c,0xb7,0x61,0x10,0x02,0xf3,0xf0,0x76, -0x41,0x4c,0xcc,0xb3,0x1f,0x81,0x11,0x11,0x13,0x15,0x35,0x37,0x90,0x2c,0x4e,0xf4, -0x47,0x87,0x54,0xd7,0x17,0x70,0x2c,0x4e,0xf4,0x47,0x87,0x74,0x02,0xc8,0xe2,0x44, -0x7f,0x74,0x48,0xb9,0x69,0x14,0x02,0xf3,0xd4,0xb8,0x6d,0x18,0x11,0x31,0x55,0xc0, -0x62,0x0d,0x43,0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61,0x46,0x31,0x08,0xcc,0x03, -0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x12,0x00,0x00,0x00,0x66,0x40,0x54,0x82, -0x23,0x19,0xc3,0xa0,0x20,0x8b,0x1d,0x18,0x4f,0x84,0x34,0x53,0x61,0x03,0xc4,0xe3, -0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c, -0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84, -0x84,0x34,0x85,0x25,0x0c,0x92,0x20,0x59,0xc1,0x20,0x30,0x8f,0x2d,0x10,0x95,0x84, -0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp deleted file mode 100644 index 1bd00a0c2a..0000000000 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/tgsi_exec.h" -#include "tgsi/tgsi_dump.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include <llvm/Module.h> -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/Instructions.h> -#include <llvm/ModuleProvider.h> -#include <llvm/Pass.h> -#include <llvm/PassManager.h> -#include <llvm/Attributes.h> -#include <llvm/Support/PatternMatch.h> -#include <llvm/ExecutionEngine/JIT.h> -#include <llvm/ExecutionEngine/Interpreter.h> -#include <llvm/ExecutionEngine/GenericValue.h> -#include <llvm/Support/MemoryBuffer.h> -#include <llvm/LinkAllPasses.h> -#include <llvm/Analysis/Verifier.h> -#include <llvm/Analysis/LoopPass.h> -#include <llvm/Target/TargetData.h> -#include <llvm/Bitcode/ReaderWriter.h> -#include <llvm/Transforms/Utils/Cloning.h> - -#include <sstream> -#include <fstream> -#include <iostream> - -struct gallivm_cpu_engine { - llvm::ExecutionEngine *engine; -}; - -static struct gallivm_cpu_engine *CPU = 0; - -typedef int (*fragment_shader_runner)(float x, float y, - float (*dests)[16][4], - float (*inputs)[16][4], - int num_attribs, - float (*consts)[4], int num_consts, - struct tgsi_sampler *samplers); - -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float fx, float fy, - float (*dests)[16][4], - float (*inputs)[16][4], - float (*consts)[4], - struct tgsi_sampler *samplers) -{ - fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function); - assert(runner); - - return runner(fx, fy, dests, inputs, prog->num_interp, - consts, prog->num_consts, - samplers); -} - -static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) -{ - llvm::Module *mod = prog->module; - llvm::Function *func = 0; - - switch (prog->type) { - case GALLIVM_VS: - func = mod->getFunction("vs_shader"); - break; - case GALLIVM_FS: - func = mod->getFunction("fs_shader"); - break; - default: - assert(!"Unknown shader type!"); - break; - } - return func; -} - -/*! - This function creates a CPU based execution engine for the given gallivm_prog. - gallivm_cpu_engine should be used as a singleton throughout the library. Before - executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. - The gallivm_prog instance which is being passed to the constructor is being - automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile - with it again. - */ -struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) -{ - struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) - calloc(1, sizeof(struct gallivm_cpu_engine)); - llvm::Module *mod = static_cast<llvm::Module*>(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); - ee->DisableLazyCompilation(); - cpu->engine = ee; - - llvm::Function *func = func_for_shader(prog); - - prog->function = ee->getPointerToFunction(func); - CPU = cpu; - return cpu; -} - - -/*! - This function JIT compiles the given gallivm_prog with the given cpu based execution engine. - The reference to the generated machine code entry point will be stored - in the gallivm_prog program. After executing this function one can call gallivm_prog_exec - in order to execute the gallivm_prog on the CPU. - */ -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) -{ - llvm::Module *mod = static_cast<llvm::Module*>(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = cpu->engine; - assert(ee); - /*FIXME : why was this disabled ? we need it for pow/sqrt/... */ - ee->DisableLazyCompilation(false); - ee->addModuleProvider(mp); - - llvm::Function *func = func_for_shader(prog); - prog->function = ee->getPointerToFunction(func); -} - -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) -{ - free(cpu); -} - -struct gallivm_cpu_engine * gallivm_global_cpu_engine() -{ - return CPU; -} - - -typedef void (*vertex_shader_runner)(void *ainputs, - void *dests, - float (*aconsts)[4]); - -#define MAX_TGSI_VERTICES 4 -/*! - This function is used to execute the gallivm_prog in software. Before calling - this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile - function. - */ -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_machine *machine, - const float (*input)[4], - unsigned num_inputs, - float (*output)[4], - unsigned num_outputs, - const float (*constants)[4], - unsigned count, - unsigned input_stride, - unsigned output_stride ) -{ - unsigned int i, j; - unsigned slot; - vertex_shader_runner runner = reinterpret_cast<vertex_shader_runner>(prog->function); - assert(runner); - - for (i = 0; i < count; i += MAX_TGSI_VERTICES) { - unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - - /* Swizzle inputs. - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < num_inputs; slot++) { - machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; - machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; - machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; - machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; - } - - input = (const float (*)[4])((const char *)input + input_stride); - } - - /* run shader */ - runner(machine->Inputs, - machine->Outputs, - (float (*)[4]) constants); - - /* Unswizzle all output results - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < num_outputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } - output = (float (*)[4])((char *)output + output_stride); - } - } - - return 0; -} - -#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_p.h b/src/gallium/auxiliary/gallivm/gallivm_p.h deleted file mode 100644 index d2c5852bdf..0000000000 --- a/src/gallium/auxiliary/gallivm/gallivm_p.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef GALLIVM_P_H -#define GALLIVM_P_H - -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_compiler.h" - -namespace llvm { - class Module; -} - -#if defined __cplusplus -extern "C" { -#endif - -enum gallivm_shader_type; -enum gallivm_vector_layout; - -struct gallivm_interpolate { - int attrib; - int chan; - int type; -}; - -struct gallivm_ir { - llvm::Module *module; - int id; - enum gallivm_shader_type type; - enum gallivm_vector_layout layout; - int num_components; - int num_consts; - - /* FIXME: this might not be enough for some shaders */ - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -struct gallivm_prog { - llvm::Module *module; - void *function; - - int id; - enum gallivm_shader_type type; - - int num_consts; - - /* FIXME: this might not be enough for some shaders */ - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -static INLINE void gallivm_swizzle_components(int swizzle, - int *xc, int *yc, - int *zc, int *wc) -{ - int x = swizzle / 1000; swizzle -= x * 1000; - int y = swizzle / 100; swizzle -= y * 100; - int z = swizzle / 10; swizzle -= z * 10; - int w = swizzle; - - if (xc) *xc = x; - if (yc) *yc = y; - if (zc) *zc = z; - if (wc) *wc = w; -} - -static INLINE boolean gallivm_is_swizzle(int swizzle) -{ - const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + - TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; - return swizzle != NO_SWIZZLE; -} - -static INLINE int gallivm_x_swizzle(int swizzle) -{ - int x; - gallivm_swizzle_components(swizzle, &x, 0, 0, 0); - return x; -} - -static INLINE int gallivm_y_swizzle(int swizzle) -{ - int y; - gallivm_swizzle_components(swizzle, 0, &y, 0, 0); - return y; -} - -static INLINE int gallivm_z_swizzle(int swizzle) -{ - int z; - gallivm_swizzle_components(swizzle, 0, 0, &z, 0); - return z; -} - -static INLINE int gallivm_w_swizzle(int swizzle) -{ - int w; - gallivm_swizzle_components(swizzle, 0, 0, 0, &w); - return w; -} - -#if defined __cplusplus -} -#endif - -#endif /* MESA_LLVM */ - -#endif diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp deleted file mode 100644 index ee8162efce..0000000000 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ /dev/null @@ -1,1193 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "instructions.h" - -#include "storage.h" - -#include "util/u_memory.h" - -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/Function.h> -#include <llvm/InstrTypes.h> -#include <llvm/Instructions.h> -#include <llvm/Attributes.h> -#include <llvm/Support/MemoryBuffer.h> -#include <llvm/Bitcode/ReaderWriter.h> - -#include <sstream> -#include <fstream> -#include <iostream> - -using namespace llvm; - -#include "gallivm_builtins.cpp" - -#if 0 -llvm::Value *arrayFromChannels(std::vector<llvm::Value*> &vals) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorArray = ArrayType::get(vectorType, 4); -} -#endif - -static inline std::string createFuncName(int label) -{ - std::ostringstream stream; - stream << "function"; - stream << label; - return stream.str(); -} - -Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage) - : m_mod(mod), m_func(func), m_builder(block), m_idx(0), - m_storage(storage) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - - m_llvmFSqrt = 0; - m_llvmFAbs = 0; - m_llvmPow = 0; - m_llvmFloor = 0; - m_llvmFlog = 0; - m_llvmFexp = 0; - m_llvmLit = 0; - m_fmtPtr = 0; - - MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( - (const char*)&llvm_builtins_data[0], - (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]); - m_mod = ParseBitcodeFile(buffer); -} - -llvm::BasicBlock * Instructions::currentBlock() const -{ - return m_builder.GetInsertBlock(); -} - -llvm::Value * Instructions::abs(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - Value *xabs = callFAbs(vec[0]); - Value *yabs = callFAbs(vec[1]); - Value *zabs = callFAbs(vec[2]); - Value *wabs = callFAbs(vec[3]); - return vectorFromVals(xabs, yabs, zabs, wabs); -} - -llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateAdd(in1, in2, name("add")); -} - -llvm::Value * Instructions::arl(llvm::Value *in) -{ - return floor(in); -} - -void Instructions::beginLoop() -{ - BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0); - BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0); - - m_builder.CreateBr(begin); - Loop loop; - loop.begin = begin; - loop.end = end; - m_builder.SetInsertPoint(begin); - m_loopStack.push(loop); -} - -void Instructions::bgnSub(unsigned label) -{ - llvm::Function *func = findFunction(label); - - Function::arg_iterator args = func->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("INPUT"); - m_storage->pushArguments(ptr_INPUT); - - llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0); - - m_func = func; - m_builder.SetInsertPoint(entry); -} - -void Instructions::brk() -{ - assert(!m_loopStack.empty()); - BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0); - m_builder.CreateBr(m_loopStack.top().end); - m_builder.SetInsertPoint(unr); -} - -void Instructions::cal(int label, llvm::Value *input) -{ - std::vector<Value*> params; - params.push_back(input); - llvm::Function *func = findFunction(label); - - m_builder.CreateCall(func, params.begin(), params.end()); -} - -llvm::Value * Instructions::ceil(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - return vectorFromVals(callCeil(vec[0]), callCeil(vec[1]), - callCeil(vec[2]), callCeil(vec[3])); -} - -llvm::Value * Instructions::clamp(llvm::Value *in1) -{ - llvm::Value *zero = constVector(0.0f, 0.0f, 0.0f, 0.0f); - llvm::Value *one = constVector(1.0f, 1.0f, 1.0f, 1.0f); - return min( max(zero, in1), one); -} - -llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - llvm::Function *func = m_mod->getFunction("cmp"); - assert(func); - - std::vector<Value*> params; - params.push_back(in1); - params.push_back(in2); - params.push_back(in3); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - std::vector<llvm::Value*> vec3 = extractVector(in3); - Constant *half = ConstantFP::get(APFloat(0.5f)); - - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], half, name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], half, name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], half, name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], half, name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::cnd0(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - std::vector<llvm::Value*> vec3 = extractVector(in3); - Constant *zero = Constant::getNullValue(Type::FloatTy); - - Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], zero, name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], zero, name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], zero, name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], zero, name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::cos(llvm::Value *in) -{ -#if 0 - llvm::Function *func = m_mod->getFunction("vcos"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("cosres")); - call->setTailCall(false); - return call; -#else - std::vector<llvm::Value*> elems = extractVector(in); - Function *func = m_mod->getFunction("cosf"); - assert(func); - CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); - cos->setCallingConv(CallingConv::C); - cos->setTailCall(true); - return vectorFromVals(cos, cos, cos, cos); -#endif -} - -llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z1")); - - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *z2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(2), - name("z2")); - Value *y1z2 = mul(y1, z2); - Value *z1y2 = mul(z1, y2); - - Value *z1x2 = mul(z1, x2); - Value *x1z2 = mul(x1, z2); - - Value *x1y2 = mul(x1, y2); - Value *y1x2 = mul(y1, x2); - - return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); -} - -llvm::Value * Instructions::ddx(llvm::Value *in) -{ - // FIXME - assert(0); -} - -llvm::Value * Instructions::ddy(llvm::Value *in) -{ - // FIXME - assert(0); -} - -llvm::Value * Instructions::div(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateFDiv(in1, in2, name("div")); -} - -llvm::Value * Instructions::dot2add(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *z = m_builder.CreateExtractElement(in3, - m_storage->constantInt(2), - name("extractz")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - Value *dot2add = m_builder.CreateAdd(xy, z, name("dot2add")); - return vectorFromVals(dot2add, dot2add, dot2add, dot2add); -} - -llvm::Value * Instructions::dp2(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - return vectorFromVals(xy, xy, xy, xy); -} - -llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *z = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(2), - name("extractz")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); - return vectorFromVals(dot3, dot3, dot3, dot3); -} - -llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector<llvm::Value*> vec = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); - Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); - return vectorFromVals(dot4, dot4, dot4, dot4); -} - -llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector<llvm::Value*> vec1 = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); - Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); - return vectorFromVals(dph, dph, dph, dph); -} - -llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) -{ - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *w = m_builder.CreateExtractElement(in2, - m_storage->constantInt(3), - name("w")); - Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); - return vectorFromVals(ConstantFP::get(APFloat(1.f)), - ry, z, w); -} - -void Instructions::elseop() -{ - assert(!m_ifStack.empty()); - BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0); - m_builder.CreateBr(ifend); - m_builder.SetInsertPoint(m_ifStack.top()); - currentBlock()->setName(name("ifelse")); - m_ifStack.pop(); - m_ifStack.push(ifend); -} - -void Instructions::endif() -{ - assert(!m_ifStack.empty()); - m_builder.CreateBr(m_ifStack.top()); - m_builder.SetInsertPoint(m_ifStack.top()); - m_ifStack.pop(); -} - -void Instructions::endLoop() -{ - assert(!m_loopStack.empty()); - Loop loop = m_loopStack.top(); - m_builder.CreateBr(loop.begin); - loop.end->moveAfter(currentBlock()); - m_builder.SetInsertPoint(loop.end); - m_loopStack.pop(); -} - -void Instructions::end() -{ - m_builder.CreateRetVoid(); -} - -void Instructions::endSub() -{ - m_func = 0; - m_builder.SetInsertPoint(0); -} - -llvm::Value * Instructions::exp(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - return vectorFromVals(callFExp(vec[0]), callFExp(vec[1]), - callFExp(vec[2]), callFExp(vec[3])); -} - -llvm::Value * Instructions::ex2(llvm::Value *in) -{ - llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)), - m_builder.CreateExtractElement( - in, m_storage->constantInt(0), - name("x1"))); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::floor(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), - callFloor(vec[2]), callFloor(vec[3])); -} - -llvm::Value * Instructions::frc(llvm::Value *in) -{ - llvm::Value *flr = floor(in); - return sub(in, flr); -} - -void Instructions::ifop(llvm::Value *in) -{ - BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0); - BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0); - - //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); - //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); - //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); - - Constant *float0 = Constant::getNullValue(Type::FloatTy); - - Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), - name("extractx")); - Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); - m_builder.CreateCondBr(xcmp, ifthen, ifend); - //m_builder.SetInsertPoint(yblock); - - m_builder.SetInsertPoint(ifthen); - m_ifStack.push(ifend); -} - -llvm::Value * Instructions::kil(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("kil"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - llvm::Value *m = mul(in1, in2); - llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); - llvm::Value *s = sub(vec1, in1); - return add(m, mul(s, in3)); -} - -llvm::Value * Instructions::lg2(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - llvm::Value *const_vec = constVector(1.442695f, 1.442695f, - 1.442695f, 1.442695f); - return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), - callFLog(vec[2]), callFLog(vec[3])), const_vec); -} - -llvm::Value * Instructions::lit(llvm::Value *in) -{ - if (!m_llvmLit) { - m_llvmLit = m_mod->getFunction("lit"); - } - CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::log(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - return vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), - callFLog(vec[2]), callFLog(vec[3])); -} - -llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - Value *mulRes = mul(in1, in2); - return add(mulRes, in3); -} - -llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) -{ - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], - name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], - name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], - name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], - name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) -{ - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateMul(in1, in2, name("mul")); -} - -llvm::Value * Instructions::neg(llvm::Value *in) -{ - Value *neg = m_builder.CreateNeg(in, name("neg")); - return neg; -} - -llvm::Value * Instructions::nrm(llvm::Value *in) -{ - llvm::Value *v = rsq(in); - return mul(v, in); -} - -llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - llvm::Value *val = callPow(x1, x2); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::rcp(llvm::Value *in1) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)), - x1, name("rcp")); - return vectorFromVals(res, res, res, res); -} - -llvm::Value * Instructions::rsq(llvm::Value *in1) -{ - Value *x = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("extractx")); - Value *abs = callFAbs(x); - Value *sqrt = callFSqrt(abs); - - Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)), - sqrt, - name("rsqrt")); - return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); -} - -llvm::Value * Instructions::scs(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("scs"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("scsres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::seq(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOEQ(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOEQ(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOEQ(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOEQ(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::sfl(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - return vectorFromVals(const0f, const0f, const0f, const0f); -} - -llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::sin(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("vsin"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("sinres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sle(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOLE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOLE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOLE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::sne(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpONE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpONE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpONE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpONE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::str(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); - - return vectorFromVals(const1f, const1f, const1f, const1f); -} - -llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) -{ - Value *res = m_builder.CreateSub(in1, in2, name("sub")); - return res; -} - -llvm::Value * Instructions::trunc(llvm::Value *in) -{ - std::vector<llvm::Value*> vec = extractVector(in); - Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), - name("ftoix")); - Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), - name("ftoiy")); - Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), - name("ftoiz")); - Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), - name("ftoiw")); - Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, - name("fx")); - Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, - name("fy")); - Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, - name("fz")); - Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, - name("fw")); - return vectorFromVals(fx, fy, fz, fw); -} - -llvm::Value * Instructions::x2d(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - std::vector<llvm::Value*> vec1 = extractVector(in1); - std::vector<llvm::Value*> vec2 = extractVector(in2); - std::vector<llvm::Value*> vec3 = extractVector(in3); - - Value *x2x3 = m_builder.CreateMul( vec2[0], vec3[0], name("x2x3")); - Value *y2y3 = m_builder.CreateMul( vec2[1], vec3[1], name("y2y3")); - Value *x1px2x3 = m_builder.CreateAdd (vec1[0], x2x3, name("x1 + x2x3")); - Value *x1px2x3py2y3 = m_builder.CreateAdd (x1px2x3, y2y3, name("x1 + x2x3 + y2y3")); - - Value *x2z3 = m_builder.CreateMul( vec2[0], vec3[2], name("x2z3")); - Value *y2w3 = m_builder.CreateMul( vec2[1], vec3[3], name("y2w3")); - Value *y1px2z3 = m_builder.CreateAdd (vec1[1], x2z3, name("y1 + x2z3")); - Value *y1px2z3py2w3 = m_builder.CreateAdd (y1px2z3, y2w3, name("y1 + x2z3 + y2w3")); - - return vectorFromVals(x1px2x3py2y3, y1px2z3py2w3, x1px2x3py2y3, y1px2z3py2w3); -} - -void Instructions::printVector(llvm::Value *val) -{ - static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; - - if (!m_fmtPtr) { - Constant *format = ConstantArray::get(frmt, true); - ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); - GlobalVariable* globalFormat = new GlobalVariable( - /*Type=*/arrayTy, - /*isConstant=*/true, - /*Linkage=*/GlobalValue::InternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name(".str"), - m_mod); - globalFormat->setInitializer(format); - - Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); - std::vector<Constant*> const_ptr_21_indices; - const_ptr_21_indices.push_back(const_int0); - const_ptr_21_indices.push_back(const_int0); - m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, - &const_ptr_21_indices[0], const_ptr_21_indices.size()); - } - - Function *func_printf = m_mod->getFunction("printf"); - if (!func_printf) - func_printf = declarePrintf(); - assert(func_printf); - std::vector<llvm::Value*> vec = extractVector(val); - Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); - Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); - Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); - Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); - std::vector<Value*> params; - params.push_back(m_fmtPtr); - params.push_back(dx); - params.push_back(dy); - params.push_back(dz); - params.push_back(dw); - CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), - name("printf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(true); -} - -const char * Instructions::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * Instructions::callCeil(llvm::Value *val) -{ - if (!m_llvmCeil) { - // predeclare the intrinsic - std::vector<const Type*> ceilArgs; - ceilArgs.push_back(Type::FloatTy); - AttrListPtr ceilPal; - FunctionType* ceilType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/ceilArgs, - /*isVarArg=*/false); - m_llvmCeil = Function::Create( - /*Type=*/ceilType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"ceilf", m_mod); - m_llvmCeil->setCallingConv(CallingConv::C); - m_llvmCeil->setAttributes(ceilPal); - } - CallInst *call = m_builder.CreateCall(m_llvmCeil, val, - name("ceilf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value *Instructions::callFAbs(llvm::Value *val) -{ - if (!m_llvmFAbs) { - // predeclare the intrinsic - std::vector<const Type*> fabsArgs; - fabsArgs.push_back(Type::FloatTy); - AttrListPtr fabsPal; - FunctionType* fabsType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fabsArgs, - /*isVarArg=*/false); - m_llvmFAbs = Function::Create( - /*Type=*/fabsType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"fabs", m_mod); - m_llvmFAbs->setCallingConv(CallingConv::C); - m_llvmFAbs->setAttributes(fabsPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, - name("fabs")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::callFExp(llvm::Value *val) -{ - if (!m_llvmFexp) { - // predeclare the intrinsic - std::vector<const Type*> fexpArgs; - fexpArgs.push_back(Type::FloatTy); - AttrListPtr fexpPal; - FunctionType* fexpType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fexpArgs, - /*isVarArg=*/false); - m_llvmFexp = Function::Create( - /*Type=*/fexpType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"expf", m_mod); - m_llvmFexp->setCallingConv(CallingConv::C); - m_llvmFexp->setAttributes(fexpPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFexp, val, - name("expf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::callFLog(llvm::Value *val) -{ - if (!m_llvmFlog) { - // predeclare the intrinsic - std::vector<const Type*> flogArgs; - flogArgs.push_back(Type::FloatTy); - AttrListPtr flogPal; - FunctionType* flogType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/flogArgs, - /*isVarArg=*/false); - m_llvmFlog = Function::Create( - /*Type=*/flogType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"logf", m_mod); - m_llvmFlog->setCallingConv(CallingConv::C); - m_llvmFlog->setAttributes(flogPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFlog, val, - name("logf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::callFloor(llvm::Value *val) -{ - if (!m_llvmFloor) { - // predeclare the intrinsic - std::vector<const Type*> floorArgs; - floorArgs.push_back(Type::FloatTy); - AttrListPtr floorPal; - FunctionType* floorType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/floorArgs, - /*isVarArg=*/false); - m_llvmFloor = Function::Create( - /*Type=*/floorType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"floorf", m_mod); - m_llvmFloor->setCallingConv(CallingConv::C); - m_llvmFloor->setAttributes(floorPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFloor, val, - name("floorf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value *Instructions::callFSqrt(llvm::Value *val) -{ - if (!m_llvmFSqrt) { - // predeclare the intrinsic - std::vector<const Type*> fsqrtArgs; - fsqrtArgs.push_back(Type::FloatTy); - AttrListPtr fsqrtPal; - FunctionType* fsqrtType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fsqrtArgs, - /*isVarArg=*/false); - m_llvmFSqrt = Function::Create( - /*Type=*/fsqrtType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.sqrt.f32", m_mod); - m_llvmFSqrt->setCallingConv(CallingConv::C); - m_llvmFSqrt->setAttributes(fsqrtPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, - name("sqrt")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) -{ - if (!m_llvmPow) { - // predeclare the intrinsic - std::vector<const Type*> powArgs; - powArgs.push_back(Type::FloatTy); - powArgs.push_back(Type::FloatTy); - AttrListPtr powPal; - FunctionType* powType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/powArgs, - /*isVarArg=*/false); - m_llvmPow = Function::Create( - /*Type=*/powType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.pow.f32", m_mod); - m_llvmPow->setCallingConv(CallingConv::C); - m_llvmPow->setAttributes(powPal); - } - std::vector<Value*> params; - params.push_back(val1); - params.push_back(val2); - CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), - name("pow")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - Constant *const_vec = Constant::getNullValue(m_floatVecType); - Value *res = m_builder.CreateInsertElement(const_vec, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -llvm::Value * Instructions::constVector(float x, float y, float z, float w) -{ - std::vector<Constant*> vec(4); - vec[0] = ConstantFP::get(APFloat(x)); - vec[1] = ConstantFP::get(APFloat(y)); - vec[2] = ConstantFP::get(APFloat(z)); - vec[3] = ConstantFP::get(APFloat(w)); - return ConstantVector::get(m_floatVecType, vec); -} - -llvm::Function * Instructions::declarePrintf() -{ - std::vector<const Type*> args; - AttrListPtr params; - FunctionType* funcTy = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/args, - /*isVarArg=*/true); - Function* func_printf = Function::Create( - /*Type=*/funcTy, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", m_mod); - func_printf->setCallingConv(CallingConv::C); - func_printf->setAttributes(params); - return func_printf; -} - -llvm::Function * Instructions::declareFunc(int label) -{ - PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); - std::vector<const Type*> args; - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - AttrListPtr params; - FunctionType *funcType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/args, - /*isVarArg=*/false); - std::string name = createFuncName(label); - Function *func = Function::Create( - /*Type=*/funcType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/name.c_str(), m_mod); - func->setCallingConv(CallingConv::C); - func->setAttributes(params); - return func; -} - -llvm::Function * Instructions::findFunction(int label) -{ - llvm::Function *func = m_functions[label]; - if (!func) { - func = declareFunc(label); - m_functions[label] = func; - } - return func; -} - -std::vector<llvm::Value*> Instructions::extractVector(llvm::Value *vec) -{ - std::vector<llvm::Value*> elems(4); - elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), - name("x")); - elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), - name("y")); - elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), - name("z")); - elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), - name("w")); - return elems; -} - - -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h deleted file mode 100644 index e18571251e..0000000000 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ /dev/null @@ -1,175 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef INSTRUCTIONS_H -#define INSTRUCTIONS_H - -#include <llvm/BasicBlock.h> -#include <llvm/Module.h> -#include <llvm/Value.h> -#include <llvm/Support/IRBuilder.h> - -#include <map> -#include <stack> - -namespace llvm { - class VectorType; - class Function; -} - -class Storage; - -class Instructions -{ -public: - Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage); - - llvm::BasicBlock *currentBlock() const; - - llvm::Value *abs(llvm::Value *in1); - llvm::Value *add(llvm::Value *in1, llvm::Value *in2); - llvm::Value *arl(llvm::Value *in1); - void beginLoop(); - void bgnSub(unsigned); - void brk(); - void cal(int label, llvm::Value *input); - llvm::Value *ceil(llvm::Value *in); - llvm::Value *clamp(llvm::Value *in); - llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cnd0(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cos(llvm::Value *in); - llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); - llvm::Value *ddx(llvm::Value *in); - llvm::Value *ddy(llvm::Value *in); - llvm::Value *div(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dot2add(llvm::Value *in, llvm::Value *in2, llvm::Value *in3); - llvm::Value *dp2(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); - void elseop(); - void endif(); - void endLoop(); - void end(); - void endSub(); - llvm::Value *exp(llvm::Value *in); - llvm::Value *ex2(llvm::Value *in); - llvm::Value *floor(llvm::Value *in); - llvm::Value *frc(llvm::Value *in); - void ifop(llvm::Value *in); - llvm::Value *kil(llvm::Value *in); - llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3); - llvm::Value *lg2(llvm::Value *in); - llvm::Value *lit(llvm::Value *in); - llvm::Value *log(llvm::Value *in); - llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3); - llvm::Value *max(llvm::Value *in1, llvm::Value *in2); - llvm::Value *min(llvm::Value *in1, llvm::Value *in2); - llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); - llvm::Value *neg(llvm::Value *in); - llvm::Value *nrm(llvm::Value *in); - llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); - llvm::Value *rcp(llvm::Value *in); - llvm::Value *rsq(llvm::Value *in); - llvm::Value *scs(llvm::Value *in); - llvm::Value *seq(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sfl(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sin(llvm::Value *in); - llvm::Value *sle(llvm::Value *in1, llvm::Value *in2); - llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sne(llvm::Value *in1, llvm::Value *in2); - llvm::Value *str(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); - llvm::Value *trunc(llvm::Value *in); - llvm::Value *x2d(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - - void printVector(llvm::Value *val); -private: - const char *name(const char *prefix); - - llvm::Value *callCeil(llvm::Value *val); - llvm::Value *callFAbs(llvm::Value *val); - llvm::Value *callFExp(llvm::Value *val); - llvm::Value *callFLog(llvm::Value *val); - llvm::Value *callFloor(llvm::Value *val); - llvm::Value *callFSqrt(llvm::Value *val); - llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); - - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w=0); - - llvm::Value *constVector(float x, float y, float z, float w); - - llvm::Function *declarePrintf(); - llvm::Function *declareFunc(int label); - - llvm::Function *findFunction(int label); - - std::vector<llvm::Value*> extractVector(llvm::Value *vec); -private: - llvm::Module *m_mod; - llvm::Function *m_func; - char m_name[32]; - llvm::IRBuilder<> m_builder; - int m_idx; - - llvm::VectorType *m_floatVecType; - - llvm::Function *m_llvmCeil; - llvm::Function *m_llvmFSqrt; - llvm::Function *m_llvmFAbs; - llvm::Function *m_llvmPow; - llvm::Function *m_llvmFloor; - llvm::Function *m_llvmFlog; - llvm::Function *m_llvmFexp; - llvm::Function *m_llvmLit; - - llvm::Constant *m_fmtPtr; - - std::stack<llvm::BasicBlock*> m_ifStack; - struct Loop { - llvm::BasicBlock *begin; - llvm::BasicBlock *end; - }; - std::stack<Loop> m_loopStack; - std::map<int, llvm::Function*> m_functions; - Storage *m_storage; -}; - -#endif diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp deleted file mode 100644 index 721b7d2d83..0000000000 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ /dev/null @@ -1,525 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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 <cstdio> -#include "instructionssoa.h" - -#include "storagesoa.h" - -#include "pipe/p_shader_tokens.h" -#include "util/u_memory.h" - -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/Module.h> -#include <llvm/Function.h> -#include <llvm/Instructions.h> -#include <llvm/Transforms/Utils/Cloning.h> -#include <llvm/Attributes.h> -#include <llvm/Support/MemoryBuffer.h> -#include <llvm/Bitcode/ReaderWriter.h> - - -#include <iostream> - - -/* disable some warnings. this file is autogenerated */ -#if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif -using namespace llvm; -#include "gallivmsoabuiltins.cpp" -#if defined(__GNUC__) -#pragma GCC diagnostic warning "-Wunused-variable" -#endif - -InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage) - : m_builder(block), - m_storage(storage), - m_idx(0) -{ - createFunctionMap(); - createBuiltins(); -} - -const char * InstructionsSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - Constant *constVector = Constant::getNullValue(vectorType); - Value *res = m_builder.CreateInsertElement(constVector, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -void InstructionsSoa::end() -{ - m_builder.CreateRetVoid(); -} - -std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector) -{ - std::vector<llvm::Value*> res(4); - res[0] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(0), - name("extract1X")); - res[1] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(1), - name("extract2X")); - res[2] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(2), - name("extract3X")); - res[3] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(3), - name("extract4X")); - - return res; -} - -llvm::IRBuilder<>* InstructionsSoa::getIRBuilder() -{ - return &m_builder; -} - -void InstructionsSoa::createFunctionMap() -{ - m_functionsMap[TGSI_OPCODE_ABS] = "abs"; - m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; - m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; - m_functionsMap[TGSI_OPCODE_MIN] = "min"; - m_functionsMap[TGSI_OPCODE_MAX] = "max"; - m_functionsMap[TGSI_OPCODE_POW] = "pow"; - m_functionsMap[TGSI_OPCODE_LIT] = "lit"; - m_functionsMap[TGSI_OPCODE_RSQ] = "rsq"; - m_functionsMap[TGSI_OPCODE_SLT] = "slt"; -} - -void InstructionsSoa::createDependencies() -{ - { - std::vector<std::string> powDeps(2); - powDeps[0] = "powf"; - powDeps[1] = "powvec"; - m_builtinDependencies["pow"] = powDeps; - } - { - std::vector<std::string> absDeps(2); - absDeps[0] = "fabsf"; - absDeps[1] = "absvec"; - m_builtinDependencies["abs"] = absDeps; - } - { - std::vector<std::string> maxDeps(1); - maxDeps[0] = "maxvec"; - m_builtinDependencies["max"] = maxDeps; - } - { - std::vector<std::string> minDeps(1); - minDeps[0] = "minvec"; - m_builtinDependencies["min"] = minDeps; - } - { - std::vector<std::string> litDeps(4); - litDeps[0] = "minvec"; - litDeps[1] = "maxvec"; - litDeps[2] = "powf"; - litDeps[3] = "powvec"; - m_builtinDependencies["lit"] = litDeps; - } - { - std::vector<std::string> rsqDeps(4); - rsqDeps[0] = "sqrtf"; - rsqDeps[1] = "sqrtvec"; - rsqDeps[2] = "fabsf"; - rsqDeps[3] = "absvec"; - m_builtinDependencies["rsq"] = rsqDeps; - } -} - -llvm::Function * InstructionsSoa::function(int op) -{ - if (m_functions.find(op) != m_functions.end()) - return m_functions[op]; - - std::string name = m_functionsMap[op]; - - std::cout <<"For op = "<<op<<", func is '"<<name<<"'"<<std::endl; - - std::vector<std::string> deps = m_builtinDependencies[name]; - for (unsigned int i = 0; i < deps.size(); ++i) { - llvm::Function *func = m_builtins->getFunction(deps[i]); - std::cout <<"\tinjecting dep = '"<<func->getName()<<"'"<<std::endl; - injectFunction(func); - } - - llvm::Function *originalFunc = m_builtins->getFunction(name); - injectFunction(originalFunc, op); - return m_functions[op]; -} - -llvm::Module * InstructionsSoa::currentModule() const -{ - BasicBlock *block = m_builder.GetInsertBlock(); - if (!block || !block->getParent()) - return 0; - - return block->getParent()->getParent(); -} - -void InstructionsSoa::createBuiltins() -{ - std::string ErrMsg; - MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( - (const char*)&soabuiltins_data[0], - (const char*)&soabuiltins_data[Elements(soabuiltins_data) - 1]); - m_builtins = ParseBitcodeFile(buffer, &ErrMsg); - std::cout<<"Builtins created at "<<m_builtins<<" ("<<ErrMsg<<")"<<std::endl; - assert(m_builtins); - createDependencies(); -} - - -std::vector<llvm::Value*> InstructionsSoa::abs(const std::vector<llvm::Value*> in1) -{ - llvm::Function *func = function(TGSI_OPCODE_ABS); - return callBuiltin(func, in1); -} - -std::vector<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - std::vector<llvm::Value*> res(4); - - res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); - res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); - res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); - res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); - - return res; -} - -std::vector<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in) -{ - std::vector<llvm::Value*> res(4); - - //Extract x's - llvm::Value *x1 = m_builder.CreateExtractElement(in[0], - m_storage->constantInt(0), - name("extractX")); - //cast it to an unsigned int - x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); - - res[0] = x1;//vectorFromVals(x1, x2, x3, x4); - //only x is valid. the others shouldn't be necessary - /* - res[1] = Constant::getNullValue(m_floatVecType); - res[2] = Constant::getNullValue(m_floatVecType); - res[3] = Constant::getNullValue(m_floatVecType); - */ - - return res; -} - -std::vector<llvm::Value*> InstructionsSoa::dp3(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_DP3); - return callBuiltin(func, in1, in2); -} - -std::vector<llvm::Value*> InstructionsSoa::lit(const std::vector<llvm::Value*> in) -{ - llvm::Function *func = function(TGSI_OPCODE_LIT); - return callBuiltin(func, in); -} - -std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2, - const std::vector<llvm::Value*> in3) -{ - std::vector<llvm::Value*> res = mul(in1, in2); - return add(res, in3); -} - -std::vector<llvm::Value*> InstructionsSoa::max(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_MAX); - return callBuiltin(func, in1, in2); -} - -std::vector<llvm::Value*> InstructionsSoa::min(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_MIN); - return callBuiltin(func, in1, in2); -} - -std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - std::vector<llvm::Value*> res(4); - - res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); - res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); - res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); - res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); - - return res; -} - -std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_POW); - return callBuiltin(func, in1, in2); -} - -std::vector<llvm::Value*> InstructionsSoa::rsq(const std::vector<llvm::Value*> in) -{ - llvm::Function *func = function(TGSI_OPCODE_RSQ); - return callBuiltin(func, in); -} - -std::vector<llvm::Value*> InstructionsSoa::slt(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_SLT); - return callBuiltin(func, in1, in2); -} - -std::vector<llvm::Value*> InstructionsSoa::sub(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - std::vector<llvm::Value*> res(4); - - res[0] = m_builder.CreateSub(in1[0], in2[0], name("subx")); - res[1] = m_builder.CreateSub(in1[1], in2[1], name("suby")); - res[2] = m_builder.CreateSub(in1[2], in2[2], name("subz")); - res[3] = m_builder.CreateSub(in1[3], in2[3], name("subw")); - - return res; -} - -void checkFunction(Function *func) -{ - for (Function::const_iterator BI = func->begin(), BE = func->end(); - BI != BE; ++BI) { - const BasicBlock &BB = *BI; - for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end(); - II != IE; ++II) { - const Instruction &I = *II; - std::cout<< "Instr = "<<I; - for (unsigned op = 0, E = I.getNumOperands(); op != E; ++op) { - const Value *Op = I.getOperand(op); - std::cout<< "\top = "<<Op<<"("<<op<<")"<<std::endl; - //I->setOperand(op, V); - } - } - } -} - -llvm::Value * InstructionsSoa::allocaTemp() -{ - VectorType *vector = VectorType::get(Type::FloatTy, 4); - ArrayType *vecArray = ArrayType::get(vector, 4); - AllocaInst *alloca = new AllocaInst(vecArray, name("tmpRes"), - m_builder.GetInsertBlock()); - - std::vector<Value*> indices; - indices.push_back(m_storage->constantInt(0)); - indices.push_back(m_storage->constantInt(0)); - GetElementPtrInst *getElem = GetElementPtrInst::Create(alloca, - indices.begin(), - indices.end(), - name("allocaPtr"), - m_builder.GetInsertBlock()); - return getElem; -} - -std::vector<llvm::Value*> InstructionsSoa::allocaToResult(llvm::Value *allocaPtr) -{ - GetElementPtrInst *xElemPtr = GetElementPtrInst::Create(allocaPtr, - m_storage->constantInt(0), - name("xPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *yElemPtr = GetElementPtrInst::Create(allocaPtr, - m_storage->constantInt(1), - name("yPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *zElemPtr = GetElementPtrInst::Create(allocaPtr, - m_storage->constantInt(2), - name("zPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *wElemPtr = GetElementPtrInst::Create(allocaPtr, - m_storage->constantInt(3), - name("wPtr"), - m_builder.GetInsertBlock()); - - std::vector<llvm::Value*> res(4); - res[0] = new LoadInst(xElemPtr, name("xRes"), false, m_builder.GetInsertBlock()); - res[1] = new LoadInst(yElemPtr, name("yRes"), false, m_builder.GetInsertBlock()); - res[2] = new LoadInst(zElemPtr, name("zRes"), false, m_builder.GetInsertBlock()); - res[3] = new LoadInst(wElemPtr, name("wRes"), false, m_builder.GetInsertBlock()); - - return res; -} - -std::vector<llvm::Value*> InstructionsSoa::dp4(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - llvm::Function *func = function(TGSI_OPCODE_DP4); - return callBuiltin(func, in1, in2); -} - -std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1) -{ - std::vector<Value*> params; - - llvm::Value *allocaPtr = allocaTemp(); - params.push_back(allocaPtr); - params.push_back(in1[0]); - params.push_back(in1[1]); - params.push_back(in1[2]); - params.push_back(in1[3]); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - - return allocaToResult(allocaPtr); -} - -std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2) -{ - std::vector<Value*> params; - - llvm::Value *allocaPtr = allocaTemp(); - params.push_back(allocaPtr); - params.push_back(in1[0]); - params.push_back(in1[1]); - params.push_back(in1[2]); - params.push_back(in1[3]); - params.push_back(in2[0]); - params.push_back(in2[1]); - params.push_back(in2[2]); - params.push_back(in2[3]); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - - return allocaToResult(allocaPtr); -} - -std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2, - const std::vector<llvm::Value*> in3) -{ - std::vector<Value*> params; - - llvm::Value *allocaPtr = allocaTemp(); - params.push_back(allocaPtr); - params.push_back(in1[0]); - params.push_back(in1[1]); - params.push_back(in1[2]); - params.push_back(in1[3]); - params.push_back(in2[0]); - params.push_back(in2[1]); - params.push_back(in2[2]); - params.push_back(in2[3]); - params.push_back(in3[0]); - params.push_back(in3[1]); - params.push_back(in3[2]); - params.push_back(in3[3]); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - - return allocaToResult(allocaPtr); -} - -void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) -{ - assert(originalFunc); - std::cout << "injecting function originalFunc " <<originalFunc->getName() <<std::endl; - if (op != TGSI_OPCODE_LAST) { - /* in this case it's possible the function has been already - * injected as part of the dependency chain, which gets - * injected below */ - llvm::Function *func = currentModule()->getFunction(originalFunc->getName()); - if (func) { - m_functions[op] = func; - return; - } - } - llvm::Function *func = 0; - if (originalFunc->isDeclaration()) { - func = Function::Create(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage, - originalFunc->getName(), currentModule()); - func->setCallingConv(CallingConv::C); - const AttrListPtr pal; - func->setAttributes(pal); - currentModule()->dump(); - } else { - DenseMap<const Value*, Value *> val; - val[m_builtins->getFunction("fabsf")] = currentModule()->getFunction("fabsf"); - val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf"); - val[m_builtins->getFunction("sqrtf")] = currentModule()->getFunction("sqrtf"); - func = CloneFunction(originalFunc, val); -#if 0 - std::cout <<" replacing "<<m_builtins->getFunction("powf") - <<", with " <<currentModule()->getFunction("powf")<<std::endl; - std::cout<<"1111-------------------------------"<<std::endl; - checkFunction(originalFunc); - std::cout<<"2222-------------------------------"<<std::endl; - checkFunction(func); - std::cout <<"XXXX = " <<val[m_builtins->getFunction("powf")]<<std::endl; -#endif - currentModule()->getFunctionList().push_back(func); - } - if (op != TGSI_OPCODE_LAST) { - m_functions[op] = func; - } -} - - diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h deleted file mode 100644 index d6831e0a6b..0000000000 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -#ifndef INSTRUCTIONSSOA_H -#define INSTRUCTIONSSOA_H - -#include <pipe/p_shader_tokens.h> -#include <llvm/Support/IRBuilder.h> - -#include <map> -#include <vector> - -namespace llvm { - class Module; - class Function; - class BasicBlock; - class Value; -} -class StorageSoa; - -class InstructionsSoa -{ -public: - InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage); - - std::vector<llvm::Value*> abs(const std::vector<llvm::Value*> in1); - std::vector<llvm::Value*> arl(const std::vector<llvm::Value*> in); - std::vector<llvm::Value*> add(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> dp3(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> dp4(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> lit(const std::vector<llvm::Value*> in); - std::vector<llvm::Value*> madd(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2, - const std::vector<llvm::Value*> in3); - std::vector<llvm::Value*> max(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> min(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> mul(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> pow(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> rsq(const std::vector<llvm::Value*> in1); - std::vector<llvm::Value*> slt(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> sub(const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - void end(); - - std::vector<llvm::Value*> extractVector(llvm::Value *vector); - llvm::IRBuilder<>* getIRBuilder(); -private: - const char * name(const char *prefix) const; - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w); - void createFunctionMap(); - void createBuiltins(); - void createDependencies(); - llvm::Function *function(int); - llvm::Module *currentModule() const; - llvm::Value *allocaTemp(); - std::vector<llvm::Value*> allocaToResult(llvm::Value *allocaPtr); - std::vector<llvm::Value*> callBuiltin(llvm::Function *func, - const std::vector<llvm::Value*> in1); - std::vector<llvm::Value*> callBuiltin(llvm::Function *func, - const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2); - std::vector<llvm::Value*> callBuiltin(llvm::Function *func, - const std::vector<llvm::Value*> in1, - const std::vector<llvm::Value*> in2, - const std::vector<llvm::Value*> in3); - void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST); -private: - llvm::IRBuilder<> m_builder; - StorageSoa *m_storage; - - std::map<int, std::string> m_functionsMap; - std::map<int, llvm::Function*> m_functions; - llvm::Module *m_builtins; - std::map<std::string, std::vector<std::string> > m_builtinDependencies; - -private: - mutable int m_idx; - mutable char m_name[32]; -}; - - -#endif diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c deleted file mode 100644 index d5a003a48b..0000000000 --- a/src/gallium/auxiliary/gallivm/llvm_builtins.c +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -typedef __attribute__(( ext_vector_type(4) )) float float4; - -extern float powf(float a, float b); - -inline float approx(float a, float b) -{ - if (b < -128.0f) b = -128.0f; - if (b > 128.0f) b = 128.0f; - if (a < 0) a = 0; - return powf(a, b); -} - -inline float4 lit(float4 tmp) -{ - float4 result; - result.x = 1.0; - result.w = 1.0; - if (tmp.x > 0) { - result.y = tmp.x; - result.z = approx(tmp.y, tmp.w); - } else { - result.y = 0; - result.z = 0; - } - return result; -} - -inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) -{ - float4 result; - - result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; - result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; - result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; - result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; - - return result; -} - -extern float cosf(float val); -extern float sinf(float val); - -inline float4 vcos(float4 val) -{ - float4 result; - printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); - result.x = cosf(val.x); - result.y = cosf(val.x); - result.z = cosf(val.x); - result.w = cosf(val.x); - printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); - return result; -} - -inline float4 scs(float4 val) -{ - float4 result; - float tmp = val.x; - result.x = cosf(tmp); - result.y = sinf(tmp); - return result; -} - - -inline float4 vsin(float4 val) -{ - float4 result; - float tmp = val.x; - float res = sinf(tmp); - result.x = res; - result.y = res; - result.z = res; - result.w = res; - return result; -} - -inline int kil(float4 val) -{ - if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) - return 1; - else - return 0; -} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.cpp b/src/gallium/auxiliary/gallivm/loweringpass.cpp deleted file mode 100644 index 556dbec366..0000000000 --- a/src/gallium/auxiliary/gallivm/loweringpass.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "loweringpass.h" - -using namespace llvm; - -char LoweringPass::ID = 0; -RegisterPass<LoweringPass> X("lowering", "Lowering Pass"); - -LoweringPass::LoweringPass() - : ModulePass((intptr_t)&ID) -{ -} - -bool LoweringPass::runOnModule(Module &m) -{ - llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; - return false; -} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.h b/src/gallium/auxiliary/gallivm/loweringpass.h deleted file mode 100644 index f62dcf6ba7..0000000000 --- a/src/gallium/auxiliary/gallivm/loweringpass.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LOWERINGPASS_H -#define LOWERINGPASS_H - -#include "llvm/Pass.h" -#include "llvm/Module.h" - -struct LoweringPass : public llvm::ModulePass -{ - static char ID; - LoweringPass(); - - virtual bool runOnModule(llvm::Module &m); -}; - -#endif diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/auxiliary/gallivm/lp_bld_alpha.c index 2b4bc5c819..7245730350 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_alpha.c @@ -35,7 +35,6 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_arit.h" #include "lp_bld_logic.h" #include "lp_bld_flow.h" #include "lp_bld_debug.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h index 634575670d..634575670d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index eea6b5d6a5..54b31befe6 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -629,7 +629,7 @@ lp_build_abs(struct lp_build_context *bld, if(type.floating) { /* Mask out the sign bit */ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - unsigned long absMask = ~(1 << (type.width - 1)); + unsigned long long absMask = ~(1ULL << (type.width - 1)); LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask)); a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); a = LLVMBuildAnd(bld->builder, a, mask, ""); @@ -874,6 +874,9 @@ lp_build_iround(struct lp_build_context *bld, } +/** + * Convert float[] to int[] with floor(). + */ LLVMValueRef lp_build_ifloor(struct lp_build_context *bld, LLVMValueRef a) @@ -900,6 +903,7 @@ lp_build_ifloor(struct lp_build_context *bld, sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); sign = LLVMBuildAnd(bld->builder, sign, mask, ""); sign = LLVMBuildAShr(bld->builder, sign, lp_build_int_const_scalar(type, type.width - 1), ""); + lp_build_name(sign, "floor.sign"); /* offset = -0.99999(9)f */ offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa)); @@ -908,11 +912,14 @@ lp_build_ifloor(struct lp_build_context *bld, /* offset = a < 0 ? -0.99999(9)f : 0.0f */ offset = LLVMBuildAnd(bld->builder, offset, sign, ""); offset = LLVMBuildBitCast(bld->builder, offset, vec_type, ""); + lp_build_name(offset, "floor.offset"); res = LLVMBuildAdd(bld->builder, a, offset, ""); + lp_build_name(res, "floor.res"); } res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, ""); + lp_build_name(res, "floor"); return res; } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h index 62be4b9aee..62be4b9aee 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/auxiliary/gallivm/lp_bld_blend.h index da272e549f..da272e549f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_blend.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_blend_aos.c index ced7b9c11d..0215bb72ac 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_blend_aos.c @@ -44,6 +44,7 @@ #include "pipe/p_state.h" +#include "util/u_debug.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -314,9 +315,10 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef dst_term; /* FIXME */ - assert(blend->colormask == 0xf); + assert(blend->independent_blend_enable == 0); + assert(blend->rt[0].colormask == 0xf); - if(!blend->blend_enable) + if(!blend->rt[0].blend_enable) return src; /* It makes no sense to blend unless values are normalized */ @@ -333,14 +335,16 @@ lp_build_blend_aos(LLVMBuilderRef builder, * combinations it is possible to reorder the operations and therefore saving * some instructions. */ - src_term = lp_build_blend_factor(&bld, src, blend->rgb_src_factor, blend->alpha_src_factor, alpha_swizzle); - dst_term = lp_build_blend_factor(&bld, dst, blend->rgb_dst_factor, blend->alpha_dst_factor, alpha_swizzle); + src_term = lp_build_blend_factor(&bld, src, blend->rt[0].rgb_src_factor, + blend->rt[0].alpha_src_factor, alpha_swizzle); + dst_term = lp_build_blend_factor(&bld, dst, blend->rt[0].rgb_dst_factor, + blend->rt[0].alpha_dst_factor, alpha_swizzle); lp_build_name(src_term, "src_term"); lp_build_name(dst_term, "dst_term"); - if(blend->rgb_func == blend->alpha_func) { - return lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term); + if(blend->rt[0].rgb_func == blend->rt[0].alpha_func) { + return lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); } else { /* Seperate RGB / A functions */ @@ -348,8 +352,8 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef rgb; LLVMValueRef alpha; - rgb = lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term); - alpha = lp_build_blend_func(&bld.base, blend->alpha_func, src_term, dst_term); + rgb = lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); + alpha = lp_build_blend_func(&bld.base, blend->rt[0].alpha_func, src_term, dst_term); return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c b/src/gallium/auxiliary/gallivm/lp_bld_blend_logicop.c index 88321f62a2..1eac0a5c89 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_blend_logicop.c @@ -35,6 +35,7 @@ #include "pipe/p_state.h" +#include "util/u_debug.h" #include "lp_bld_blend.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_blend_soa.c index 9511299d55..6d5a45db7a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_blend_soa.c @@ -69,9 +69,9 @@ #include "pipe/p_state.h" +#include "util/u_debug.h" #include "lp_bld_type.h" -#include "lp_bld_const.h" #include "lp_bld_arit.h" #include "lp_bld_blend.h" @@ -218,7 +218,7 @@ lp_build_blend_soa(LLVMBuilderRef builder, } for (i = 0; i < 4; ++i) { - if (blend->colormask & (1 << i)) { + if (blend->rt[0].colormask & (1 << i)) { if (blend->logicop_enable) { if(!type.floating) { res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]); @@ -226,10 +226,10 @@ lp_build_blend_soa(LLVMBuilderRef builder, else res[i] = dst[i]; } - else if (blend->blend_enable) { - unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor; - unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor; - unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func; + else if (blend->rt[0].blend_enable) { + unsigned src_factor = i < 3 ? blend->rt[0].rgb_src_factor : blend->rt[0].alpha_src_factor; + unsigned dst_factor = i < 3 ? blend->rt[0].rgb_dst_factor : blend->rt[0].alpha_dst_factor; + unsigned func = i < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; boolean func_commutative = lp_build_blend_func_commutative(func); /* It makes no sense to blend unless values are normalized */ @@ -270,7 +270,7 @@ lp_build_blend_soa(LLVMBuilderRef builder, /* See if this function has been previously applied */ for(j = 0; j < i; ++j) { - unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func; + unsigned prev_func = j < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func); if((!func_reverse && diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c index c8eaa8c394..c8eaa8c394 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_const.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h index cb8e1c7b00..cb8e1c7b00 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_const.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c index 9935209437..f77cf78721 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c @@ -63,11 +63,9 @@ #include "util/u_debug.h" #include "util/u_math.h" -#include "util/u_cpu_detect.h" #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_intr.h" #include "lp_bld_arit.h" #include "lp_bld_pack.h" #include "lp_bld_conv.h" @@ -125,6 +123,10 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), ""); /* TODO: Fill in the empty lower bits for additional precision? */ + /* YES: this fixes progs/trivial/tri-z-eq.c. + * Otherwise vertex Z=1.0 values get converted to something like + * 0xfffffb00 and the test for equality with 0xffffffff fails. + */ #if 0 { LLVMValueRef msb; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h index 948e68fae4..948e68fae4 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.c b/src/gallium/auxiliary/gallivm/lp_bld_debug.c index 39dfc51e50..39dfc51e50 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_debug.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h index 583e6132b4..583e6132b4 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_debug.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c index d438c0e63d..d438c0e63d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h index 79d6981bb5..79d6981bb5 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c index 25c10af29f..bc83138908 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_flow.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c @@ -41,13 +41,13 @@ #define LP_BUILD_FLOW_MAX_VARIABLES 32 #define LP_BUILD_FLOW_MAX_DEPTH 32 - /** * Enumeration of all possible flow constructs. */ enum lp_build_flow_construct_kind { - lP_BUILD_FLOW_SCOPE, - LP_BUILD_FLOW_SKIP + LP_BUILD_FLOW_SCOPE, + LP_BUILD_FLOW_SKIP, + LP_BUILD_FLOW_IF }; @@ -73,7 +73,21 @@ struct lp_build_flow_skip /** Number of variables declared at the beginning */ unsigned num_variables; - LLVMValueRef *phi; + LLVMValueRef *phi; /**< array [num_variables] */ +}; + + +/** + * if/else/endif. + */ +struct lp_build_flow_if +{ + unsigned num_variables; + + LLVMValueRef *phi; /**< array [num_variables] */ + + LLVMValueRef condition; + LLVMBasicBlockRef entry_block, true_block, false_block, merge_block; }; @@ -84,6 +98,7 @@ union lp_build_flow_construct_data { struct lp_build_flow_scope scope; struct lp_build_flow_skip skip; + struct lp_build_flow_if ifthen; }; @@ -145,6 +160,10 @@ lp_build_flow_destroy(struct lp_build_flow_context *flow) } +/** + * Begin/push a new flow control construct, such as a loop, skip block + * or variable scope. + */ static union lp_build_flow_construct_data * lp_build_flow_push(struct lp_build_flow_context *flow, enum lp_build_flow_construct_kind kind) @@ -158,6 +177,10 @@ lp_build_flow_push(struct lp_build_flow_context *flow, } +/** + * Return the current/top flow control construct on the stack. + * \param kind the expected type of the top-most construct + */ static union lp_build_flow_construct_data * lp_build_flow_peek(struct lp_build_flow_context *flow, enum lp_build_flow_construct_kind kind) @@ -174,6 +197,10 @@ lp_build_flow_peek(struct lp_build_flow_context *flow, } +/** + * End/pop the current/top flow control construct on the stack. + * \param kind the expected type of the top-most construct + */ static union lp_build_flow_construct_data * lp_build_flow_pop(struct lp_build_flow_context *flow, enum lp_build_flow_construct_kind kind) @@ -200,7 +227,7 @@ lp_build_flow_scope_begin(struct lp_build_flow_context *flow) { struct lp_build_flow_scope *scope; - scope = &lp_build_flow_push(flow, lP_BUILD_FLOW_SCOPE)->scope; + scope = &lp_build_flow_push(flow, LP_BUILD_FLOW_SCOPE)->scope; if(!scope) return; @@ -213,11 +240,11 @@ lp_build_flow_scope_begin(struct lp_build_flow_context *flow) * * A variable is a named entity which can have different LLVMValueRef's at * different points of the program. This is relevant for control flow because - * when there are mutiple branches to a same location we need to replace + * when there are multiple branches to a same location we need to replace * the variable's value with a Phi function as explained in * http://en.wikipedia.org/wiki/Static_single_assignment_form . * - * We keep track of variables by keeping around a pointer to where their + * We keep track of variables by keeping around a pointer to where they're * current. * * There are a few cautions to observe: @@ -241,7 +268,7 @@ lp_build_flow_scope_declare(struct lp_build_flow_context *flow, { struct lp_build_flow_scope *scope; - scope = &lp_build_flow_peek(flow, lP_BUILD_FLOW_SCOPE)->scope; + scope = &lp_build_flow_peek(flow, LP_BUILD_FLOW_SCOPE)->scope; if(!scope) return; @@ -263,7 +290,7 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow) { struct lp_build_flow_scope *scope; - scope = &lp_build_flow_pop(flow, lP_BUILD_FLOW_SCOPE)->scope; + scope = &lp_build_flow_pop(flow, LP_BUILD_FLOW_SCOPE)->scope; if(!scope) return; @@ -277,27 +304,47 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow) } +/** + * Note: this function has no dependencies on the flow code and could + * be used elsewhere. + */ static LLVMBasicBlockRef -lp_build_flow_insert_block(struct lp_build_flow_context *flow) +lp_build_insert_new_block(LLVMBuilderRef builder, const char *name) { LLVMBasicBlockRef current_block; LLVMBasicBlockRef next_block; LLVMBasicBlockRef new_block; - current_block = LLVMGetInsertBlock(flow->builder); + /* get current basic block */ + current_block = LLVMGetInsertBlock(builder); + /* check if there's another block after this one */ next_block = LLVMGetNextBasicBlock(current_block); - if(next_block) { - new_block = LLVMInsertBasicBlock(next_block, ""); + if (next_block) { + /* insert the new block before the next block */ + new_block = LLVMInsertBasicBlock(next_block, name); } else { + /* append new block after current block */ LLVMValueRef function = LLVMGetBasicBlockParent(current_block); - new_block = LLVMAppendBasicBlock(function, ""); + new_block = LLVMAppendBasicBlock(function, name); } return new_block; } + +static LLVMBasicBlockRef +lp_build_flow_insert_block(struct lp_build_flow_context *flow) +{ + return lp_build_insert_new_block(flow->builder, ""); +} + + +/** + * Begin a "skip" block. Inside this block we can test a condition and + * skip to the end of the block if the condition is false. + */ void lp_build_flow_skip_begin(struct lp_build_flow_context *flow) { @@ -309,13 +356,16 @@ lp_build_flow_skip_begin(struct lp_build_flow_context *flow) if(!skip) return; + /* create new basic block */ skip->block = lp_build_flow_insert_block(flow); + skip->num_variables = flow->num_variables; if(!skip->num_variables) { skip->phi = NULL; return; } + /* Allocate a Phi node for each variable in this skip scope */ skip->phi = MALLOC(skip->num_variables * sizeof *skip->phi); if(!skip->phi) { skip->num_variables = 0; @@ -325,6 +375,7 @@ lp_build_flow_skip_begin(struct lp_build_flow_context *flow) builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, skip->block); + /* create a Phi node for each variable */ for(i = 0; i < skip->num_variables; ++i) skip->phi[i] = LLVMBuildPhi(builder, LLVMTypeOf(*flow->variables[i]), ""); @@ -332,6 +383,10 @@ lp_build_flow_skip_begin(struct lp_build_flow_context *flow) } +/** + * Insert code to test a condition and branch to the end of the current + * skip block if the condition is true. + */ void lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow, LLVMValueRef cond) @@ -349,15 +404,17 @@ lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow, new_block = lp_build_flow_insert_block(flow); + /* for each variable, update the Phi node with a (variable, block) pair */ for(i = 0; i < skip->num_variables; ++i) { assert(*flow->variables[i]); LLVMAddIncoming(skip->phi[i], flow->variables[i], ¤t_block, 1); } + /* if cond is true, goto skip->block, else goto new_block */ LLVMBuildCondBr(flow->builder, cond, skip->block, new_block); LLVMPositionBuilderAtEnd(flow->builder, new_block); - } +} void @@ -373,12 +430,14 @@ lp_build_flow_skip_end(struct lp_build_flow_context *flow) current_block = LLVMGetInsertBlock(flow->builder); + /* add (variable, block) tuples to the phi nodes */ for(i = 0; i < skip->num_variables; ++i) { assert(*flow->variables[i]); LLVMAddIncoming(skip->phi[i], flow->variables[i], ¤t_block, 1); *flow->variables[i] = skip->phi[i]; } + /* goto block */ LLVMBuildBr(flow->builder, skip->block); LLVMPositionBuilderAtEnd(flow->builder, skip->block); @@ -386,22 +445,34 @@ lp_build_flow_skip_end(struct lp_build_flow_context *flow) } +/** + * Check if the mask predicate is zero. If so, jump to the end of the block. + */ static void lp_build_mask_check(struct lp_build_mask_context *mask) { LLVMBuilderRef builder = mask->flow->builder; LLVMValueRef cond; + /* cond = (mask == 0) */ cond = LLVMBuildICmp(builder, LLVMIntEQ, LLVMBuildBitCast(builder, mask->value, mask->reg_type, ""), LLVMConstNull(mask->reg_type), ""); + /* if cond, goto end of block */ lp_build_flow_skip_cond_break(mask->flow, cond); } +/** + * Begin a section of code which is predicated on a mask. + * \param mask the mask context, initialized here + * \param flow the flow context + * \param type the type of the mask + * \param value storage for the mask + */ void lp_build_mask_begin(struct lp_build_mask_context *mask, struct lp_build_flow_context *flow, @@ -422,6 +493,11 @@ lp_build_mask_begin(struct lp_build_mask_context *mask, } +/** + * Update boolean mask with given value (bitwise AND). + * Typically used to update the quad's pixel alive/killed mask + * after depth testing, alpha testing, TGSI_OPCODE_KIL, etc. + */ void lp_build_mask_update(struct lp_build_mask_context *mask, LLVMValueRef value) @@ -432,6 +508,9 @@ lp_build_mask_update(struct lp_build_mask_context *mask, } +/** + * End section of code which is predicated on a mask. + */ LLVMValueRef lp_build_mask_end(struct lp_build_mask_context *mask) { @@ -491,3 +570,188 @@ lp_build_loop_end(LLVMBuilderRef builder, LLVMPositionBuilderAtEnd(builder, after_block); } + + +/* + Example of if/then/else building: + + int x; + if (cond) { + x = 1 + 2; + } + else { + x = 2 + 3; + } + + Is built with: + + LLVMValueRef x = LLVMGetUndef(); // or something else + + flow = lp_build_flow_create(builder); + + lp_build_flow_scope_begin(flow); + + // x needs a phi node + lp_build_flow_scope_declare(flow, &x); + + lp_build_if(ctx, flow, builder, cond); + x = LLVMAdd(1, 2); + lp_build_else(ctx); + x = LLVMAdd(2, 3); + lp_build_endif(ctx); + + lp_build_flow_scope_end(flow); + + lp_build_flow_destroy(flow); + */ + + + +/** + * Begin an if/else/endif construct. + */ +void +lp_build_if(struct lp_build_if_state *ctx, + struct lp_build_flow_context *flow, + LLVMBuilderRef builder, + LLVMValueRef condition) +{ + LLVMBasicBlockRef block = LLVMGetInsertBlock(builder); + struct lp_build_flow_if *ifthen; + unsigned i; + + memset(ctx, 0, sizeof(*ctx)); + ctx->builder = builder; + ctx->flow = flow; + + /* push/create new scope */ + ifthen = &lp_build_flow_push(flow, LP_BUILD_FLOW_IF)->ifthen; + assert(ifthen); + + ifthen->num_variables = flow->num_variables; + ifthen->condition = condition; + ifthen->entry_block = block; + + /* create a Phi node for each variable in this flow scope */ + ifthen->phi = MALLOC(ifthen->num_variables * sizeof(*ifthen->phi)); + if (!ifthen->phi) { + ifthen->num_variables = 0; + return; + } + + /* create endif/merge basic block for the phi functions */ + ifthen->merge_block = lp_build_insert_new_block(builder, "endif-block"); + LLVMPositionBuilderAtEnd(builder, ifthen->merge_block); + + /* create a phi node for each variable */ + for (i = 0; i < flow->num_variables; i++) { + ifthen->phi[i] = LLVMBuildPhi(builder, LLVMTypeOf(*flow->variables[i]), ""); + + /* add add the initial value of the var from the entry block */ + LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->entry_block, 1); + } + + /* create/insert true_block before merge_block */ + ifthen->true_block = LLVMInsertBasicBlock(ifthen->merge_block, "if-true-block"); + + /* successive code goes into the true block */ + LLVMPositionBuilderAtEnd(builder, ifthen->true_block); +} + + +/** + * Begin else-part of a conditional + */ +void +lp_build_else(struct lp_build_if_state *ctx) +{ + struct lp_build_flow_context *flow = ctx->flow; + struct lp_build_flow_if *ifthen; + unsigned i; + + ifthen = &lp_build_flow_peek(flow, LP_BUILD_FLOW_IF)->ifthen; + assert(ifthen); + + /* for each variable, update the Phi node with a (variable, block) pair */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block); + for (i = 0; i < flow->num_variables; i++) { + assert(*flow->variables[i]); + LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->true_block, 1); + } + + /* create/insert false_block before the merge block */ + ifthen->false_block = LLVMInsertBasicBlock(ifthen->merge_block, "if-false-block"); + + /* successive code goes into the else block */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->false_block); +} + + +/** + * End a conditional. + */ +void +lp_build_endif(struct lp_build_if_state *ctx) +{ + struct lp_build_flow_context *flow = ctx->flow; + struct lp_build_flow_if *ifthen; + unsigned i; + + ifthen = &lp_build_flow_pop(flow, LP_BUILD_FLOW_IF)->ifthen; + assert(ifthen); + + if (ifthen->false_block) { + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block); + /* for each variable, update the Phi node with a (variable, block) pair */ + for (i = 0; i < flow->num_variables; i++) { + assert(*flow->variables[i]); + LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->false_block, 1); + + /* replace the variable ref with the phi function */ + *flow->variables[i] = ifthen->phi[i]; + } + } + else { + /* no else clause */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block); + for (i = 0; i < flow->num_variables; i++) { + assert(*flow->variables[i]); + LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->true_block, 1); + + /* replace the variable ref with the phi function */ + *flow->variables[i] = ifthen->phi[i]; + } + } + + FREE(ifthen->phi); + + /*** + *** Now patch in the various branch instructions. + ***/ + + /* Insert the conditional branch instruction at the end of entry_block */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->entry_block); + if (ifthen->false_block) { + /* we have an else clause */ + LLVMBuildCondBr(ctx->builder, ifthen->condition, + ifthen->true_block, ifthen->false_block); + } + else { + /* no else clause */ + LLVMBuildCondBr(ctx->builder, ifthen->condition, + ifthen->true_block, ifthen->merge_block); + } + + /* Append an unconditional Br(anch) instruction on the true_block */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->true_block); + LLVMBuildBr(ctx->builder, ifthen->merge_block); + if (ifthen->false_block) { + /* Append an unconditional Br(anch) instruction on the false_block */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->false_block); + LLVMBuildBr(ctx->builder, ifthen->merge_block); + } + + + /* Resume building code at end of the ifthen->merge_block */ + LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block); +} diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h index e61999ff06..4c225a0d4f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_flow.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h @@ -126,4 +126,26 @@ lp_build_loop_end(LLVMBuilderRef builder, + +struct lp_build_if_state +{ + LLVMBuilderRef builder; + struct lp_build_flow_context *flow; +}; + + +void +lp_build_if(struct lp_build_if_state *ctx, + struct lp_build_flow_context *flow, + LLVMBuilderRef builder, + LLVMValueRef condition); + +void +lp_build_else(struct lp_build_if_state *ctx); + +void +lp_build_endif(struct lp_build_if_state *ctx); + + + #endif /* !LP_BLD_FLOW_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 970bee379f..970bee379f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 10e82f120b..dfa080b853 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -38,7 +38,6 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_logic.h" #include "lp_bld_swizzle.h" #include "lp_bld_format.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_query.c b/src/gallium/auxiliary/gallivm/lp_bld_format_query.c index f3832d07ff..f3832d07ff 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_query.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_query.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 64151d169d..64151d169d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/auxiliary/gallivm/lp_bld_interp.c index 49dab8ab61..a6acaead88 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.c @@ -45,6 +45,36 @@ #include "lp_bld_interp.h" +/* + * The shader JIT function operates on blocks of quads. + * Each block has 2x2 quads and each quad has 2x2 pixels. + * + * We iterate over the quads in order 0, 1, 2, 3: + * + * ################# + * # | # | # + * #---0---#---1---# + * # | # | # + * ################# + * # | # | # + * #---2---#---3---# + * # | # | # + * ################# + * + * Within each quad, we have four pixels which are represented in SOA + * order: + * + * ######### + * # 0 | 1 # + * #---+---# + * # 2 | 3 # + * ######### + * + * So the green channel (for example) of the four pixels is stored in + * a single vector register: {g0, g1, g2, g3}. + */ + + static void attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix) { @@ -55,6 +85,10 @@ attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix } +/** + * Initialize the bld->a0, dadx, dady fields. This involves fetching + * those values from the arrays which are passed into the JIT function. + */ static void coeffs_init(struct lp_build_interp_soa_context *bld, LLVMValueRef a0_ptr, @@ -91,7 +125,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld, case TGSI_INTERPOLATE_CONSTANT: a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), ""); a0 = lp_build_broadcast_scalar(&bld->base, a0); - attrib_name(a0, attrib, chan, ".dady"); + attrib_name(a0, attrib, chan, ".a0"); break; default: @@ -109,30 +143,13 @@ coeffs_init(struct lp_build_interp_soa_context *bld, /** - * Multiply the dadx and dady with the xstep and ystep respectively. + * Emit LLVM code to compute the fragment shader input attribute values. + * For example, for a color input, we'll compute red, green, blue and alpha + * values for the four pixels in a quad. + * Recall that we're operating on 4-element vectors so each arithmetic + * operation is operating on the four pixels in a quad. */ static void -coeffs_update(struct lp_build_interp_soa_context *bld) -{ - unsigned attrib; - unsigned chan; - - for(attrib = 0; attrib < bld->num_attribs; ++attrib) { - unsigned mask = bld->mask[attrib]; - unsigned mode = bld->mode[attrib]; - if (mode != TGSI_INTERPOLATE_CONSTANT) { - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - if(mask & (1 << chan)) { - bld->dadx[attrib][chan] = lp_build_mul_imm(&bld->base, bld->dadx[attrib][chan], bld->xstep); - bld->dady[attrib][chan] = lp_build_mul_imm(&bld->base, bld->dady[attrib][chan], bld->ystep); - } - } - } - } -} - - -static void attribs_init(struct lp_build_interp_soa_context *bld) { LLVMValueRef x = bld->pos[0]; @@ -154,7 +171,9 @@ attribs_init(struct lp_build_interp_soa_context *bld) res = a0; if (mode != TGSI_INTERPOLATE_CONSTANT) { + /* res = res + x * dadx */ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx)); + /* res = res + y * dady */ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady)); } @@ -178,13 +197,19 @@ attribs_init(struct lp_build_interp_soa_context *bld) } +/** + * Increment the shader input attribute values. + * This is called when we move from one quad to the next. + */ static void -attribs_update(struct lp_build_interp_soa_context *bld) +attribs_update(struct lp_build_interp_soa_context *bld, int quad_index) { LLVMValueRef oow = NULL; unsigned attrib; unsigned chan; + assert(quad_index < 4); + for(attrib = 0; attrib < bld->num_attribs; ++attrib) { unsigned mask = bld->mask[attrib]; unsigned mode = bld->mode[attrib]; @@ -198,13 +223,21 @@ attribs_update(struct lp_build_interp_soa_context *bld) res = bld->attribs_pre[attrib][chan]; - if(bld->xstep) + if (quad_index == 1 || quad_index == 3) { + /* top-right or bottom-right quad */ + /* build res = res + dadx + dadx */ + res = lp_build_add(&bld->base, res, dadx); res = lp_build_add(&bld->base, res, dadx); + } - if(bld->ystep) + if (quad_index == 2 || quad_index == 3) { + /* bottom-left or bottom-right quad */ + /* build res = res + dady + dady */ + res = lp_build_add(&bld->base, res, dady); res = lp_build_add(&bld->base, res, dady); + } - bld->attribs_pre[attrib][chan] = res; + //XXX bld->attribs_pre[attrib][chan] = res; if (mode == TGSI_INTERPOLATE_PERSPECTIVE) { LLVMValueRef w = bld->pos[3]; @@ -242,17 +275,32 @@ pos_init(struct lp_build_interp_soa_context *bld, } +/** + * Update quad position values when moving to the next quad. + */ static void -pos_update(struct lp_build_interp_soa_context *bld) +pos_update(struct lp_build_interp_soa_context *bld, int quad_index) { LLVMValueRef x = bld->attribs[0][0]; LLVMValueRef y = bld->attribs[0][1]; + const int xstep = 2, ystep = 2; - if(bld->xstep) - x = lp_build_add(&bld->base, x, lp_build_const_scalar(bld->base.type, bld->xstep)); + if (quad_index == 1 || quad_index == 3) { + /* top-right or bottom-right quad in block */ + /* build x += xstep */ + x = lp_build_add(&bld->base, x, + lp_build_const_scalar(bld->base.type, xstep)); + } - if(bld->ystep) - y = lp_build_add(&bld->base, y, lp_build_const_scalar(bld->base.type, bld->ystep)); + if (quad_index == 2) { + /* bottom-left quad in block */ + /* build y += ystep */ + y = lp_build_add(&bld->base, y, + lp_build_const_scalar(bld->base.type, ystep)); + /* build x -= xstep */ + x = lp_build_sub(&bld->base, x, + lp_build_const_scalar(bld->base.type, xstep)); + } lp_build_name(x, "pos.x"); lp_build_name(y, "pos.y"); @@ -262,18 +310,20 @@ pos_update(struct lp_build_interp_soa_context *bld) } +/** + * Initialize fragment shader input attribute info. + */ void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, const struct tgsi_token *tokens, + boolean flatshade, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef a0_ptr, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, LLVMValueRef x0, - LLVMValueRef y0, - int xstep, - int ystep) + LLVMValueRef y0) { struct tgsi_parse_context parse; struct tgsi_full_declaration *decl; @@ -309,7 +359,15 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, for( attrib = first; attrib <= last; ++attrib ) { bld->mask[1 + attrib] = mask; - bld->mode[1 + attrib] = decl->Declaration.Interpolate; + + /* XXX: have mesa set INTERP_CONSTANT in the fragment + * shader. + */ + if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR && + flatshade) + bld->mode[1 + attrib] = TGSI_INTERPOLATE_CONSTANT; + else + bld->mode[1 + attrib] = decl->Declaration.Interpolate; } bld->num_attribs = MAX2(bld->num_attribs, 1 + last + 1); @@ -331,21 +389,19 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, pos_init(bld, x0, y0); attribs_init(bld); - - bld->xstep = xstep; - bld->ystep = ystep; - - coeffs_update(bld); } /** - * Advance the position and inputs with the xstep and ystep. + * Advance the position and inputs to the given quad within the block. */ void -lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld) +lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld, + int quad_index) { - pos_update(bld); + assert(quad_index < 4); + + pos_update(bld, quad_index); - attribs_update(bld); + attribs_update(bld, quad_index); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/auxiliary/gallivm/lp_bld_interp.h index 9c57a10879..ca958cdf34 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.h @@ -63,9 +63,6 @@ struct lp_build_interp_soa_context LLVMValueRef dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; LLVMValueRef dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - int xstep; - int ystep; - /* Attribute values before perspective divide */ LLVMValueRef attribs_pre[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; @@ -82,18 +79,18 @@ struct lp_build_interp_soa_context void lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld, const struct tgsi_token *tokens, + boolean flatshade, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef a0_ptr, LLVMValueRef dadx_ptr, LLVMValueRef dady_ptr, LLVMValueRef x0, - LLVMValueRef y0, - int xstep, - int ystep); + LLVMValueRef y0); void -lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld); +lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld, + int quad_index); #endif /* LP_BLD_INTERP_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.c b/src/gallium/auxiliary/gallivm/lp_bld_intr.c index 9895749d56..9895749d56 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_intr.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_intr.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.h b/src/gallium/auxiliary/gallivm/lp_bld_intr.h index f813f27074..f813f27074 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_intr.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_intr.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c index db22a8028a..41ac81b744 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c @@ -34,6 +34,7 @@ #include "util/u_cpu_detect.h" +#include "util/u_debug.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -41,13 +42,17 @@ #include "lp_bld_logic.h" +/** + * Build code to compare two values 'a' and 'b' of 'type' using the given func. + * \param func one of PIPE_FUNC_x + */ LLVMValueRef -lp_build_cmp(struct lp_build_context *bld, - unsigned func, - LLVMValueRef a, - LLVMValueRef b) +lp_build_compare(LLVMBuilderRef builder, + const struct lp_type type, + unsigned func, + LLVMValueRef a, + LLVMValueRef b) { - const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); LLVMValueRef zeros = LLVMConstNull(int_vec_type); @@ -56,6 +61,9 @@ lp_build_cmp(struct lp_build_context *bld, LLVMValueRef res; unsigned i; + assert(func >= PIPE_FUNC_NEVER); + assert(func <= PIPE_FUNC_ALWAYS); + if(func == PIPE_FUNC_NEVER) return zeros; if(func == PIPE_FUNC_ALWAYS) @@ -68,6 +76,7 @@ lp_build_cmp(struct lp_build_context *bld, #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) if(type.width * type.length == 128) { if(type.floating && util_cpu_caps.has_sse) { + /* float[4] comparison */ LLVMValueRef args[3]; unsigned cc; boolean swap; @@ -96,7 +105,7 @@ lp_build_cmp(struct lp_build_context *bld, break; default: assert(0); - return bld->undef; + return lp_build_undef(type); } if(swap) { @@ -109,14 +118,15 @@ lp_build_cmp(struct lp_build_context *bld, } args[2] = LLVMConstInt(LLVMInt8Type(), cc, 0); - res = lp_build_intrinsic(bld->builder, + res = lp_build_intrinsic(builder, "llvm.x86.sse.cmp.ps", vec_type, args, 3); - res = LLVMBuildBitCast(bld->builder, res, int_vec_type, ""); + res = LLVMBuildBitCast(builder, res, int_vec_type, ""); return res; } else if(util_cpu_caps.has_sse2) { + /* int[4] comparison */ static const struct { unsigned swap:1; unsigned eq:1; @@ -152,7 +162,7 @@ lp_build_cmp(struct lp_build_context *bld, break; default: assert(0); - return bld->undef; + return lp_build_undef(type); } /* There are no signed byte and unsigned word/dword comparison @@ -162,8 +172,8 @@ lp_build_cmp(struct lp_build_context *bld, ((type.width == 8 && type.sign) || (type.width != 8 && !type.sign))) { LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1)); - a = LLVMBuildXor(bld->builder, a, msb, ""); - b = LLVMBuildXor(bld->builder, b, msb, ""); + a = LLVMBuildXor(builder, a, msb, ""); + b = LLVMBuildXor(builder, b, msb, ""); } if(table[func].swap) { @@ -176,14 +186,14 @@ lp_build_cmp(struct lp_build_context *bld, } if(table[func].eq) - res = lp_build_intrinsic(bld->builder, pcmpeq, vec_type, args, 2); + res = lp_build_intrinsic(builder, pcmpeq, vec_type, args, 2); else if (table[func].gt) - res = lp_build_intrinsic(bld->builder, pcmpgt, vec_type, args, 2); + res = lp_build_intrinsic(builder, pcmpgt, vec_type, args, 2); else res = LLVMConstNull(vec_type); if(table[func].not) - res = LLVMBuildNot(bld->builder, res, ""); + res = LLVMBuildNot(builder, res, ""); return res; } @@ -219,28 +229,28 @@ lp_build_cmp(struct lp_build_context *bld, break; default: assert(0); - return bld->undef; + return lp_build_undef(type); } #if 0 /* XXX: Although valid IR, no LLVM target currently support this */ - cond = LLVMBuildFCmp(bld->builder, op, a, b, ""); - res = LLVMBuildSelect(bld->builder, cond, ones, zeros, ""); + cond = LLVMBuildFCmp(builder, op, a, b, ""); + res = LLVMBuildSelect(builder, cond, ones, zeros, ""); #else debug_printf("%s: warning: using slow element-wise vector comparison\n", __FUNCTION__); res = LLVMGetUndef(int_vec_type); for(i = 0; i < type.length; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - cond = LLVMBuildFCmp(bld->builder, op, - LLVMBuildExtractElement(bld->builder, a, index, ""), - LLVMBuildExtractElement(bld->builder, b, index, ""), + cond = LLVMBuildFCmp(builder, op, + LLVMBuildExtractElement(builder, a, index, ""), + LLVMBuildExtractElement(builder, b, index, ""), ""); - cond = LLVMBuildSelect(bld->builder, cond, + cond = LLVMBuildSelect(builder, cond, LLVMConstExtractElement(ones, index), LLVMConstExtractElement(zeros, index), ""); - res = LLVMBuildInsertElement(bld->builder, res, cond, index, ""); + res = LLVMBuildInsertElement(builder, res, cond, index, ""); } #endif } @@ -267,28 +277,28 @@ lp_build_cmp(struct lp_build_context *bld, break; default: assert(0); - return bld->undef; + return lp_build_undef(type); } #if 0 /* XXX: Although valid IR, no LLVM target currently support this */ - cond = LLVMBuildICmp(bld->builder, op, a, b, ""); - res = LLVMBuildSelect(bld->builder, cond, ones, zeros, ""); + cond = LLVMBuildICmp(builder, op, a, b, ""); + res = LLVMBuildSelect(builder, cond, ones, zeros, ""); #else - debug_printf("%s: warning: using slow element-wise vector comparison\n", + debug_printf("%s: warning: using slow element-wise int vector comparison\n", __FUNCTION__); res = LLVMGetUndef(int_vec_type); for(i = 0; i < type.length; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - cond = LLVMBuildICmp(bld->builder, op, - LLVMBuildExtractElement(bld->builder, a, index, ""), - LLVMBuildExtractElement(bld->builder, b, index, ""), + cond = LLVMBuildICmp(builder, op, + LLVMBuildExtractElement(builder, a, index, ""), + LLVMBuildExtractElement(builder, b, index, ""), ""); - cond = LLVMBuildSelect(bld->builder, cond, + cond = LLVMBuildSelect(builder, cond, LLVMConstExtractElement(ones, index), LLVMConstExtractElement(zeros, index), ""); - res = LLVMBuildInsertElement(bld->builder, res, cond, index, ""); + res = LLVMBuildInsertElement(builder, res, cond, index, ""); } #endif } @@ -297,6 +307,21 @@ lp_build_cmp(struct lp_build_context *bld, } + +/** + * Build code to compare two values 'a' and 'b' using the given func. + * \param func one of PIPE_FUNC_x + */ +LLVMValueRef +lp_build_cmp(struct lp_build_context *bld, + unsigned func, + LLVMValueRef a, + LLVMValueRef b) +{ + return lp_build_compare(bld->builder, bld->type, func, a, b); +} + + LLVMValueRef lp_build_select(struct lp_build_context *bld, LLVMValueRef mask, @@ -394,3 +419,15 @@ lp_build_select_aos(struct lp_build_context *bld, #endif } } + +LLVMValueRef +lp_build_alloca(struct lp_build_context *bld) +{ + const struct lp_type type = bld->type; + + if (type.length > 1) { /*vector*/ + return LLVMBuildAlloca(bld->builder, lp_build_vec_type(type), ""); + } else { /*scalar*/ + return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), ""); + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h index d67500ef70..a399ebf39e 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_logic.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h @@ -46,6 +46,14 @@ struct lp_type; struct lp_build_context; +LLVMValueRef +lp_build_compare(LLVMBuilderRef builder, + const struct lp_type type, + unsigned func, + LLVMValueRef a, + LLVMValueRef b); + + /** * @param func is one of PIPE_FUNC_xxx */ @@ -68,5 +76,7 @@ lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef b, const boolean cond[4]); +LLVMValueRef +lp_build_alloca(struct lp_build_context *bld); #endif /* !LP_BLD_LOGIC_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 6e79438ead..6e79438ead 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp diff --git a/src/gallium/drivers/llvmpipe/lp_bld_misc.h b/src/gallium/auxiliary/gallivm/lp_bld_misc.h index 0e787e0b9c..0e787e0b9c 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_misc.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c index bc360ad77a..bc360ad77a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_pack.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_pack.h b/src/gallium/auxiliary/gallivm/lp_bld_pack.h index fb2a34984a..fb2a34984a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_pack.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 9003e108c1..a133b56ac5 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -74,7 +74,6 @@ lp_sampler_static_state(struct lp_sampler_static_state *state, state->compare_func = sampler->compare_func; } state->normalized_coords = sampler->normalized_coords; - state->prefilter = sampler->prefilter; } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 8cb8210ca7..39edcf13d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -70,7 +70,6 @@ struct lp_sampler_static_state unsigned compare_mode:1; unsigned compare_func:3; unsigned normalized_coords:1; - unsigned prefilter:4; }; diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 5ee8d556a6..57c2b763e4 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -172,7 +172,7 @@ lp_build_sample_wrap(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: /* FIXME */ - _debug_printf("warning: failed to translate texture wrap mode %s\n", + _debug_printf("llvmpipe: failed to translate texture wrap mode %s\n", debug_dump_tex_wrap(wrap_mode, TRUE)); coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero); coord = lp_build_min(int_coord_bld, coord, length_minus_one); @@ -201,9 +201,13 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld, x = lp_build_ifloor(&bld->coord_bld, s); y = lp_build_ifloor(&bld->coord_bld, t); + lp_build_name(x, "tex.x.floor"); + lp_build_name(y, "tex.y.floor"); x = lp_build_sample_wrap(bld, x, width, bld->static_state->pot_width, bld->static_state->wrap_s); y = lp_build_sample_wrap(bld, y, height, bld->static_state->pot_height, bld->static_state->wrap_t); + lp_build_name(x, "tex.x.wrapped"); + lp_build_name(y, "tex.y.wrapped"); lp_build_sample_texel_soa(bld, x, y, stride, data_ptr, texel); } @@ -588,7 +592,6 @@ lp_build_sample_soa(LLVMBuilderRef builder, /* FIXME: respect static_state->min_mip_filter */; /* FIXME: respect static_state->mag_img_filter */; - /* FIXME: respect static_state->prefilter */; lp_build_sample_compare(&bld, p, texel); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_struct.c b/src/gallium/auxiliary/gallivm/lp_bld_struct.c index 3998ac374f..3998ac374f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_struct.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h index 740392f561..740392f561 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_struct.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c index 64e81f7b1f..64e81f7b1f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h index b9472127a6..b9472127a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index eddb7a83fa..eddb7a83fa 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index fb1eda4423..a52c6c5028 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -47,13 +47,11 @@ #include "tgsi/tgsi_exec.h" #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_intr.h" #include "lp_bld_arit.h" #include "lp_bld_logic.h" #include "lp_bld_swizzle.h" #include "lp_bld_flow.h" #include "lp_bld_tgsi.h" -#include "lp_bld_debug.h" #define LP_MAX_TEMPS 256 @@ -187,7 +185,7 @@ emit_fetch( break; case TGSI_FILE_TEMPORARY: - res = bld->temps[reg->Register.Index][swizzle]; + res = LLVMBuildLoad(bld->base.builder, bld->temps[reg->Register.Index][swizzle], ""); if(!res) return bld->base.undef; break; @@ -289,11 +287,13 @@ emit_store( switch( reg->Register.File ) { case TGSI_FILE_OUTPUT: - bld->outputs[reg->Register.Index][chan_index] = value; + LLVMBuildStore(bld->base.builder, value, + bld->outputs[reg->Register.Index][chan_index]); break; case TGSI_FILE_TEMPORARY: - bld->temps[reg->Register.Index][chan_index] = value; + LLVMBuildStore(bld->base.builder, value, + bld->temps[reg->Register.Index][chan_index]); break; case TGSI_FILE_ADDRESS: @@ -440,6 +440,42 @@ indirect_temp_reference(const struct tgsi_full_instruction *inst) return FALSE; } +static int +emit_declaration( + struct lp_build_tgsi_soa_context *bld, + const struct tgsi_full_declaration *decl) +{ + unsigned first = decl->Range.First; + unsigned last = decl->Range.Last; + unsigned idx, i; + + for (idx = first; idx <= last; ++idx) { + boolean ok; + + switch (decl->Declaration.File) { + case TGSI_FILE_TEMPORARY: + for (i = 0; i < NUM_CHANNELS; i++) + bld->temps[idx][i] = lp_build_alloca(&bld->base); + ok = TRUE; + break; + + case TGSI_FILE_OUTPUT: + for (i = 0; i < NUM_CHANNELS; i++) + bld->outputs[idx][i] = lp_build_alloca(&bld->base); + ok = TRUE; + break; + + default: + /* don't need to declare other vars */ + ok = TRUE; + } + + if (!ok) + return FALSE; + } + + return TRUE; +} static int emit_instruction( @@ -1431,6 +1467,10 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: /* Inputs already interpolated */ + { + if (!emit_declaration( &bld, &parse.FullToken.FullDeclaration )) + _debug_printf("warning: failed to define LLVM variable\n"); + } break; case TGSI_TOKEN_TYPE_INSTRUCTION: diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c index 1320a26721..8270cd057f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_type.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c @@ -157,6 +157,27 @@ lp_build_int_vec_type(struct lp_type type) } +/** + * Build int32[4] vector type + */ +LLVMTypeRef +lp_build_int32_vec4_type(void) +{ + struct lp_type t; + LLVMTypeRef type; + + memset(&t, 0, sizeof(t)); + t.floating = FALSE; /* floating point values */ + t.sign = TRUE; /* values are signed */ + t.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ + t.width = 32; /* 32-bit int */ + t.length = 4; /* 4 elements per vector */ + + type = lp_build_int_elem_type(t); + return LLVMVectorType(type, t.length); +} + + struct lp_type lp_int_type(struct lp_type type) { diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h index 2fb233d335..62ee05be4d 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_type.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h @@ -252,6 +252,10 @@ LLVMTypeRef lp_build_int_vec_type(struct lp_type type); +LLVMTypeRef +lp_build_int32_vec4_type(void); + + struct lp_type lp_int_type(struct lp_type type); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c deleted file mode 100644 index cb85e1734e..0000000000 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ /dev/null @@ -1,210 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * This file is compiled with clang into the LLVM bitcode - * - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -typedef __attribute__(( ext_vector_type(4) )) float float4; - - -extern float fabsf(float val); - -/* helpers */ - -float4 absvec(float4 vec) -{ - float4 res; - res.x = fabsf(vec.x); - res.y = fabsf(vec.y); - res.z = fabsf(vec.z); - res.w = fabsf(vec.w); - - return res; -} - -float4 maxvec(float4 a, float4 b) -{ - return (float4){(a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y, - (a.z > b.z) ? a.z : b.z, - (a.w > b.w) ? a.w : b.w}; -} - -float4 minvec(float4 a, float4 b) -{ - return (float4){(a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y, - (a.z < b.z) ? a.z : b.z, - (a.w < b.w) ? a.w : b.w}; -} - -extern float powf(float num, float p); -extern float sqrtf(float x); - -float4 powvec(float4 vec, float4 q) -{ - float4 p; - p.x = powf(vec.x, q.x); - p.y = powf(vec.y, q.y); - p.z = powf(vec.z, q.z); - p.w = powf(vec.w, q.w); - return p; -} - -float4 sqrtvec(float4 vec) -{ - float4 p; - p.x = sqrtf(vec.x); - p.y = sqrtf(vec.y); - p.z = sqrtf(vec.z); - p.w = sqrtf(vec.w); - return p; -} - -float4 sltvec(float4 v1, float4 v2) -{ - float4 p; - p.x = (v1.x < v2.x) ? 1.0 : 0.0; - p.y = (v1.y < v2.y) ? 1.0 : 0.0; - p.z = (v1.z < v2.z) ? 1.0 : 0.0; - p.w = (v1.w < v2.w) ? 1.0 : 0.0; - return p; -} - - -/* instructions */ - -void abs(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) -{ - res[0] = absvec(tmp0x); - res[1] = absvec(tmp0y); - res[2] = absvec(tmp0z); - res[3] = absvec(tmp0w); -} - -void dp3(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - float4 dot = (tmp0x * tmp1x) + (tmp0y * tmp1y) + - (tmp0z * tmp1z); - - res[0] = dot; - res[1] = dot; - res[2] = dot; - res[3] = dot; -} - -void dp4(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - float4 dot = (tmp0x * tmp1x) + (tmp0y * tmp1y) + - (tmp0z * tmp1z) + (tmp0w * tmp1w); - - res[0] = dot; - res[1] = dot; - res[2] = dot; - res[3] = dot; -} - -void lit(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) -{ - const float4 zerovec = (float4) {0.0, 0.0, 0.0, 0.0}; - const float4 min128 = (float4) {-128.f, -128.f, -128.f, -128.f}; - const float4 plus128 = (float4) {128.f, 128.f, 128.f, 128.f}; - - res[0] = (float4){1.0, 1.0, 1.0, 1.0}; - if (tmp0x.x > 0) { - float4 tmpy = maxvec(tmp0y, zerovec); - float4 tmpw = minvec(tmp0w, plus128); - tmpw = maxvec(tmpw, min128); - res[1] = tmp0x; - res[2] = powvec(tmpy, tmpw); - } else { - res[1] = zerovec; - res[2] = zerovec; - } - res[3] = (float4){1.0, 1.0, 1.0, 1.0}; -} - -void min(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - res[0] = minvec(tmp0x, tmp1x); - res[1] = minvec(tmp0y, tmp1y); - res[2] = minvec(tmp0z, tmp1z); - res[3] = minvec(tmp0w, tmp1w); -} - - -void max(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - res[0] = maxvec(tmp0x, tmp1x); - res[1] = maxvec(tmp0y, tmp1y); - res[2] = maxvec(tmp0z, tmp1z); - res[3] = maxvec(tmp0w, tmp1w); -} - -void pow(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - res[0] = powvec(tmp0x, tmp1x); - res[1] = res[0]; - res[2] = res[0]; - res[3] = res[0]; -} - -void rsq(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) -{ - const float4 onevec = (float4) {1., 1., 1., 1.}; - res[0] = onevec/sqrtvec(absvec(tmp0x)); - res[1] = onevec/sqrtvec(absvec(tmp0y)); - res[2] = onevec/sqrtvec(absvec(tmp0z)); - res[3] = onevec/sqrtvec(absvec(tmp0w)); -} - -void slt(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - res[0] = sltvec(tmp0x, tmp1x); - res[1] = sltvec(tmp0y, tmp1y); - res[2] = sltvec(tmp0z, tmp1z); - res[3] = sltvec(tmp0w, tmp1w); -} - diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp deleted file mode 100644 index 73df24c976..0000000000 --- a/src/gallium/auxiliary/gallivm/storage.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "storage.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include <llvm/BasicBlock.h> -#include <llvm/Module.h> -#include <llvm/Value.h> - -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/InstrTypes.h> -#include <llvm/Instructions.h> - -using namespace llvm; - -Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) - : m_block(block), - m_INPUT(input), - m_addrs(32), - m_idx(0) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - m_intVecType = VectorType::get(IntegerType::get(32), 4); - - m_undefFloatVec = UndefValue::get(m_floatVecType); - m_undefIntVec = UndefValue::get(m_intVecType); - m_extSwizzleVec = 0; - - m_numConsts = 0; -} - -//can only build vectors with all members in the [0, 9] range -llvm::Constant *Storage::shuffleMask(int vec) -{ - if (!m_extSwizzleVec) { - std::vector<Constant*> elems; - elems.push_back(ConstantFP::get(APFloat(0.f))); - elems.push_back(ConstantFP::get(APFloat(1.f))); - elems.push_back(ConstantFP::get(APFloat(0.f))); - elems.push_back(ConstantFP::get(APFloat(1.f))); - m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); - } - - if (m_intVecs.find(vec) != m_intVecs.end()) { - return m_intVecs[vec]; - } - int origVec = vec; - Constant* const_vec = 0; - if (origVec == 0) { - const_vec = Constant::getNullValue(m_intVecType); - } else { - int x = gallivm_x_swizzle(vec); - int y = gallivm_y_swizzle(vec); - int z = gallivm_z_swizzle(vec); - int w = gallivm_w_swizzle(vec); - std::vector<Constant*> elems; - elems.push_back(constantInt(x)); - elems.push_back(constantInt(y)); - elems.push_back(constantInt(z)); - elems.push_back(constantInt(w)); - const_vec = ConstantVector::get(m_intVecType, elems); - } - - m_intVecs[origVec] = const_vec; - return const_vec; -} - -llvm::ConstantInt *Storage::constantInt(int idx) -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = const_int; - return const_int; -} - -llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) -{ - Value *val = element(InputsArg, idx, indIdx); - LoadInst *load = new LoadInst(val, name("input"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) -{ - m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; - - Value *elem = element(ConstsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("const"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) -{ - Constant *mask = shuffleMask(shuffle); - ShuffleVectorInst *res = - new ShuffleVectorInst(vec, m_extSwizzleVec, mask, - name("shuffle"), m_block); - return res; -} - - -llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(TempsArg, idx, indIdx); - - LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); - load->setAlignment(8); - - return load; -} - -void Storage::setTempElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_tempWriteMap[idx]) - templ = tempElement(idx); - val = maskWrite(val, mask, templ); - } - Value *elem = element(TempsArg, idx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_tempWriteMap[idx] = true; -} - -void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_destWriteMap[dstIdx]) - templ = outputElement(dstIdx); - val = maskWrite(val, mask, templ); - } - - Value *elem = element(DestsArg, dstIdx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_destWriteMap[dstIdx] = true; -} - -llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) -{ - llvm::Value *dst = templ; - if (!dst) - dst = Constant::getNullValue(m_floatVecType); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *x = new ExtractElementInst(src, unsigned(0), - name("x"), m_block); - dst = InsertElementInst::Create(dst, x, unsigned(0), - name("dstx"), m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *y = new ExtractElementInst(src, unsigned(1), - name("y"), m_block); - dst = InsertElementInst::Create(dst, y, unsigned(1), - name("dsty"), m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *z = new ExtractElementInst(src, unsigned(2), - name("z"), m_block); - dst = InsertElementInst::Create(dst, z, unsigned(2), - name("dstz"), m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *w = new ExtractElementInst(src, unsigned(3), - name("w"), m_block); - dst = InsertElementInst::Create(dst, w, unsigned(3), - name("dstw"), m_block); - } - return dst; -} - -const char * Storage::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -int Storage::numConsts() const -{ - return m_numConsts; -} - -llvm::Value * Storage::addrElement(int idx) const -{ - Value *ret = m_addrs[idx]; - if (!ret) - return m_undefFloatVec; - return ret; -} - -void Storage::setAddrElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = m_addrs[idx]; - val = maskWrite(val, mask, templ); - } - m_addrs[idx] = val; -} - -llvm::Value * Storage::extractIndex(llvm::Value *vec) -{ - llvm::Value *x = new ExtractElementInst(vec, unsigned(0), - name("x"), m_block); - return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); -} - -void Storage::setCurrentBlock(llvm::BasicBlock *block) -{ - m_block = block; -} - -llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(DestsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("output"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value * Storage::inputPtr() const -{ - return m_INPUT; -} - -void Storage::pushArguments(llvm::Value *input) -{ - m_argStack.push(m_INPUT); - - m_INPUT = input; -} - -void Storage::popArguments() -{ - m_INPUT = m_argStack.top(); - m_argStack.pop(); -} - -void Storage::pushTemps() -{ - m_extSwizzleVec = 0; -} - -void Storage::popTemps() -{ -} - -llvm::Value * Storage::immediateElement(int idx) -{ - return m_immediates[idx]; -} - -void Storage::addImmediate(float *val) -{ - std::vector<Constant*> vec(4); - vec[0] = ConstantFP::get(APFloat(val[0])); - vec[1] = ConstantFP::get(APFloat(val[1])); - vec[2] = ConstantFP::get(APFloat(val[2])); - vec[3] = ConstantFP::get(APFloat(val[3])); - m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); -} - - -llvm::Value * Storage::elemPtr(Args arg) -{ - std::vector<Value*> indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast<int>(arg))); - GetElementPtrInst *getElem = GetElementPtrInst::Create(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); - return new LoadInst(getElem, name("input_field"), false, m_block); -} - -llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx ) -{ - GetElementPtrInst *getElem = 0; - - if (indIdx) { - getElem = GetElementPtrInst::Create(ptr, - BinaryOperator::Create(Instruction::Add, - indIdx, - constantInt(idx), - name("add"), - m_block), - name("field"), - m_block); - } else { - getElem = GetElementPtrInst::Create(ptr, - constantInt(idx), - name("field"), - m_block); - } - return getElem; -} - -llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) -{ - Value *val = elemPtr(arg); - return elemIdx(val, idx, indIdx); -} - -void Storage::setKilElement(llvm::Value *val) -{ - std::vector<Value*> indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast<int>(KilArg))); - GetElementPtrInst *elem = GetElementPtrInst::Create(m_INPUT, - indices.begin(), - indices.end(), - name("kil_ptr"), - m_block); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); -} - -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/gallivm/storage.h b/src/gallium/auxiliary/gallivm/storage.h deleted file mode 100644 index 8574f7554e..0000000000 --- a/src/gallium/auxiliary/gallivm/storage.h +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef STORAGE_H -#define STORAGE_H - -#include <map> -#include <set> -#include <stack> -#include <vector> - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class LoadInst; - class Value; - class VectorType; -} - -class Storage -{ -public: - Storage(llvm::BasicBlock *block, - llvm::Value *input); - - llvm::Value *inputPtr() const; - - void setCurrentBlock(llvm::BasicBlock *block); - - llvm::ConstantInt *constantInt(int); - llvm::Constant *shuffleMask(int vec); - llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *constElement(int idx, llvm::Value *indIdx =0); - llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); - llvm::Value *immediateElement(int idx); - - void setOutputElement(int dstIdx, llvm::Value *val, int mask); - void setTempElement(int idx, llvm::Value *val, int mask); - - llvm::Value *addrElement(int idx) const; - void setAddrElement(int idx, llvm::Value *val, int mask); - - void setKilElement(llvm::Value *val); - - llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); - - llvm::Value *extractIndex(llvm::Value *vec); - - int numConsts() const; - - void pushArguments(llvm::Value *input); - void popArguments(); - void pushTemps(); - void popTemps(); - - void addImmediate(float *val); - -private: - llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); - const char *name(const char *prefix); - - enum Args { - DestsArg = 0, - InputsArg = 1, - TempsArg = 2, - ConstsArg = 3, - KilArg = 4 - }; - llvm::Value *elemPtr(Args arg); - llvm::Value *elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx = 0); - llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); - -private: - llvm::BasicBlock *m_block; - llvm::Value *m_INPUT; - - std::map<int, llvm::ConstantInt*> m_constInts; - std::map<int, llvm::Constant*> m_intVecs; - std::vector<llvm::Value*> m_addrs; - std::vector<llvm::Constant*> m_immediates; - - llvm::VectorType *m_floatVecType; - llvm::VectorType *m_intVecType; - - char m_name[32]; - int m_idx; - - int m_numConsts; - - std::map<int, bool > m_destWriteMap; - std::map<int, bool > m_tempWriteMap; - - llvm::Value *m_undefFloatVec; - llvm::Value *m_undefIntVec; - llvm::Value *m_extSwizzleVec; - - std::stack<llvm::Value*> m_argStack; - std::stack<std::vector<llvm::Value*> > m_tempStack; -}; - -#endif diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp deleted file mode 100644 index 4984ce985c..0000000000 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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 "storagesoa.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include "util/u_debug.h" - -#include <llvm/BasicBlock.h> -#include <llvm/Module.h> -#include <llvm/Value.h> - -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/InstrTypes.h> -#include <llvm/Instructions.h> - -using namespace llvm; - - -StorageSoa::StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts) - : m_block(block), - m_input(input), - m_output(output), - m_consts(consts), - m_immediates(0), - m_idx(0) -{ -} - -void StorageSoa::addImmediate(float *vec) -{ - std::vector<float> vals(4); - vals[0] = vec[0]; - vals[1] = vec[1]; - vals[2] = vec[2]; - vals[3] = vec[3]; - m_immediatesToFlush.push_back(vals); -} - -void StorageSoa::declareImmediates() -{ - if (m_immediatesToFlush.empty()) - return; - - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorChannels = ArrayType::get(vectorType, 4); - ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); - - m_immediates = new GlobalVariable( - /*Type=*/arrayType, - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("immediates"), - currentModule()); - - std::vector<Constant*> arrayVals; - for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { - std::vector<float> vec = m_immediatesToFlush[i]; - std::vector<float> vals(4); - std::vector<Constant*> channelArray; - - vals[0] = vec[0]; vals[1] = vec[1]; vals[2] = vec[2]; vals[3] = vec[3]; - llvm::Constant *xChannel = createConstGlobalVector(vals); - - vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; - llvm::Constant *yChannel = createConstGlobalVector(vals); - - vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; - llvm::Constant *zChannel = createConstGlobalVector(vals); - - vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; - llvm::Constant *wChannel = createConstGlobalVector(vals); - channelArray.push_back(xChannel); - channelArray.push_back(yChannel); - channelArray.push_back(zChannel); - channelArray.push_back(wChannel); - Constant *constChannels = ConstantArray::get(vectorChannels, - channelArray); - arrayVals.push_back(constChannels); - } - Constant *constArray = ConstantArray::get(arrayType, arrayVals); - m_immediates->setInitializer(constArray); - - m_immediatesToFlush.clear(); -} - -llvm::Value *StorageSoa::addrElement(int idx) const -{ - std::map<int, llvm::Value*>::const_iterator itr = m_addresses.find(idx); - if (itr == m_addresses.end()) { - debug_printf("Trying to access invalid shader 'address'\n"); - return 0; - } - llvm::Value * res = (*itr).second; - - res = new LoadInst(res, name("addr"), false, m_block); - - return res; -} - -std::vector<llvm::Value*> StorageSoa::inputElement(llvm::Value *idx) -{ - std::vector<llvm::Value*> res(4); - - res[0] = element(m_input, idx, 0); - res[1] = element(m_input, idx, 1); - res[2] = element(m_input, idx, 2); - res[3] = element(m_input, idx, 3); - - return res; -} - -llvm::Value* StorageSoa::unpackConstElement(llvm::IRBuilder<>* m_builder, llvm::Value* vector, int cc) -{ - std::vector<llvm::Value*> x(4); - x[0] = m_builder->CreateExtractElement(vector, - constantInt(cc), - name("x")); - - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - Constant *constVector = Constant::getNullValue(vectorType); - Value *res = m_builder->CreateInsertElement(constVector, x[0], - constantInt(0), - name("vecx")); - res = m_builder->CreateInsertElement(res, x[0], constantInt(1), - name("vecxx")); - res = m_builder->CreateInsertElement(res, x[0], constantInt(2), - name("vecxxx")); - res = m_builder->CreateInsertElement(res, x[0], constantInt(3), - name("vecxxxx")); - return res; -} - -std::vector<llvm::Value*> StorageSoa::constElement(llvm::IRBuilder<>* m_builder, llvm::Value *idx) -{ - llvm::Value* res; - std::vector<llvm::Value*> res2(4); - llvm::Value *xChannel; - - xChannel = elementPointer(m_consts, idx, 0); - - res = alignedArrayLoad(xChannel); - - res2[0]=unpackConstElement(m_builder, res,0); - res2[1]=unpackConstElement(m_builder, res,1); - res2[2]=unpackConstElement(m_builder, res,2); - res2[3]=unpackConstElement(m_builder, res,3); - - return res2; -} - -std::vector<llvm::Value*> StorageSoa::outputElement(llvm::Value *idx) -{ - std::vector<llvm::Value*> res(4); - - res[0] = element(m_output, idx, 0); - res[1] = element(m_output, idx, 1); - res[2] = element(m_output, idx, 2); - res[3] = element(m_output, idx, 3); - - return res; -} - -std::vector<llvm::Value*> StorageSoa::tempElement(llvm::IRBuilder<>* m_builder, int idx) -{ - std::vector<llvm::Value*> res(4); - llvm::Value *temp = m_temps[idx]; - - res[0] = element(temp, constantInt(0), 0); - res[1] = element(temp, constantInt(0), 1); - res[2] = element(temp, constantInt(0), 2); - res[3] = element(temp, constantInt(0), 3); - - return res; -} - -std::vector<llvm::Value*> StorageSoa::immediateElement(llvm::Value *idx) -{ - std::vector<llvm::Value*> res(4); - - res[0] = element(m_immediates, idx, 0); - res[1] = element(m_immediates, idx, 1); - res[2] = element(m_immediates, idx, 2); - res[3] = element(m_immediates, idx, 3); - - return res; -} - -llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - std::vector<Value*> indices; - if (m_immediates == ptr) - indices.push_back(constantInt(0)); - indices.push_back(index); - indices.push_back(constantInt(channel)); - - GetElementPtrInst *getElem = GetElementPtrInst::Create(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); - return getElem; -} - -llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - llvm::Value *res = elementPointer(ptr, index, channel); - LoadInst *load = new LoadInst(res, name("element"), false, m_block); - //load->setAlignment(8); - return load; -} - -const char * StorageSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::ConstantInt * StorageSoa::constantInt(int idx) const -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = constInt; - return constInt; -} - -llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - PointerType *vectorPtr = PointerType::get(vectorType, 0); - - CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); - LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Module * StorageSoa::currentModule() const -{ - if (!m_block || !m_block->getParent()) - return 0; - - return m_block->getParent()->getParent(); -} - -llvm::Constant * StorageSoa::createConstGlobalFloat(const float val) -{ - Constant*c = ConstantFP::get(APFloat(val)); - return c; -} - -llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector<float> &vec) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - std::vector<Constant*> immValues; - ConstantFP *constx = ConstantFP::get(APFloat(vec[0])); - ConstantFP *consty = ConstantFP::get(APFloat(vec[1])); - ConstantFP *constz = ConstantFP::get(APFloat(vec[2])); - ConstantFP *constw = ConstantFP::get(APFloat(vec[3])); - immValues.push_back(constx); - immValues.push_back(consty); - immValues.push_back(constz); - immValues.push_back(constw); - Constant *constVector = ConstantVector::get(vectorType, immValues); - - return constVector; -} - -std::vector<llvm::Value*> StorageSoa::load(enum tgsi_file_type type, int idx, int swizzle, - llvm::IRBuilder<>* m_builder,llvm::Value *indIdx) -{ - std::vector<llvm::Value*> val(4); - - //if we have an indirect index, always use that - // if not use the integer offset to create one - llvm::Value *realIndex = 0; - if (indIdx) - realIndex = indIdx; - else - realIndex = constantInt(idx); - debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); - - switch(type) { - case TGSI_FILE_INPUT: - val = inputElement(realIndex); - break; - case TGSI_FILE_OUTPUT: - val = outputElement(realIndex); - break; - case TGSI_FILE_TEMPORARY: - val = tempElement(m_builder, idx); - break; - case TGSI_FILE_CONSTANT: - val = constElement(m_builder, realIndex); - break; - case TGSI_FILE_IMMEDIATE: - val = immediateElement(realIndex); - break; - case TGSI_FILE_ADDRESS: - debug_printf("Address not handled in the load phase!\n"); - assert(0); - break; - default: - debug_printf("Unknown load!\n"); - assert(0); - break; - } - if (!gallivm_is_swizzle(swizzle)) - return val; - - std::vector<llvm::Value*> res(4); - - res[0] = val[gallivm_x_swizzle(swizzle)]; - res[1] = val[gallivm_y_swizzle(swizzle)]; - res[2] = val[gallivm_z_swizzle(swizzle)]; - res[3] = val[gallivm_w_swizzle(swizzle)]; - return res; -} - -llvm::Value * StorageSoa::allocaTemp(llvm::IRBuilder<>* m_builder) -{ - VectorType *vector = VectorType::get(Type::FloatTy, 4); - ArrayType *vecArray = ArrayType::get(vector, 4); - AllocaInst *alloca = new AllocaInst(vecArray, "temp", - m_builder->GetInsertBlock()); - - return alloca; -} - - -void StorageSoa::store(enum tgsi_file_type type, int idx, const std::vector<llvm::Value*> &val, - int mask, llvm::IRBuilder<>* m_builder) -{ - llvm::Value *out = 0; - llvm::Value *realIndex = 0; - switch(type) { - case TGSI_FILE_OUTPUT: - out = m_output; - realIndex = constantInt(idx); - break; - case TGSI_FILE_TEMPORARY: - // if that temp doesn't already exist, alloca it - if (m_temps.find(idx) == m_temps.end()) - m_temps[idx] = allocaTemp(m_builder); - - out = m_temps[idx]; - - realIndex = constantInt(0); - break; - case TGSI_FILE_INPUT: - out = m_input; - realIndex = constantInt(idx); - break; - case TGSI_FILE_ADDRESS: { - llvm::Value *addr = m_addresses[idx]; - if (!addr) { - addAddress(idx); - addr = m_addresses[idx]; - assert(addr); - } - new StoreInst(val[0], addr, false, m_block); - return; - break; - } - default: - debug_printf("Can't save output of this type: %d !\n", type); - assert(0); - break; - } - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *xChannel = elementPointer(out, realIndex, 0); - new StoreInst(val[0], xChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *yChannel = elementPointer(out, realIndex, 1); - new StoreInst(val[1], yChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *zChannel = elementPointer(out, realIndex, 2); - new StoreInst(val[2], zChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *wChannel = elementPointer(out, realIndex, 3); - new StoreInst(val[3], wChannel, false, m_block); - } -} - -void StorageSoa::addAddress(int idx) -{ - GlobalVariable *val = new GlobalVariable( - /*Type=*/IntegerType::get(32), - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("address"), - currentModule()); - val->setInitializer(Constant::getNullValue(IntegerType::get(32))); - - debug_printf("adding to %d\n", idx); - m_addresses[idx] = val; -} diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h deleted file mode 100644 index 56886f85e7..0000000000 --- a/src/gallium/auxiliary/gallivm/storagesoa.h +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -#ifndef STORAGESOA_H -#define STORAGESOA_H - -#include <pipe/p_shader_tokens.h> -#include <llvm/Support/IRBuilder.h> - -#include <vector> -#include <list> -#include <map> - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class GlobalVariable; - class LoadInst; - class Value; - class VectorType; - class Module; -} - -class StorageSoa -{ -public: - StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts); - - - std::vector<llvm::Value*> load(enum tgsi_file_type type, int idx, int swizzle, - llvm::IRBuilder<>* m_builder, llvm::Value *indIdx =0); - void store(enum tgsi_file_type type, int idx, const std::vector<llvm::Value*> &val, - int mask, llvm::IRBuilder<>* m_builder); - - void addImmediate(float *vec); - void declareImmediates(); - - void addAddress(int idx); - - llvm::Value * addrElement(int idx) const; - - llvm::ConstantInt *constantInt(int) const; -private: - llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, - int channel) const; - llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, - int channel) const; - const char *name(const char *prefix) const; - llvm::Value *alignedArrayLoad(llvm::Value *val); - llvm::Module *currentModule() const; - llvm::Constant *createConstGlobalFloat(const float val); - llvm::Constant *createConstGlobalVector(const std::vector<float> &vec); - - std::vector<llvm::Value*> inputElement(llvm::Value *indIdx); - llvm::Value* unpackConstElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx, int cc); - std::vector<llvm::Value*> constElement(llvm::IRBuilder<>* m_builder, llvm::Value *indIdx); - std::vector<llvm::Value*> outputElement(llvm::Value *indIdx); - std::vector<llvm::Value*> tempElement(llvm::IRBuilder<>* m_builder, int idx); - std::vector<llvm::Value*> immediateElement(llvm::Value *indIdx); -private: - llvm::BasicBlock *m_block; - - llvm::Value *m_input; - llvm::Value *m_output; - llvm::Value *m_consts; - std::map<int, llvm::Value*> m_temps; - llvm::GlobalVariable *m_immediates; - - std::map<int, llvm::Value*> m_addresses; - - std::vector<std::vector<float> > m_immediatesToFlush; - llvm::Value * allocaTemp(llvm::IRBuilder<>* m_builder); - - mutable std::map<int, llvm::ConstantInt*> m_constInts; - mutable char m_name[32]; - mutable int m_idx; -}; - -#endif diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp deleted file mode 100644 index 8f7d3b7100..0000000000 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ /dev/null @@ -1,1136 +0,0 @@ -#include "tgsitollvm.h" - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "storage.h" -#include "instructions.h" -#include "storagesoa.h" -#include "instructionssoa.h" - -#include "pipe/p_shader_tokens.h" - -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_exec.h" -#include "tgsi/tgsi_util.h" -#include "tgsi/tgsi_build.h" -#include "tgsi/tgsi_dump.h" - - -#include <llvm/Module.h> -#include <llvm/CallingConv.h> -#include <llvm/Constants.h> -#include <llvm/DerivedTypes.h> -#include <llvm/Instructions.h> -#include <llvm/ModuleProvider.h> -#include <llvm/Pass.h> -#include <llvm/PassManager.h> -#include <llvm/Attributes.h> -#include <llvm/Support/PatternMatch.h> -#include <llvm/ExecutionEngine/JIT.h> -#include <llvm/ExecutionEngine/Interpreter.h> -#include <llvm/ExecutionEngine/GenericValue.h> -#include <llvm/Support/MemoryBuffer.h> -#include <llvm/LinkAllPasses.h> -#include <llvm/Analysis/Verifier.h> -#include <llvm/Analysis/LoopPass.h> -#include <llvm/Target/TargetData.h> -#include <llvm/Bitcode/ReaderWriter.h> -#include <llvm/Transforms/Utils/Cloning.h> - - -#include <sstream> -#include <fstream> -#include <iostream> - -using namespace llvm; - -static inline FunctionType *vertexShaderFunctionType() -{ - //Function takes three arguments, - // the calling code has to make sure the types it will - // pass are castable to the following: - // [4 x <4 x float>] inputs, - // [4 x <4 x float>] output, - // [4 x [1 x float]] consts, - - std::vector<const Type*> funcArgs; - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorArray = ArrayType::get(vectorType, 4); - PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); - - ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); - ArrayType *constsArray = ArrayType::get(floatArray, 1); - PointerType *constsArrayPtr = PointerType::get(constsArray, 0); - - funcArgs.push_back(vectorArrayPtr);//inputs - funcArgs.push_back(vectorArrayPtr);//output - funcArgs.push_back(constsArrayPtr);//consts - - FunctionType *functionType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/funcArgs, - /*isVarArg=*/false); - - return functionType; -} - -static inline void -add_interpolator(struct gallivm_ir *ir, - struct gallivm_interpolate *interp) -{ - ir->interpolators[ir->num_interp] = *interp; - ++ir->num_interp; -} - -static void -translate_declaration(struct gallivm_ir *prog, - llvm::Module *module, - Storage *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *fd) -{ - if (decl->Declaration.File == TGSI_FILE_INPUT) { - unsigned first, last, mask; - uint interp_method; - - first = decl->Range.First; - last = decl->Range.Last; - mask = decl->Declaration.UsageMask; - - /* Do not touch WPOS.xy */ - if (first == 0) { - mask &= ~TGSI_WRITEMASK_XY; - if (mask == TGSI_WRITEMASK_NONE) { - first++; - if (first > last) { - return; - } - } - } - - interp_method = decl->Declaration.Interpolate; - - if (mask == TGSI_WRITEMASK_XYZW) { - unsigned i, j; - - for (i = first; i <= last; i++) { - for (j = 0; j < NUM_CHANNELS; j++) { - //interp( mach, i, j ); - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } else { - unsigned i, j; - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } - } - } -} - -static void -translate_declarationir(struct gallivm_ir *, - llvm::Module *, - StorageSoa *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *) -{ - if (decl->Declaration.File == TGSI_FILE_ADDRESS) { - int idx = decl->Range.First; - storage->addAddress(idx); - } -} - -static void -translate_immediate(Storage *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - assert( imm->Immediate.NrTokens <= 4 + 1 ); - for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - - -static void -translate_immediateir(StorageSoa *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - assert( imm->Immediate.NrTokens <= 4 + 1 ); - for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - -static inline int -swizzleInt(struct tgsi_full_src_register *src) -{ - int swizzle = 0; - int start = 1000; - - for (int k = 0; k < 4; ++k) { - swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; - start /= 10; - } - return swizzle; -} - -static inline llvm::Value * -swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, - Storage *storage) -{ - int swizzle = swizzleInt(src); - - if (gallivm_is_swizzle(swizzle)) { - /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ - val = storage->shuffleVector(val, swizzle); - } - return val; -} - -static void -translate_instruction(llvm::Module *module, - Storage *storage, - Instructions *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - llvm::Value *inputs[4]; - inputs[0] = 0; - inputs[1] = 0; - inputs[2] = 0; - inputs[3] = 0; - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->Src[i]; - llvm::Value *val = 0; - llvm::Value *indIdx = 0; - - if (src->Register.Indirect) { - indIdx = storage->addrElement(src->Indirect.Index); - indIdx = storage->extractIndex(indIdx); - } - if (src->Register.File == TGSI_FILE_CONSTANT) { - val = storage->constElement(src->Register.Index, indIdx); - } else if (src->Register.File == TGSI_FILE_INPUT) { - val = storage->inputElement(src->Register.Index, indIdx); - } else if (src->Register.File == TGSI_FILE_TEMPORARY) { - val = storage->tempElement(src->Register.Index); - } else if (src->Register.File == TGSI_FILE_OUTPUT) { - val = storage->outputElement(src->Register.Index, indIdx); - } else if (src->Register.File == TGSI_FILE_IMMEDIATE) { - val = storage->immediateElement(src->Register.Index); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->Register.File); - return; - } - - inputs[i] = swizzleVector(val, src, storage); - } - - /*if (inputs[0]) - instr->printVector(inputs[0]); - if (inputs[1]) - instr->printVector(inputs[1]);*/ - llvm::Value *out = 0; - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - out = instr->lit(inputs[0]); - } - break; - case TGSI_OPCODE_RCP: { - out = instr->rcp(inputs[0]); - } - break; - case TGSI_OPCODE_RSQ: { - out = instr->rsq(inputs[0]); - } - break; - case TGSI_OPCODE_EXP: { - out = instr->exp(inputs[0]); - } - break; - case TGSI_OPCODE_LOG: { - out = instr->log(inputs[0]); - } - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - out = instr->dp3(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP4: { - out = instr->dp4(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DST: { - out = instr->dst(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MIN: { - out = instr->min(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAX: { - out = instr->max(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SLT: { - out = instr->slt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGE: { - out = instr->sge(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - out = instr->sub(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_LRP: { - out = instr->lerp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_CND: { - out = instr->cnd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_CND0: { - out = instr->cnd0(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_DP2A: { - out = instr->dot2add(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_FRC: { - out = instr->frc(inputs[0]); - } - break; - case TGSI_OPCODE_CLAMP: { - out = instr->clamp(inputs[0]); - } - break; - case TGSI_OPCODE_FLR: { - out = instr->floor(inputs[0]); - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EX2: { - out = instr->ex2(inputs[0]); - } - break; - case TGSI_OPCODE_LG2: { - out = instr->lg2(inputs[0]); - } - break; - case TGSI_OPCODE_POW: { - out = instr->pow(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_XPD: { - out = instr->cross(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ABS: { - out = instr->abs(inputs[0]); - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - out = instr->dph(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_COS: { - out = instr->cos(inputs[0]); - } - break; - case TGSI_OPCODE_DDX: { - out = instr->ddx(inputs[0]); - } - break; - case TGSI_OPCODE_DDY: { - out = instr->ddy(inputs[0]); - } - break; - case TGSI_OPCODE_KILP: - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: { - out = instr->seq(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SFL: { - out = instr->sfl(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGT: { - out = instr->sgt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SIN: { - out = instr->sin(inputs[0]); - } - break; - case TGSI_OPCODE_SLE: { - out = instr->sle(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SNE: { - out = instr->sne(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_STR: { - out = instr->str(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: { - out = instr->x2d(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); - return; - } - break; - case TGSI_OPCODE_RET: { - instr->end(); - return; - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - out = instr->cmp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SCS: { - out = instr->scs(inputs[0]); - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM4: - case TGSI_OPCODE_NRM: { - out = instr->nrm(inputs[0]); - } - break; - case TGSI_OPCODE_DIV: { - out = instr->div(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP2: { - out = instr->dp2(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - instr->brk(); - return; - } - break; - case TGSI_OPCODE_IF: { - instr->ifop(inputs[0]); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_BGNFOR: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - instr->elseop(); - storage->setCurrentBlock(instr->currentBlock()); - return; //only state update - } - break; - case TGSI_OPCODE_ENDIF: { - instr->endif(); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_ENDFOR: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - out = instr->trunc(inputs[0]); - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_ISHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP: { - instr->beginLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_BGNSUB: { - instr->bgnSub(instno); - storage->setCurrentBlock(instr->currentBlock()); - storage->pushTemps(); - return; - } - break; - case TGSI_OPCODE_ENDLOOP: { - instr->endLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_ENDSUB: { - instr->endSub(); - storage->setCurrentBlock(instr->currentBlock()); - storage->popArguments(); - storage->popTemps(); - return; - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: { - out = instr->kil(inputs[0]); - storage->setKilElement(out); - return; - } - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* # not sure if we need this */ - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - /*TXT( "_SAT" );*/ - break; - case TGSI_SAT_MINUS_PLUS_ONE: - /*TXT( "_SAT[-1,1]" );*/ - break; - default: - assert( 0 ); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->Dst[i]; - - if (dst->Register.File == TGSI_FILE_OUTPUT) { - storage->setOutputElement(dst->Register.Index, out, dst->Register.WriteMask); - } else if (dst->Register.File == TGSI_FILE_TEMPORARY) { - storage->setTempElement(dst->Register.Index, out, dst->Register.WriteMask); - } else if (dst->Register.File == TGSI_FILE_ADDRESS) { - storage->setAddrElement(dst->Register.Index, out, dst->Register.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - - -static void -translate_instructionir(llvm::Module *module, - StorageSoa *storage, - InstructionsSoa *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - std::vector< std::vector<llvm::Value*> > inputs(inst->Instruction.NumSrcRegs); - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->Src[i]; - std::vector<llvm::Value*> val; - llvm::Value *indIdx = 0; - int swizzle = swizzleInt(src); - - if (src->Register.Indirect) { - indIdx = storage->addrElement(src->Indirect.Index); - } - val = storage->load((enum tgsi_file_type)src->Register.File, - src->Register.Index, swizzle, instr->getIRBuilder(), indIdx); - - inputs[i] = val; - } - - std::vector<llvm::Value*> out(4); - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - out = instr->lit(inputs[0]); - } - break; - case TGSI_OPCODE_RCP: { - } - break; - case TGSI_OPCODE_RSQ: { - out = instr->rsq(inputs[0]); - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - out = instr->dp3(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP4: { - out = instr->dp4(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DST: { - } - break; - case TGSI_OPCODE_MIN: { - out = instr->min(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAX: { - out = instr->max(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SLT: { - out = instr->slt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGE: { - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - out = instr->sub(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_LRP: { - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DP2A: - break; - case TGSI_OPCODE_FRC: { - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLR: { - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EX2: { - } - break; - case TGSI_OPCODE_LG2: { - } - break; - case TGSI_OPCODE_POW: { - out = instr->pow(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_XPD: { - } - break; - case TGSI_OPCODE_ABS: { - out = instr->abs(inputs[0]); - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - } - break; - case TGSI_OPCODE_COS: { - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - } - break; - case TGSI_OPCODE_SIN: { - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - } - break; - case TGSI_OPCODE_RET: { - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - } - break; - case TGSI_OPCODE_SCS: { - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - } - break; - case TGSI_OPCODE_IF: { - } - break; - case TGSI_OPCODE_BGNFOR: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - } - break; - case TGSI_OPCODE_ENDIF: { - } - break; - case TGSI_OPCODE_ENDFOR: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_ISHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP: { - } - break; - case TGSI_OPCODE_BGNSUB: { - } - break; - case TGSI_OPCODE_ENDLOOP: { - } - break; - case TGSI_OPCODE_ENDSUB: { - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: { - } - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out[0]) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->Dst[i]; - storage->store((enum tgsi_file_type)dst->Register.File, - dst->Register.Index, out, dst->Register.WriteMask, - instr->getIRBuilder() ); - } -} - -llvm::Module * -tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - Function* shader = mod->getFunction("execute_shader"); - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - stream << ir->id; - std::string func_name = stream.str(); - shader->setName(func_name.c_str()); - - Function::arg_iterator args = shader->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("input"); - - BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - Storage storage(label_entry, ptr_INPUT); - Instructions instr(mod, shader, label_entry, &storage); - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declaration(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediate(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - translate_instruction(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - ir->num_consts = storage.numConsts(); - return mod; -} - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - //stream << ir->id; - std::string func_name = stream.str(); - Function *shader = llvm::cast<Function>(mod->getOrInsertFunction( - func_name.c_str(), - vertexShaderFunctionType())); - - Function::arg_iterator args = shader->arg_begin(); - Value *input = args++; - input->setName("inputs"); - Value *output = args++; - output->setName("outputs"); - Value *consts = args++; - consts->setName("consts"); - - BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - StorageSoa storage(label_entry, input, output, consts); - InstructionsSoa instr(mod, shader, label_entry, &storage); - - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declarationir(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediateir(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - storage.declareImmediates(); - translate_instructionir(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - return mod; -} diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.h b/src/gallium/auxiliary/gallivm/tgsitollvm.h deleted file mode 100644 index 7ada04d629..0000000000 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TGSITOLLVM_H -#define TGSITOLLVM_H - - -namespace llvm { - class Module; -} - -struct gallivm_ir; -struct tgsi_token; - - -llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - -#endif diff --git a/src/gallium/auxiliary/os/os_memory.h b/src/gallium/auxiliary/os/os_memory.h new file mode 100644 index 0000000000..556662d35e --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory.h @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * OS memory management abstractions + */ + + +#ifndef _OS_MEMORY_H_ +#define _OS_MEMORY_H_ + + +#include "pipe/p_config.h" +#include "pipe/p_compiler.h" + + +#if defined(PIPE_OS_EMBEDDED) + +#ifdef __cplusplus +extern "C" { +#endif + +void * +os_malloc(size_t size); + +void * +os_calloc(size_t count, size_t size); + +void +os_free(void *ptr); + +void * +os_realloc(void *ptr, size_t old_size, size_t new_size); + +void * +os_malloc_aligned(size_t size, size_t alignment); + +void +os_free_aligned(void *ptr); + +#ifdef __cplusplus +} +#endif + +#elif defined(PIPE_OS_WINDOWS) && defined(DEBUG) && !defined(DEBUG_MEMORY_IMPLEMENTATION) + +# include "os_memory_debug.h" + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +# include "os_memory_win32k.h" + +#else + +# include "os_memory_stdc.h" + +#endif + +#endif /* _OS_MEMORY_H_ */ diff --git a/src/gallium/auxiliary/os/os_memory_aligned.h b/src/gallium/auxiliary/os/os_memory_aligned.h new file mode 100644 index 0000000000..72c5cf65b6 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_aligned.h @@ -0,0 +1,72 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Memory alignment wrappers. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +/** + * Return memory on given byte alignment + */ +static INLINE void * +os_malloc_aligned(size_t size, size_t alignment) +{ + char *ptr, *buf; + + ptr = (char *) os_malloc(size + alignment + sizeof(void *)); + if (!ptr) + return NULL; + + buf = (char *)(((uintptr_t)ptr + sizeof(void *) + alignment - 1) & ~((uintptr_t)(alignment - 1))); + *(char **)(buf - sizeof(void *)) = ptr; + + return buf; +} + + +/** + * Free memory returned by align_malloc(). + */ +static INLINE void +os_free_aligned(void *ptr) +{ + if (ptr) { + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + os_free(realAddr); + } +} diff --git a/src/gallium/auxiliary/os/os_memory_debug.h b/src/gallium/auxiliary/os/os_memory_debug.h new file mode 100644 index 0000000000..c664be9aad --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_debug.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Debugging wrappers for OS memory management abstractions. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size); + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ); + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr); + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ); + + +#ifdef __cplusplus +} +#endif + + +#ifndef DEBUG_MEMORY_IMPLEMENTATION + +#define os_malloc( _size ) \ + debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) +#define os_calloc( _count, _size ) \ + debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) +#define os_free( _ptr ) \ + debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) +#define os_realloc( _ptr, _old_size, _new_size ) \ + debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _new_size ) + +/* TODO: wrap os_malloc_aligned() and os_free_aligned() too */ +#include "os_memory_aligned.h" + +#endif /* !DEBUG_MEMORY_IMPLEMENTATION */ diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/auxiliary/os/os_memory_stdc.h index 161bab3799..806e536356 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.h +++ b/src/gallium/auxiliary/os/os_memory_stdc.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,54 +18,59 @@ * 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 + * IN NO EVENT SHALL VMWARE 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. * **************************************************************************/ -#ifndef LP_TILE_CACHE_H -#define LP_TILE_CACHE_H +/* + * OS memory management abstractions for the standard C library. + */ -#include "pipe/p_compiler.h" -#include "lp_tile_soa.h" +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + +#include <stdlib.h> -struct llvmpipe_tile_cache; /* opaque */ +#include "pipe/p_compiler.h" -extern struct llvmpipe_tile_cache * -lp_create_tile_cache( struct pipe_screen *screen ); +#define os_malloc(_size) malloc(_size) +#define os_calloc(_count, _size ) calloc(_count, _size ) +#define os_free(_ptr) free(_ptr) -extern void -lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc); +#define os_realloc( _old_ptr, _old_size, _new_size) \ + realloc(_old_ptr, _new_size + 0*(_old_size)) -extern void -lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc, - struct pipe_surface *lps); -extern struct pipe_surface * -lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc); +#if defined(HAVE_POSIX_MEMALIGN) -extern void -lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc); +static INLINE void * +os_malloc_aligned(size_t size, size_t alignment) +{ + void *ptr; + alignment = (alignment + sizeof(void*) - 1) & ~(sizeof(void*) - 1); + if(posix_memalign(&ptr, alignment, size) != 0) + return NULL; + return ptr; +} -extern void -lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc); +#define os_free_aligned(_ptr) free(_ptr) -extern void -lp_flush_tile_cache(struct llvmpipe_tile_cache *tc); +#elif defined(PIPE_OS_WINDOWS) -extern void -lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba, - uint clearValue); +#include <malloc.h> -extern void * -lp_get_cached_tile(struct llvmpipe_tile_cache *tc, - unsigned x, unsigned y ); +#define os_malloc_aligned(_size, _align) _aligned_malloc(_size, _align) +#define os_free_aligned(_ptr) _aligned_free(_ptr) +#else -#endif /* LP_TILE_CACHE_H */ +#include "os_memory_aligned.h" +#endif diff --git a/src/gallium/auxiliary/os/os_memory_win32k.h b/src/gallium/auxiliary/os/os_memory_win32k.h new file mode 100644 index 0000000000..d56d690872 --- /dev/null +++ b/src/gallium/auxiliary/os/os_memory_win32k.h @@ -0,0 +1,123 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * OS memory management abstractions for Windows kernel. + */ + + +#ifndef _OS_MEMORY_H_ +#error "Must not be included directly. Include os_memory.h instead" +#endif + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void * __stdcall +EngAllocMem(unsigned long Flags, + unsigned long MemSize, + unsigned long Tag); + +void __stdcall +EngFreeMem(void *Mem); + +#define os_malloc(_size) EngAllocMem(0, _size, 'D3AG') +#define os_calloc(_count, _size) EngAllocMem(1, (_count)*(_size), 'D3AG') +#define _os_free(_ptr) EngFreeMem(_ptr) + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +void * +ExAllocatePool(unsigned long PoolType, + size_t NumberOfBytes); + +void +ExFreePool(void *P); + +#define os_malloc(_size) ExAllocatePool(0, _size) +#define _os_free(_ptr) ExFreePool(_ptr) + +static INLINE void * +os_calloc(unsigned count, unsigned size) +{ + void *ptr = os_malloc(count * size); + if (ptr) { + memset(ptr, 0, count * size); + } + return ptr; +} + +#else + +#error "Unsupported subsystem" + +#endif + + +static INLINE void +os_free( void *ptr ) +{ + if (ptr) { + _os_free(ptr); + } +} + + +static INLINE void * +os_realloc(void *old_ptr, unsigned old_size, unsigned new_size) +{ + void *new_ptr = NULL; + + if (new_size != 0) { + unsigned copy_size = old_size < new_size ? old_size : new_size; + new_ptr = os_malloc( new_size ); + if (new_ptr && old_ptr && copy_size) { + memcpy(new_ptr, old_ptr, copy_size); + } + } + + os_free(old_ptr); + + return new_ptr; +} + + +#ifdef __cplusplus +} +#endif + + +#include "os_memory_aligned.h" diff --git a/src/gallium/auxiliary/os/os_misc.c b/src/gallium/auxiliary/os/os_misc.c new file mode 100644 index 0000000000..384988017b --- /dev/null +++ b/src/gallium/auxiliary/os/os_misc.c @@ -0,0 +1,188 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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 "os_misc.h" + +#include <stdarg.h> + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + +#include <windows.h> +#include <winddi.h> + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + +#include <stdio.h> +#include <stdlib.h> +#include <windows.h> +#include <types.h> + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif +#include <windows.h> +#include <stdio.h> + +#else + +#include <stdio.h> +#include <stdlib.h> + +#endif + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +static INLINE void +_EngDebugPrint(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + EngDebugPrint("", (PCHAR)format, ap); + va_end(ap); +} +#endif + + +void +os_log_message(const char *message) +{ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + _EngDebugPrint("%s", message); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + OutputDebugStringA(message); + if(GetConsoleWindow() && !IsDebuggerPresent()) { + fflush(stdout); + fputs(message, stderr); + fflush(stderr); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + wchar_t *wide_format; + long wide_str_len; + /* Format is ascii - needs to be converted to wchar_t for printing */ + wide_str_len = MultiByteToWideChar(CP_ACP, 0, message, -1, NULL, 0); + wide_format = (wchar_t *) malloc((wide_str_len+1) * sizeof(wchar_t)); + if (wide_format) { + MultiByteToWideChar(CP_ACP, 0, message, -1, + wide_format, wide_str_len); + NKDbgPrintfW(wide_format, wide_format); + free(wide_format); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* TODO */ +#else /* !PIPE_SUBSYSTEM_WINDOWS */ + fflush(stdout); + fputs(message, stderr); +#endif +} + + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +static const char * +find(const char *start, const char *end, char c) +{ + const char *p; + for(p = start; !end || p != end; ++p) { + if(*p == c) + return p; + if(*p < 32) + break; + } + return NULL; +} + +static int +compare(const char *start, const char *end, const char *s) +{ + const char *p, *q; + for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { + if(*p != *q) + return 0; + } + return p == end && *q == '\0'; +} + +static void +copy(char *dst, const char *start, const char *end, size_t n) +{ + const char *p; + char *q; + for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) + *q = *p; + *q = '\0'; +} +#endif + + +const char * +os_get_option(const char *name) +{ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + /* EngMapFile creates the file if it does not exists, so it must either be + * disabled on release versions (or put in a less conspicuous place). */ +#ifdef DEBUG + const char *result = NULL; + ULONG_PTR iFile = 0; + const void *pMap = NULL; + const char *sol, *eol, *sep; + static char output[1024]; + + pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); + if(pMap) { + sol = (const char *)pMap; + while(1) { + /* TODO: handle LF line endings */ + eol = find(sol, NULL, '\r'); + if(!eol || eol == sol) + break; + sep = find(sol, eol, '='); + if(!sep) + break; + if(compare(sol, sep, name)) { + copy(output, sep + 1, eol, sizeof(output)); + result = output; + break; + } + sol = eol + 2; + } + EngUnmapFile(iFile); + } + return result; +#else + return NULL; +#endif +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* TODO: implement */ + return NULL; +#else + return getenv(name); +#endif +} + diff --git a/src/gallium/auxiliary/os/os_misc.h b/src/gallium/auxiliary/os/os_misc.h new file mode 100644 index 0000000000..d59f9819fe --- /dev/null +++ b/src/gallium/auxiliary/os/os_misc.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2010 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 VMWARE 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. + * + **************************************************************************/ + + +/* + * Miscellaneous OS services. + */ + + +#ifndef _OS_MISC_H_ +#define _OS_MISC_H_ + + +#include "pipe/p_compiler.h" + + +#if defined(PIPE_OS_UNIX) +# include <signal.h> /* for kill() */ +# include <unistd.h> /* getpid() */ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Trap into the debugger. + */ +#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) +# define os_break() __asm("int3") +#elif defined(PIPE_CC_MSVC) +# define os_break() __debugbreak() +#elif defined(PIPE_OS_UNIX) +# define os_break() kill(getpid(), SIGTRAP) +#elif defined(PIPE_OS_EMBEDDED) +void os_break(void); +#else +# define os_break() abort() +#endif + + +/* + * Abort the program. + */ +#if defined(DEBUG) || defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +# define os_abort() os_break() +#elif defined(PIPE_OS_EMBEDDED) +void os_abort(void); +#else +# define os_abort() abort() +#endif + + +/* + * Output a message. Message should preferably end in a newline. + */ +void +os_log_message(const char *message); + + +/* + * Get an option. Should return NULL if specified option is not set. + */ +const char * +os_get_option(const char *name); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _OS_MISC_H_ */ diff --git a/src/gallium/auxiliary/util/u_stream.h b/src/gallium/auxiliary/os/os_stream.h index a9d0f0121a..bf30e6542d 100644 --- a/src/gallium/auxiliary/util/u_stream.h +++ b/src/gallium/auxiliary/os/os_stream.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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 + * IN NO EVENT SHALL VMWARE 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. @@ -30,14 +30,14 @@ * Cross-platform sequential access stream abstraction. */ -#ifndef U_STREAM_H -#define U_STREAM_H +#ifndef _OS_STREAM_H_ +#define _OS_STREAM_H_ #include "pipe/p_compiler.h" -struct util_stream; +struct os_stream; /** @@ -45,17 +45,17 @@ struct util_stream; * @param filename relative or absolute path (necessary for windows) * @param optional maximum file size (0 for a growable size). */ -struct util_stream * -util_stream_create(const char *filename, size_t max_size); +struct os_stream * +os_stream_create(const char *filename, size_t max_size); boolean -util_stream_write(struct util_stream *stream, const void *data, size_t size); +os_stream_write(struct os_stream *stream, const void *data, size_t size); void -util_stream_flush(struct util_stream *stream); +os_stream_flush(struct os_stream *stream); void -util_stream_close(struct util_stream *stream); +os_stream_close(struct os_stream *stream); -#endif /* U_STREAM_H */ +#endif /* _OS_STREAM_H_ */ diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/os/os_stream_stdc.c index 4d976d6dca..caa60c0b50 100644 --- a/src/gallium/auxiliary/util/u_stream_stdc.c +++ b/src/gallium/auxiliary/os/os_stream_stdc.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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 + * IN NO EVENT SHALL VMWARE 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. @@ -32,47 +32,46 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE) +#if defined(PIPE_OS_UNIX) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) +#include <stdlib.h> #include <stdio.h> -#include "util/u_memory.h" +#include "os_stream.h" -#include "u_stream.h" - -struct util_stream +struct os_stream { FILE *file; }; -struct util_stream * -util_stream_create(const char *filename, size_t max_size) +struct os_stream * +os_stream_create(const char *filename, size_t max_size) { - struct util_stream *stream; + struct os_stream *stream; (void)max_size; - stream = CALLOC_STRUCT(util_stream); + stream = (struct os_stream *)calloc(1, sizeof(struct os_stream)); if(!stream) - goto error1; + goto no_stream; stream->file = fopen(filename, "w"); if(!stream->file) - goto error2; + goto no_file; return stream; -error2: - FREE(stream); -error1: +no_file: + free(stream); +no_stream: return NULL; } boolean -util_stream_write(struct util_stream *stream, const void *data, size_t size) +os_stream_write(struct os_stream *stream, const void *data, size_t size) { if(!stream) return FALSE; @@ -82,7 +81,7 @@ util_stream_write(struct util_stream *stream, const void *data, size_t size) void -util_stream_flush(struct util_stream *stream) +os_stream_flush(struct os_stream *stream) { if(!stream) return; @@ -92,14 +91,14 @@ util_stream_flush(struct util_stream *stream) void -util_stream_close(struct util_stream *stream) +os_stream_close(struct os_stream *stream) { if(!stream) return; fclose(stream->file); - FREE(stream); + free(stream); } diff --git a/src/gallium/auxiliary/util/u_stream_wd.c b/src/gallium/auxiliary/os/os_stream_wd.c index 864489e775..a64cbcab4c 100644 --- a/src/gallium/auxiliary/util/u_stream_wd.c +++ b/src/gallium/auxiliary/os/os_stream_wd.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * 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 + * IN NO EVENT SHALL VMWARE 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. @@ -37,16 +37,14 @@ #include <windows.h> #include <winddi.h> -#include "util/u_memory.h" -#include "util/u_string.h" - -#include "u_stream.h" +#include "os_memory.h" +#include "os_stream.h" #define MAP_FILE_SIZE (4*1024*1024) -struct util_stream +struct os_stream { char filename[MAX_PATH + 1]; WCHAR wFileName[MAX_PATH + 1]; @@ -60,23 +58,23 @@ struct util_stream static INLINE boolean -util_stream_map(struct util_stream *stream) +os_stream_map(struct os_stream *stream) { ULONG BytesInUnicodeString; static char filename[MAX_PATH + 1]; unsigned filename_len; if(stream->growable) - filename_len = util_snprintf(filename, - sizeof(filename), - "%s.%04x", - stream->filename, - stream->suffix++); + filename_len = snprintf(filename, + sizeof(filename), + "%s.%04x", + stream->filename, + stream->suffix++); else - filename_len = util_snprintf(filename, - sizeof(filename), - "%s", - stream->filename); + filename_len = snprintf(filename, + sizeof(filename), + "%s", + stream->filename); EngMultiByteToUnicodeN( stream->wFileName, @@ -97,7 +95,7 @@ util_stream_map(struct util_stream *stream) static INLINE void -util_stream_unmap(struct util_stream *stream) +os_stream_unmap(struct os_stream *stream) { EngUnmapFile(stream->iFile); if(stream->written < stream->map_size) { @@ -112,7 +110,7 @@ util_stream_unmap(struct util_stream *stream) static INLINE void -util_stream_full_qualified_filename(char *dst, size_t size, const char *src) +os_stream_full_qualified_filename(char *dst, size_t size, const char *src) { boolean need_drive, need_root; @@ -125,24 +123,24 @@ util_stream_full_qualified_filename(char *dst, size_t size, const char *src) need_root = src[0] == '\\' ? FALSE : TRUE; } - util_snprintf(dst, size, - "\\??\\%s%s%s", - need_drive ? "C:" : "", - need_root ? "\\" : "", - src); + snprintf(dst, size, + "\\??\\%s%s%s", + need_drive ? "C:" : "", + need_root ? "\\" : "", + src); } -struct util_stream * -util_stream_create(const char *filename, size_t max_size) +struct os_stream * +os_stream_create(const char *filename, size_t max_size) { - struct util_stream *stream; + struct os_stream *stream; - stream = CALLOC_STRUCT(util_stream); + stream = CALLOC_STRUCT(os_stream); if(!stream) goto error1; - util_stream_full_qualified_filename(stream->filename, + os_stream_full_qualified_filename(stream->filename, sizeof(stream->filename), filename); @@ -155,7 +153,7 @@ util_stream_create(const char *filename, size_t max_size) stream->map_size = MAP_FILE_SIZE; } - if(!util_stream_map(stream)) + if(!os_stream_map(stream)) goto error2; return stream; @@ -168,7 +166,7 @@ error1: static INLINE void -util_stream_copy(struct util_stream *stream, const char *data, size_t size) +os_stream_copy(struct os_stream *stream, const char *data, size_t size) { assert(stream->written + size <= stream->map_size); memcpy(stream->pMap + stream->written, data, size); @@ -177,7 +175,7 @@ util_stream_copy(struct util_stream *stream, const char *data, size_t size) boolean -util_stream_write(struct util_stream *stream, const void *data, size_t size) +os_stream_write(struct os_stream *stream, const void *data, size_t size) { if(!stream) return FALSE; @@ -187,35 +185,35 @@ util_stream_write(struct util_stream *stream, const void *data, size_t size) while(stream->written + size > stream->map_size) { size_t step = stream->map_size - stream->written; - util_stream_copy(stream, data, step); + os_stream_copy(stream, data, step); data = (const char *)data + step; size -= step; - util_stream_unmap(stream); - if(!stream->growable || !util_stream_map(stream)) + os_stream_unmap(stream); + if(!stream->growable || !os_stream_map(stream)) return FALSE; } - util_stream_copy(stream, data, size); + os_stream_copy(stream, data, size); return TRUE; } void -util_stream_flush(struct util_stream *stream) +os_stream_flush(struct os_stream *stream) { (void)stream; } void -util_stream_close(struct util_stream *stream) +os_stream_close(struct os_stream *stream) { if(!stream) return; - util_stream_unmap(stream); + os_stream_unmap(stream); FREE(stream); } diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/auxiliary/os/os_thread.h index 25e4148232..8ae90308c5 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -27,12 +27,13 @@ /** * @file * - * Thread, mutex, condition var and thread-specific data functions. + * Thread, mutex, condition variable, barrier, semaphore and + * thread-specific data functions. */ -#ifndef _P_THREAD2_H_ -#define _P_THREAD2_H_ +#ifndef OS_THREAD_H_ +#define OS_THREAD_H_ #include "pipe/p_compiler.h" @@ -46,6 +47,8 @@ #define PIPE_THREAD_HAVE_CONDVAR +/* pipe_thread + */ typedef pthread_t pipe_thread; #define PIPE_THREAD_ROUTINE( name, param ) \ @@ -69,8 +72,10 @@ static INLINE int pipe_thread_destroy( pipe_thread thread ) return pthread_detach( thread ); } + +/* pipe_mutex + */ typedef pthread_mutex_t pipe_mutex; -typedef pthread_cond_t pipe_condvar; #define pipe_static_mutex(mutex) \ static pipe_mutex mutex = PTHREAD_MUTEX_INITIALIZER @@ -87,6 +92,11 @@ typedef pthread_cond_t pipe_condvar; #define pipe_mutex_unlock(mutex) \ (void) pthread_mutex_unlock(&(mutex)) + +/* pipe_condvar + */ +typedef pthread_cond_t pipe_condvar; + #define pipe_static_condvar(mutex) \ static pipe_condvar mutex = PTHREAD_COND_INITIALIZER @@ -106,10 +116,32 @@ typedef pthread_cond_t pipe_condvar; pthread_cond_broadcast(&(cond)) +/* pipe_barrier + */ +typedef pthread_barrier_t pipe_barrier; + +static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count) +{ + pthread_barrier_init(barrier, NULL, count); +} + +static INLINE void pipe_barrier_destroy(pipe_barrier *barrier) +{ + pthread_barrier_destroy(barrier); +} + +static INLINE void pipe_barrier_wait(pipe_barrier *barrier) +{ + pthread_barrier_wait(barrier); +} + + #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) #include <windows.h> +/* pipe_thread + */ typedef HANDLE pipe_thread; #define PIPE_THREAD_ROUTINE( name, param ) \ @@ -135,6 +167,9 @@ static INLINE int pipe_thread_destroy( pipe_thread thread ) return -1; } + +/* pipe_mutex + */ typedef CRITICAL_SECTION pipe_mutex; #define pipe_static_mutex(mutex) \ @@ -152,23 +187,74 @@ typedef CRITICAL_SECTION pipe_mutex; #define pipe_mutex_unlock(mutex) \ LeaveCriticalSection(&mutex) -/* XXX: dummy definitions, make it compile */ +/* pipe_condvar (XXX FIX THIS) + */ typedef unsigned pipe_condvar; -#define pipe_condvar_init(condvar) \ - (void) condvar +#define pipe_condvar_init(cond) \ + (void) cond + +#define pipe_condvar_destroy(cond) \ + (void) cond + +#define pipe_condvar_wait(cond, mutex) \ + (void) cond; (void) mutex + +#define pipe_condvar_signal(cond) \ + (void) cond + +#define pipe_condvar_broadcast(cond) \ + (void) cond + + +/* pipe_barrier (XXX FIX THIS) + */ +typedef unsigned pipe_barrier; + +static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count) +{ + /* XXX we could implement barriers with a mutex and condition var */ +} + +static INLINE void pipe_barrier_destroy(pipe_barrier *barrier) +{ +} + +static INLINE void pipe_barrier_wait(pipe_barrier *barrier) +{ + assert(0); +} + -#define pipe_condvar_broadcast(condvar) \ - (void) condvar #else /** Dummy definitions */ typedef unsigned pipe_thread; + +#define PIPE_THREAD_ROUTINE( name, param ) \ + void * name( void *param ) + +static INLINE pipe_thread pipe_thread_create( void *(* routine)( void *), void *param ) +{ + return 0; +} + +static INLINE int pipe_thread_wait( pipe_thread thread ) +{ + return -1; +} + +static INLINE int pipe_thread_destroy( pipe_thread thread ) +{ + return -1; +} + typedef unsigned pipe_mutex; typedef unsigned pipe_condvar; +typedef unsigned pipe_barrier; #define pipe_static_mutex(mutex) \ static pipe_mutex mutex = 0 @@ -204,9 +290,77 @@ typedef unsigned pipe_condvar; (void) condvar +static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count) +{ + /* XXX we could implement barriers with a mutex and condition var */ + assert(0); +} + +static INLINE void pipe_barrier_destroy(pipe_barrier *barrier) +{ + assert(0); +} + +static INLINE void pipe_barrier_wait(pipe_barrier *barrier) +{ + assert(0); +} + + + #endif /* PIPE_OS_? */ +/* + * Semaphores + */ + +typedef struct +{ + pipe_mutex mutex; + pipe_condvar cond; + int counter; +} pipe_semaphore; + + +static INLINE void +pipe_semaphore_init(pipe_semaphore *sema, int init_val) +{ + pipe_mutex_init(sema->mutex); + pipe_condvar_init(sema->cond); + sema->counter = init_val; +} + +static INLINE void +pipe_semaphore_destroy(pipe_semaphore *sema) +{ + pipe_mutex_destroy(sema->mutex); + pipe_condvar_destroy(sema->cond); +} + +/** Signal/increment semaphore counter */ +static INLINE void +pipe_semaphore_signal(pipe_semaphore *sema) +{ + pipe_mutex_lock(sema->mutex); + sema->counter++; + pipe_condvar_signal(sema->cond); + pipe_mutex_unlock(sema->mutex); +} + +/** Wait for semaphore counter to be greater than zero */ +static INLINE void +pipe_semaphore_wait(pipe_semaphore *sema) +{ + pipe_mutex_lock(sema->mutex); + while (sema->counter <= 0) { + pipe_condvar_wait(sema->cond, sema->mutex); + } + sema->counter--; + pipe_mutex_unlock(sema->mutex); +} + + /* * Thread-specific data. @@ -276,4 +430,4 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) -#endif /* _P_THREAD2_H_ */ +#endif /* OS_THREAD_H_ */ diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c new file mode 100644 index 0000000000..6259142bec --- /dev/null +++ b/src/gallium/auxiliary/os/os_time.c @@ -0,0 +1,128 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + + +#include "pipe/p_config.h" + +#if !defined(PIPE_OS_EMBEDDED) + +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) +# include <sys/time.h> /* timeval */ +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) +# include <windows.h> +# include <winddi.h> +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +# include <windows.h> +extern VOID KeQuerySystemTime(PLARGE_INTEGER); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +# include <windows.h> +#else +# error Unsupported OS +#endif + +#include "os_time.h" + + +int64_t +os_time_get(void) +{ +#if defined(PIPE_OS_UNIX) + + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_usec + tv.tv_sec*1000000LL; + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + + static LONGLONG frequency; + LONGLONG counter; + if(!frequency) + EngQueryPerformanceFrequency(&frequency); + EngQueryPerformanceCounter(&counter); + return counter*INT64_C(1000000)/frequency; + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) + + static LARGE_INTEGER frequency; + LARGE_INTEGER counter; + if(!frequency.QuadPart) + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&counter); + return counter.QuadPart*INT64_C(1000000)/frequency.QuadPart; + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + + /* Updated every 10 miliseconds, measured in units of 100 nanoseconds. + * http://msdn.microsoft.com/en-us/library/ms801642.aspx */ + LARGE_INTEGER counter; + KeQuerySystemTime(&counter); + return counter.QuadPart/10; + +#endif +} + + +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void +os_time_sleep(int64_t usecs) +{ + static LONGLONG frequency; + LONGLONG start, curr, end; + + EngQueryPerformanceCounter(&start); + + if(!frequency) + EngQueryPerformanceFrequency(&frequency); + + end = start + (usecs * frequency + 999999LL)/1000000LL; + + do { + EngQueryPerformanceCounter(&curr); + } while(start <= curr && curr < end || + end < start && (curr < end || start <= curr)); +} + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +void +os_time_sleep(int64_t usecs) +{ + Sleep((usecs + 999) / 1000); +} + +#endif + + +#endif /* !PIPE_OS_EMBEDDED */ diff --git a/src/gallium/auxiliary/os/os_time.h b/src/gallium/auxiliary/os/os_time.h new file mode 100644 index 0000000000..5b55c1b374 --- /dev/null +++ b/src/gallium/auxiliary/os/os_time.h @@ -0,0 +1,92 @@ +/************************************************************************** + * + * Copyright 2008-2010 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 VMWARE 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. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#ifndef _OS_TIME_H_ +#define _OS_TIME_H_ + + +#include "pipe/p_config.h" + +#if defined(PIPE_OS_UNIX) +# include <unistd.h> /* usleep */ +#endif + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Get the current time in microseconds from an unknown base. + */ +int64_t +os_time_get(void); + + +/* + * Sleep. + */ +#if defined(PIPE_OS_UNIX) +#define os_time_sleep(_usecs) usleep(_usecs) +#else +void +os_time_sleep(int64_t usecs); +#endif + + +/* + * Helper function for detecting time outs, taking in account overflow. + * + * Returns true the the current time has elapsed beyond the specified interval. + */ +static INLINE boolean +os_time_timeout(int64_t start, + int64_t end, + int64_t curr) +{ + if(start <= end) + return !(start <= curr && curr < end); + else + return !((start <= curr) || (curr < end)); +} + + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_TIME_H_ */ diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile new file mode 100644 index 0000000000..21d25d2474 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -0,0 +1,18 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = pipebuffer + +C_SOURCES = \ + pb_buffer_fenced.c \ + pb_buffer_malloc.c \ + pb_bufmgr_alt.c \ + pb_bufmgr_cache.c \ + pb_bufmgr_debug.c \ + pb_bufmgr_mm.c \ + pb_bufmgr_ondemand.c \ + pb_bufmgr_pool.c \ + pb_bufmgr_slab.c \ + pb_validate.c + +include ../../Makefile.template diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript new file mode 100644 index 0000000000..a074a55471 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -0,0 +1,18 @@ +Import('*') + +pipebuffer = env.ConvenienceLibrary( + target = 'pipebuffer', + source = [ + 'pb_buffer_fenced.c', + 'pb_buffer_malloc.c', + 'pb_bufmgr_alt.c', + 'pb_bufmgr_cache.c', + 'pb_bufmgr_debug.c', + 'pb_bufmgr_mm.c', + 'pb_bufmgr_ondemand.c', + 'pb_bufmgr_pool.c', + 'pb_bufmgr_slab.c', + 'pb_validate.c', + ]) + +auxiliaries.insert(0, pipebuffer) diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index eb7e84be84..34b1b77df4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -46,6 +46,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index ba6f7b15f9..95eb5f6563 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007-2009 VMware, Inc. + * Copyright 2007-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -28,9 +28,9 @@ /** * \file * Implementation of fenced buffers. - * - * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com> - * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com> + * + * \author Jose Fonseca <jfonseca-at-vmware-dot-com> + * \author Thomas Hellström <thellstrom-at-vmware-dot-com> */ @@ -44,12 +44,13 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" +#include "pb_bufmgr.h" @@ -59,23 +60,50 @@ #define SUPER(__derived) (&(__derived)->base) -struct fenced_buffer_list +struct fenced_manager { - pipe_mutex mutex; - + struct pb_manager base; + struct pb_manager *provider; struct pb_fence_ops *ops; - - pb_size numDelayed; - struct list_head delayed; - -#ifdef DEBUG - pb_size numUnfenced; + + /** + * Maximum buffer size that can be safely allocated. + */ + pb_size max_buffer_size; + + /** + * Maximum cpu memory we can allocate before we start waiting for the + * GPU to idle. + */ + pb_size max_cpu_total_size; + + /** + * Following members are mutable and protected by this mutex. + */ + pipe_mutex mutex; + + /** + * Fenced buffer list. + * + * All fenced buffers are placed in this listed, ordered from the oldest + * fence to the newest fence. + */ + struct list_head fenced; + pb_size num_fenced; + struct list_head unfenced; -#endif + pb_size num_unfenced; + + /** + * How much temporary CPU memory is being used to hold unvalidated buffers. + */ + pb_size cpu_total_size; }; /** + * Fenced buffer. + * * Wrapper around a pipe buffer which adds fencing and reference counting. */ struct fenced_buffer @@ -85,22 +113,26 @@ struct fenced_buffer */ struct pb_buffer base; - struct pb_buffer *buffer; - struct fenced_buffer_list *list; + struct fenced_manager *mgr; - /** - * Protected by fenced_buffer_list::mutex + /* + * Following members are mutable and protected by fenced_manager::mutex. */ + struct list_head head; /** - * Following members are mutable and protected by this mutex. - * - * You may lock this mutex alone, or lock it with fenced_buffer_list::mutex - * held, but in order to prevent deadlocks you must never lock - * fenced_buffer_list::mutex with this mutex held. + * Buffer with storage. */ - pipe_mutex mutex; + struct pb_buffer *buffer; + pb_size size; + struct pb_desc desc; + + /** + * Temporary CPU storage data. Used when there isn't enough GPU memory to + * store the buffer. + */ + void *data; /** * A bitmask of PIPE_BUFFER_USAGE_CPU/GPU_READ/WRITE describing the current @@ -109,12 +141,22 @@ struct fenced_buffer unsigned flags; unsigned mapcount; + struct pb_validate *vl; unsigned validation_flags; + struct pipe_fence_handle *fence; }; +static INLINE struct fenced_manager * +fenced_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct fenced_manager *)mgr; +} + + static INLINE struct fenced_buffer * fenced_buffer(struct pb_buffer *buf) { @@ -123,81 +165,172 @@ fenced_buffer(struct pb_buffer *buf) } +static void +fenced_buffer_destroy_cpu_storage_locked(struct fenced_buffer *fenced_buf); + +static enum pipe_error +fenced_buffer_create_cpu_storage_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf); + +static void +fenced_buffer_destroy_gpu_storage_locked(struct fenced_buffer *fenced_buf); + +static enum pipe_error +fenced_buffer_create_gpu_storage_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf, + boolean wait); + +static enum pipe_error +fenced_buffer_copy_storage_to_gpu_locked(struct fenced_buffer *fenced_buf); + +static enum pipe_error +fenced_buffer_copy_storage_to_cpu_locked(struct fenced_buffer *fenced_buf); + + +/** + * Dump the fenced buffer list. + * + * Useful to understand failures to allocate buffers. + */ +static void +fenced_manager_dump_locked(struct fenced_manager *fenced_mgr) +{ +#ifdef DEBUG + struct pb_fence_ops *ops = fenced_mgr->ops; + struct list_head *curr, *next; + struct fenced_buffer *fenced_buf; + + debug_printf("%10s %7s %8s %7s %10s %s\n", + "buffer", "size", "refcount", "storage", "fence", "signalled"); + + curr = fenced_mgr->unfenced.next; + next = curr->next; + while(curr != &fenced_mgr->unfenced) { + fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + assert(!fenced_buf->fence); + debug_printf("%10p %7u %8u %7s\n", + (void *) fenced_buf, + fenced_buf->base.base.size, + p_atomic_read(&fenced_buf->base.base.reference.count), + fenced_buf->buffer ? "gpu" : (fenced_buf->data ? "cpu" : "none")); + curr = next; + next = curr->next; + } + + curr = fenced_mgr->fenced.next; + next = curr->next; + while(curr != &fenced_mgr->fenced) { + int signaled; + fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + assert(fenced_buf->buffer); + signaled = ops->fence_signalled(ops, fenced_buf->fence, 0); + debug_printf("%10p %7u %8u %7s %10p %s\n", + (void *) fenced_buf, + fenced_buf->base.base.size, + p_atomic_read(&fenced_buf->base.base.reference.count), + "gpu", + (void *) fenced_buf->fence, + signaled == 0 ? "y" : "n"); + curr = next; + next = curr->next; + } +#else + (void)fenced_mgr; +#endif +} + + +static INLINE void +fenced_buffer_destroy_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf) +{ + assert(!pipe_is_referenced(&fenced_buf->base.base.reference)); + + assert(!fenced_buf->fence); + assert(fenced_buf->head.prev); + assert(fenced_buf->head.next); + LIST_DEL(&fenced_buf->head); + assert(fenced_mgr->num_unfenced); + --fenced_mgr->num_unfenced; + + fenced_buffer_destroy_gpu_storage_locked(fenced_buf); + fenced_buffer_destroy_cpu_storage_locked(fenced_buf); + + FREE(fenced_buf); +} + + /** * Add the buffer to the fenced list. - * - * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this - * order, before calling this function. - * + * * Reference count should be incremented before calling this function. */ static INLINE void -fenced_buffer_add_locked(struct fenced_buffer_list *fenced_list, +fenced_buffer_add_locked(struct fenced_manager *fenced_mgr, struct fenced_buffer *fenced_buf) { assert(pipe_is_referenced(&fenced_buf->base.base.reference)); assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); assert(fenced_buf->fence); - /* TODO: Move the reference count increment here */ - -#ifdef DEBUG + p_atomic_inc(&fenced_buf->base.base.reference.count); + LIST_DEL(&fenced_buf->head); - assert(fenced_list->numUnfenced); - --fenced_list->numUnfenced; -#endif - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); - ++fenced_list->numDelayed; + assert(fenced_mgr->num_unfenced); + --fenced_mgr->num_unfenced; + LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->fenced); + ++fenced_mgr->num_fenced; } /** - * Remove the buffer from the fenced list. - * - * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this - * order before calling this function. - * - * Reference count should be decremented after calling this function. + * Remove the buffer from the fenced list, and potentially destroy the buffer + * if the reference count reaches zero. + * + * Returns TRUE if the buffer was detroyed. */ -static INLINE void -fenced_buffer_remove_locked(struct fenced_buffer_list *fenced_list, +static INLINE boolean +fenced_buffer_remove_locked(struct fenced_manager *fenced_mgr, struct fenced_buffer *fenced_buf) { - struct pb_fence_ops *ops = fenced_list->ops; + struct pb_fence_ops *ops = fenced_mgr->ops; assert(fenced_buf->fence); - assert(fenced_buf->list == fenced_list); - + assert(fenced_buf->mgr == fenced_mgr); + ops->fence_reference(ops, &fenced_buf->fence, NULL); fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; - + assert(fenced_buf->head.prev); assert(fenced_buf->head.next); - + LIST_DEL(&fenced_buf->head); - assert(fenced_list->numDelayed); - --fenced_list->numDelayed; - -#ifdef DEBUG - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->unfenced); - ++fenced_list->numUnfenced; -#endif - - /* TODO: Move the reference count decrement and destruction here */ + assert(fenced_mgr->num_fenced); + --fenced_mgr->num_fenced; + + LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->unfenced); + ++fenced_mgr->num_unfenced; + + if (p_atomic_dec_zero(&fenced_buf->base.base.reference.count)) { + fenced_buffer_destroy_locked(fenced_mgr, fenced_buf); + return TRUE; + } + + return FALSE; } /** * Wait for the fence to expire, and remove it from the fenced list. - * - * fenced_buffer::mutex must be held. fenced_buffer_list::mutex must not be - * held -- it will be acquired internally. + * + * This function will release and re-aquire the mutex, so any copy of mutable + * state must be discarded after calling it. */ static INLINE enum pipe_error -fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list, - struct fenced_buffer *fenced_buf) +fenced_buffer_finish_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf) { - struct pb_fence_ops *ops = fenced_list->ops; + struct pb_fence_ops *ops = fenced_mgr->ops; enum pipe_error ret = PIPE_ERROR; #if 0 @@ -207,22 +340,42 @@ fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list, assert(pipe_is_referenced(&fenced_buf->base.base.reference)); assert(fenced_buf->fence); - /* - * Acquire the global lock. Must release buffer mutex first to preserve - * lock order. - */ - pipe_mutex_unlock(fenced_buf->mutex); - pipe_mutex_lock(fenced_list->mutex); - pipe_mutex_lock(fenced_buf->mutex); - if(fenced_buf->fence) { - if(ops->fence_finish(ops, fenced_buf->fence, 0) == 0) { - /* Remove from the fenced list */ - /* TODO: remove consequents */ - fenced_buffer_remove_locked(fenced_list, fenced_buf); + struct pipe_fence_handle *fence = NULL; + int finished; + boolean proceed; + + ops->fence_reference(ops, &fence, fenced_buf->fence); + + pipe_mutex_unlock(fenced_mgr->mutex); + + finished = ops->fence_finish(ops, fenced_buf->fence, 0); + + pipe_mutex_lock(fenced_mgr->mutex); + + assert(pipe_is_referenced(&fenced_buf->base.base.reference)); + + /* + * Only proceed if the fence object didn't change in the meanwhile. + * Otherwise assume the work has been already carried out by another + * thread that re-aquired the lock before us. + */ + proceed = fence == fenced_buf->fence ? TRUE : FALSE; + + ops->fence_reference(ops, &fence, NULL); - p_atomic_dec(&fenced_buf->base.base.reference.count); - assert(pipe_is_referenced(&fenced_buf->base.base.reference)); + if(proceed && finished == 0) { + /* + * Remove from the fenced list + */ + + boolean destroyed; + + destroyed = fenced_buffer_remove_locked(fenced_mgr, fenced_buf); + + /* TODO: remove consequents buffers with the same fence? */ + + assert(!destroyed); fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; @@ -230,131 +383,350 @@ fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list, } } - pipe_mutex_unlock(fenced_list->mutex); - return ret; } /** - * Free as many fenced buffers from the list head as possible. + * Remove as many fenced buffers from the fenced list as possible. + * + * Returns TRUE if at least one buffer was removed. */ -static void -fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list, - int wait) +static boolean +fenced_manager_check_signalled_locked(struct fenced_manager *fenced_mgr, + boolean wait) { - struct pb_fence_ops *ops = fenced_list->ops; + struct pb_fence_ops *ops = fenced_mgr->ops; struct list_head *curr, *next; struct fenced_buffer *fenced_buf; - struct pb_buffer *pb_buf; struct pipe_fence_handle *prev_fence = NULL; + boolean ret = FALSE; - curr = fenced_list->delayed.next; + curr = fenced_mgr->fenced.next; next = curr->next; - while(curr != &fenced_list->delayed) { + while(curr != &fenced_mgr->fenced) { fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); - pipe_mutex_lock(fenced_buf->mutex); - if(fenced_buf->fence != prev_fence) { int signaled; - if (wait) + + if (wait) { signaled = ops->fence_finish(ops, fenced_buf->fence, 0); - else + + /* + * Don't return just now. Instead preemptively check if the + * following buffers' fences already expired, without further waits. + */ + wait = FALSE; + } + else { signaled = ops->fence_signalled(ops, fenced_buf->fence, 0); + } + if (signaled != 0) { - pipe_mutex_unlock(fenced_buf->mutex); - break; + return ret; } + prev_fence = fenced_buf->fence; } else { + /* This buffer's fence object is identical to the previous buffer's + * fence object, so no need to check the fence again. + */ assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0); } - fenced_buffer_remove_locked(fenced_list, fenced_buf); - pipe_mutex_unlock(fenced_buf->mutex); + fenced_buffer_remove_locked(fenced_mgr, fenced_buf); - pb_buf = &fenced_buf->base; - pb_reference(&pb_buf, NULL); + ret = TRUE; - curr = next; + curr = next; next = curr->next; } + + return ret; +} + + +/** + * Try to free some GPU memory by backing it up into CPU memory. + * + * Returns TRUE if at least one buffer was freed. + */ +static boolean +fenced_manager_free_gpu_storage_locked(struct fenced_manager *fenced_mgr) +{ + struct list_head *curr, *next; + struct fenced_buffer *fenced_buf; + + curr = fenced_mgr->unfenced.next; + next = curr->next; + while(curr != &fenced_mgr->unfenced) { + fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + + /* + * We can only move storage if the buffer is not mapped and not + * validated. + */ + if(fenced_buf->buffer && + !fenced_buf->mapcount && + !fenced_buf->vl) { + enum pipe_error ret; + + ret = fenced_buffer_create_cpu_storage_locked(fenced_mgr, fenced_buf); + if(ret == PIPE_OK) { + ret = fenced_buffer_copy_storage_to_cpu_locked(fenced_buf); + if(ret == PIPE_OK) { + fenced_buffer_destroy_gpu_storage_locked(fenced_buf); + return TRUE; + } + fenced_buffer_destroy_cpu_storage_locked(fenced_buf); + } + } + + curr = next; + next = curr->next; + } + + return FALSE; +} + + +/** + * Destroy CPU storage for this buffer. + */ +static void +fenced_buffer_destroy_cpu_storage_locked(struct fenced_buffer *fenced_buf) +{ + if(fenced_buf->data) { + align_free(fenced_buf->data); + fenced_buf->data = NULL; + assert(fenced_buf->mgr->cpu_total_size >= fenced_buf->size); + fenced_buf->mgr->cpu_total_size -= fenced_buf->size; + } +} + + +/** + * Create CPU storage for this buffer. + */ +static enum pipe_error +fenced_buffer_create_cpu_storage_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf) +{ + assert(!fenced_buf->data); + if(fenced_buf->data) + return PIPE_OK; + + if (fenced_mgr->cpu_total_size + fenced_buf->size > fenced_mgr->max_cpu_total_size) + return PIPE_ERROR_OUT_OF_MEMORY; + + fenced_buf->data = align_malloc(fenced_buf->size, fenced_buf->desc.alignment); + if(!fenced_buf->data) + return PIPE_ERROR_OUT_OF_MEMORY; + + fenced_mgr->cpu_total_size += fenced_buf->size; + + return PIPE_OK; +} + + +/** + * Destroy the GPU storage. + */ +static void +fenced_buffer_destroy_gpu_storage_locked(struct fenced_buffer *fenced_buf) +{ + if(fenced_buf->buffer) { + pb_reference(&fenced_buf->buffer, NULL); + } +} + + +/** + * Try to create GPU storage for this buffer. + * + * This function is a shorthand around pb_manager::create_buffer for + * fenced_buffer_create_gpu_storage_locked()'s benefit. + */ +static INLINE boolean +fenced_buffer_try_create_gpu_storage_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf) +{ + struct pb_manager *provider = fenced_mgr->provider; + + assert(!fenced_buf->buffer); + + fenced_buf->buffer = provider->create_buffer(fenced_mgr->provider, + fenced_buf->size, + &fenced_buf->desc); + return fenced_buf->buffer ? TRUE : FALSE; +} + + +/** + * Create GPU storage for this buffer. + */ +static enum pipe_error +fenced_buffer_create_gpu_storage_locked(struct fenced_manager *fenced_mgr, + struct fenced_buffer *fenced_buf, + boolean wait) +{ + assert(!fenced_buf->buffer); + + /* + * Check for signaled buffers before trying to allocate. + */ + fenced_manager_check_signalled_locked(fenced_mgr, FALSE); + + fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf); + + /* + * Keep trying while there is some sort of progress: + * - fences are expiring, + * - or buffers are being being swapped out from GPU memory into CPU memory. + */ + while(!fenced_buf->buffer && + (fenced_manager_check_signalled_locked(fenced_mgr, FALSE) || + fenced_manager_free_gpu_storage_locked(fenced_mgr))) { + fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf); + } + + if(!fenced_buf->buffer && wait) { + /* + * Same as before, but this time around, wait to free buffers if + * necessary. + */ + while(!fenced_buf->buffer && + (fenced_manager_check_signalled_locked(fenced_mgr, TRUE) || + fenced_manager_free_gpu_storage_locked(fenced_mgr))) { + fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf); + } + } + + if(!fenced_buf->buffer) { + if(0) + fenced_manager_dump_locked(fenced_mgr); + + /* give up */ + return PIPE_ERROR_OUT_OF_MEMORY; + } + + return PIPE_OK; +} + + +static enum pipe_error +fenced_buffer_copy_storage_to_gpu_locked(struct fenced_buffer *fenced_buf) +{ + uint8_t *map; + + assert(fenced_buf->data); + assert(fenced_buf->buffer); + + map = pb_map(fenced_buf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + if(!map) + return PIPE_ERROR; + + memcpy(map, fenced_buf->data, fenced_buf->size); + + pb_unmap(fenced_buf->buffer); + + return PIPE_OK; +} + + +static enum pipe_error +fenced_buffer_copy_storage_to_cpu_locked(struct fenced_buffer *fenced_buf) +{ + const uint8_t *map; + + assert(fenced_buf->data); + assert(fenced_buf->buffer); + + map = pb_map(fenced_buf->buffer, PIPE_BUFFER_USAGE_CPU_READ); + if(!map) + return PIPE_ERROR; + + memcpy(fenced_buf->data, map, fenced_buf->size); + + pb_unmap(fenced_buf->buffer); + + return PIPE_OK; } static void fenced_buffer_destroy(struct pb_buffer *buf) { - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_manager *fenced_mgr = fenced_buf->mgr; assert(!pipe_is_referenced(&fenced_buf->base.base.reference)); - assert(!fenced_buf->fence); -#ifdef DEBUG - pipe_mutex_lock(fenced_list->mutex); - assert(fenced_buf->head.prev); - assert(fenced_buf->head.next); - LIST_DEL(&fenced_buf->head); - assert(fenced_list->numUnfenced); - --fenced_list->numUnfenced; - pipe_mutex_unlock(fenced_list->mutex); -#else - (void)fenced_list; -#endif + pipe_mutex_lock(fenced_mgr->mutex); - pb_reference(&fenced_buf->buffer, NULL); + fenced_buffer_destroy_locked(fenced_mgr, fenced_buf); - pipe_mutex_destroy(fenced_buf->mutex); - FREE(fenced_buf); + pipe_mutex_unlock(fenced_mgr->mutex); } static void * -fenced_buffer_map(struct pb_buffer *buf, +fenced_buffer_map(struct pb_buffer *buf, unsigned flags) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); - struct fenced_buffer_list *fenced_list = fenced_buf->list; - struct pb_fence_ops *ops = fenced_list->ops; + struct fenced_manager *fenced_mgr = fenced_buf->mgr; + struct pb_fence_ops *ops = fenced_mgr->ops; void *map = NULL; - pipe_mutex_lock(fenced_buf->mutex); + pipe_mutex_lock(fenced_mgr->mutex); assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); - - /* Serialize writes */ - if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) || - ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) { + + /* + * Serialize writes. + */ + while((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) || + ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) { + + /* + * Don't wait for the GPU to finish accessing it, if blocking is forbidden. + */ if((flags & PIPE_BUFFER_USAGE_DONTBLOCK) && ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) { - /* Don't wait for the GPU to finish writing */ goto done; } - /* Wait for the GPU to finish writing */ - fenced_buffer_finish_locked(fenced_list, fenced_buf); + if (flags & PIPE_BUFFER_USAGE_UNSYNCHRONIZED) { + break; + } + + /* + * Wait for the GPU to finish accessing. This will release and re-acquire + * the mutex, so all copies of mutable state must be discarded. + */ + fenced_buffer_finish_locked(fenced_mgr, fenced_buf); } -#if 0 - /* Check for CPU write access (read is OK) */ - if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { - /* this is legal -- just for debugging */ - debug_warning("concurrent CPU writes"); + if(fenced_buf->buffer) { + map = pb_map(fenced_buf->buffer, flags); } -#endif - - map = pb_map(fenced_buf->buffer, flags); + else { + assert(fenced_buf->data); + map = fenced_buf->data; + } + if(map) { ++fenced_buf->mapcount; fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE; } done: - pipe_mutex_unlock(fenced_buf->mutex); - + pipe_mutex_unlock(fenced_mgr->mutex); + return map; } @@ -363,18 +735,20 @@ static void fenced_buffer_unmap(struct pb_buffer *buf) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); - - pipe_mutex_lock(fenced_buf->mutex); - + struct fenced_manager *fenced_mgr = fenced_buf->mgr; + + pipe_mutex_lock(fenced_mgr->mutex); + assert(fenced_buf->mapcount); if(fenced_buf->mapcount) { - pb_unmap(fenced_buf->buffer); + if (fenced_buf->buffer) + pb_unmap(fenced_buf->buffer); --fenced_buf->mapcount; if(!fenced_buf->mapcount) fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; } - - pipe_mutex_unlock(fenced_buf->mutex); + + pipe_mutex_unlock(fenced_mgr->mutex); } @@ -384,9 +758,10 @@ fenced_buffer_validate(struct pb_buffer *buf, unsigned flags) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_manager *fenced_mgr = fenced_buf->mgr; enum pipe_error ret; - - pipe_mutex_lock(fenced_buf->mutex); + + pipe_mutex_lock(fenced_mgr->mutex); if(!vl) { /* invalidate */ @@ -395,28 +770,16 @@ fenced_buffer_validate(struct pb_buffer *buf, ret = PIPE_OK; goto done; } - + assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE)); flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE; - /* Buffer cannot be validated in two different lists */ + /* Buffer cannot be validated in two different lists */ if(fenced_buf->vl && fenced_buf->vl != vl) { ret = PIPE_ERROR_RETRY; goto done; } - -#if 0 - /* Do not validate if buffer is still mapped */ - if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { - /* TODO: wait for the thread that mapped the buffer to unmap it */ - ret = PIPE_ERROR_RETRY; - goto done; - } - /* Final sanity checking */ - assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE)); - assert(!fenced_buf->mapcount); -#endif if(fenced_buf->vl == vl && (fenced_buf->validation_flags & flags) == flags) { @@ -424,16 +787,41 @@ fenced_buffer_validate(struct pb_buffer *buf, ret = PIPE_OK; goto done; } - + + /* + * Create and update GPU storage. + */ + if(!fenced_buf->buffer) { + assert(!fenced_buf->mapcount); + + ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, TRUE); + if(ret != PIPE_OK) { + goto done; + } + + ret = fenced_buffer_copy_storage_to_gpu_locked(fenced_buf); + if(ret != PIPE_OK) { + fenced_buffer_destroy_gpu_storage_locked(fenced_buf); + goto done; + } + + if(fenced_buf->mapcount) { + debug_printf("warning: validating a buffer while it is still mapped\n"); + } + else { + fenced_buffer_destroy_cpu_storage_locked(fenced_buf); + } + } + ret = pb_validate(fenced_buf->buffer, vl, flags); if (ret != PIPE_OK) goto done; - + fenced_buf->vl = vl; fenced_buf->validation_flags |= flags; - + done: - pipe_mutex_unlock(fenced_buf->mutex); + pipe_mutex_unlock(fenced_mgr->mutex); return ret; } @@ -443,43 +831,37 @@ static void fenced_buffer_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) { - struct fenced_buffer *fenced_buf; - struct fenced_buffer_list *fenced_list; - struct pb_fence_ops *ops; - - fenced_buf = fenced_buffer(buf); - fenced_list = fenced_buf->list; - ops = fenced_list->ops; + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_manager *fenced_mgr = fenced_buf->mgr; + struct pb_fence_ops *ops = fenced_mgr->ops; - pipe_mutex_lock(fenced_list->mutex); - pipe_mutex_lock(fenced_buf->mutex); + pipe_mutex_lock(fenced_mgr->mutex); assert(pipe_is_referenced(&fenced_buf->base.base.reference)); + assert(fenced_buf->buffer); if(fence != fenced_buf->fence) { assert(fenced_buf->vl); assert(fenced_buf->validation_flags); - + if (fenced_buf->fence) { - fenced_buffer_remove_locked(fenced_list, fenced_buf); - p_atomic_dec(&fenced_buf->base.base.reference.count); - assert(pipe_is_referenced(&fenced_buf->base.base.reference)); + boolean destroyed; + destroyed = fenced_buffer_remove_locked(fenced_mgr, fenced_buf); + assert(!destroyed); } if (fence) { ops->fence_reference(ops, &fenced_buf->fence, fence); fenced_buf->flags |= fenced_buf->validation_flags; - p_atomic_inc(&fenced_buf->base.base.reference.count); - fenced_buffer_add_locked(fenced_list, fenced_buf); + fenced_buffer_add_locked(fenced_mgr, fenced_buf); } pb_fence(fenced_buf->buffer, fence); - + fenced_buf->vl = NULL; fenced_buf->validation_flags = 0; } - pipe_mutex_unlock(fenced_buf->mutex); - pipe_mutex_unlock(fenced_list->mutex); + pipe_mutex_unlock(fenced_mgr->mutex); } @@ -489,12 +871,29 @@ fenced_buffer_get_base_buffer(struct pb_buffer *buf, pb_size *offset) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); - /* NOTE: accesses immutable members only -- mutex not necessary */ - pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); + struct fenced_manager *fenced_mgr = fenced_buf->mgr; + + pipe_mutex_lock(fenced_mgr->mutex); + + /* + * This should only be called when the buffer is validated. Typically + * when processing relocations. + */ + assert(fenced_buf->vl); + assert(fenced_buf->buffer); + + if(fenced_buf->buffer) + pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); + else { + *base_buf = buf; + *offset = 0; + } + + pipe_mutex_unlock(fenced_mgr->mutex); } -static const struct pb_vtbl +static const struct pb_vtbl fenced_buffer_vtbl = { fenced_buffer_destroy, fenced_buffer_map, @@ -505,154 +904,166 @@ fenced_buffer_vtbl = { }; -struct pb_buffer * -fenced_buffer_create(struct fenced_buffer_list *fenced_list, - struct pb_buffer *buffer) +/** + * Wrap a buffer in a fenced buffer. + */ +static struct pb_buffer * +fenced_bufmgr_create_buffer(struct pb_manager *mgr, + pb_size size, + const struct pb_desc *desc) { - struct fenced_buffer *buf; - - if(!buffer) - return NULL; - - buf = CALLOC_STRUCT(fenced_buffer); - if(!buf) { - pb_reference(&buffer, NULL); - return NULL; + struct fenced_manager *fenced_mgr = fenced_manager(mgr); + struct fenced_buffer *fenced_buf; + enum pipe_error ret; + + /* + * Don't stall the GPU, waste time evicting buffers, or waste memory + * trying to create a buffer that will most likely never fit into the + * graphics aperture. + */ + if(size > fenced_mgr->max_buffer_size) { + goto no_buffer; } - - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = buffer->base.alignment; - buf->base.base.usage = buffer->base.usage; - buf->base.base.size = buffer->base.size; - - buf->base.vtbl = &fenced_buffer_vtbl; - buf->buffer = buffer; - buf->list = fenced_list; - - pipe_mutex_init(buf->mutex); -#ifdef DEBUG - pipe_mutex_lock(fenced_list->mutex); - LIST_ADDTAIL(&buf->head, &fenced_list->unfenced); - ++fenced_list->numUnfenced; - pipe_mutex_unlock(fenced_list->mutex); -#endif + fenced_buf = CALLOC_STRUCT(fenced_buffer); + if(!fenced_buf) + goto no_buffer; - return &buf->base; -} + pipe_reference_init(&fenced_buf->base.base.reference, 1); + fenced_buf->base.base.alignment = desc->alignment; + fenced_buf->base.base.usage = desc->usage; + fenced_buf->base.base.size = size; + fenced_buf->size = size; + fenced_buf->desc = *desc; + fenced_buf->base.vtbl = &fenced_buffer_vtbl; + fenced_buf->mgr = fenced_mgr; -struct fenced_buffer_list * -fenced_buffer_list_create(struct pb_fence_ops *ops) -{ - struct fenced_buffer_list *fenced_list; + pipe_mutex_lock(fenced_mgr->mutex); - fenced_list = CALLOC_STRUCT(fenced_buffer_list); - if (!fenced_list) - return NULL; + /* + * Try to create GPU storage without stalling, + */ + ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, FALSE); - fenced_list->ops = ops; + /* + * Attempt to use CPU memory to avoid stalling the GPU. + */ + if(ret != PIPE_OK) { + ret = fenced_buffer_create_cpu_storage_locked(fenced_mgr, fenced_buf); + } - LIST_INITHEAD(&fenced_list->delayed); - fenced_list->numDelayed = 0; - -#ifdef DEBUG - LIST_INITHEAD(&fenced_list->unfenced); - fenced_list->numUnfenced = 0; -#endif + /* + * Create GPU storage, waiting for some to be available. + */ + if(ret != PIPE_OK) { + ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, TRUE); + } + + /* + * Give up. + */ + if(ret != PIPE_OK) { + goto no_storage; + } - pipe_mutex_init(fenced_list->mutex); + assert(fenced_buf->buffer || fenced_buf->data); - return fenced_list; -} + LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->unfenced); + ++fenced_mgr->num_unfenced; + pipe_mutex_unlock(fenced_mgr->mutex); + return &fenced_buf->base; -void -fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, - int wait) -{ - pipe_mutex_lock(fenced_list->mutex); - fenced_buffer_list_check_free_locked(fenced_list, wait); - pipe_mutex_unlock(fenced_list->mutex); +no_storage: + pipe_mutex_unlock(fenced_mgr->mutex); + FREE(fenced_buf); +no_buffer: + return NULL; } -#ifdef DEBUG -void -fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list) +static void +fenced_bufmgr_flush(struct pb_manager *mgr) { - struct pb_fence_ops *ops = fenced_list->ops; - struct list_head *curr, *next; - struct fenced_buffer *fenced_buf; + struct fenced_manager *fenced_mgr = fenced_manager(mgr); - pipe_mutex_lock(fenced_list->mutex); + pipe_mutex_lock(fenced_mgr->mutex); + while(fenced_manager_check_signalled_locked(fenced_mgr, TRUE)) + ; + pipe_mutex_unlock(fenced_mgr->mutex); - debug_printf("%10s %7s %7s %10s %s\n", - "buffer", "size", "refcount", "fence", "signalled"); - - curr = fenced_list->unfenced.next; - next = curr->next; - while(curr != &fenced_list->unfenced) { - fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); - pipe_mutex_lock(fenced_buf->mutex); - assert(!fenced_buf->fence); - debug_printf("%10p %7u %7u\n", - (void *) fenced_buf, - fenced_buf->base.base.size, - p_atomic_read(&fenced_buf->base.base.reference.count)); - pipe_mutex_unlock(fenced_buf->mutex); - curr = next; - next = curr->next; - } - - curr = fenced_list->delayed.next; - next = curr->next; - while(curr != &fenced_list->delayed) { - int signaled; - fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); - pipe_mutex_lock(fenced_buf->mutex); - signaled = ops->fence_signalled(ops, fenced_buf->fence, 0); - debug_printf("%10p %7u %7u %10p %s\n", - (void *) fenced_buf, - fenced_buf->base.base.size, - p_atomic_read(&fenced_buf->base.base.reference.count), - (void *) fenced_buf->fence, - signaled == 0 ? "y" : "n"); - pipe_mutex_unlock(fenced_buf->mutex); - curr = next; - next = curr->next; - } - - pipe_mutex_unlock(fenced_list->mutex); + assert(fenced_mgr->provider->flush); + if(fenced_mgr->provider->flush) + fenced_mgr->provider->flush(fenced_mgr->provider); } -#endif -void -fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) +static void +fenced_bufmgr_destroy(struct pb_manager *mgr) { - pipe_mutex_lock(fenced_list->mutex); + struct fenced_manager *fenced_mgr = fenced_manager(mgr); + + pipe_mutex_lock(fenced_mgr->mutex); /* Wait on outstanding fences */ - while (fenced_list->numDelayed) { - pipe_mutex_unlock(fenced_list->mutex); + while (fenced_mgr->num_fenced) { + pipe_mutex_unlock(fenced_mgr->mutex); #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) sched_yield(); #endif - pipe_mutex_lock(fenced_list->mutex); - fenced_buffer_list_check_free_locked(fenced_list, 1); + pipe_mutex_lock(fenced_mgr->mutex); + while(fenced_manager_check_signalled_locked(fenced_mgr, TRUE)) + ; } #ifdef DEBUG - /*assert(!fenced_list->numUnfenced);*/ + /*assert(!fenced_mgr->num_unfenced);*/ #endif - - pipe_mutex_unlock(fenced_list->mutex); - pipe_mutex_destroy(fenced_list->mutex); - - fenced_list->ops->destroy(fenced_list->ops); - - FREE(fenced_list); + + pipe_mutex_unlock(fenced_mgr->mutex); + pipe_mutex_destroy(fenced_mgr->mutex); + + if(fenced_mgr->provider) + fenced_mgr->provider->destroy(fenced_mgr->provider); + + fenced_mgr->ops->destroy(fenced_mgr->ops); + + FREE(fenced_mgr); } +struct pb_manager * +fenced_bufmgr_create(struct pb_manager *provider, + struct pb_fence_ops *ops, + pb_size max_buffer_size, + pb_size max_cpu_total_size) +{ + struct fenced_manager *fenced_mgr; + + if(!provider) + return NULL; + + fenced_mgr = CALLOC_STRUCT(fenced_manager); + if (!fenced_mgr) + return NULL; + + fenced_mgr->base.destroy = fenced_bufmgr_destroy; + fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; + fenced_mgr->base.flush = fenced_bufmgr_flush; + + fenced_mgr->provider = provider; + fenced_mgr->ops = ops; + fenced_mgr->max_buffer_size = max_buffer_size; + fenced_mgr->max_cpu_total_size = max_cpu_total_size; + + LIST_INITHEAD(&fenced_mgr->fenced); + fenced_mgr->num_fenced = 0; + + LIST_INITHEAD(&fenced_mgr->unfenced); + fenced_mgr->num_unfenced = 0; + + pipe_mutex_init(fenced_mgr->mutex); + + return &fenced_mgr->base; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h index 034ca1e024..0372f81d0a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h @@ -98,43 +98,6 @@ struct pb_fence_ops }; -/** - * Create a fenced buffer list. - * - * See also fenced_bufmgr_create for a more convenient way to use this. - */ -struct fenced_buffer_list * -fenced_buffer_list_create(struct pb_fence_ops *ops); - - -/** - * Walk the fenced buffer list to check and free signalled buffers. - */ -void -fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, - int wait); - - -#ifdef DEBUG -void -fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list); -#endif - - -void -fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list); - - -/** - * Wrap a buffer in a fenced buffer. - * - * NOTE: this will not increase the buffer reference count. - */ -struct pb_buffer * -fenced_buffer_create(struct fenced_buffer_list *fenced, - struct pb_buffer *buffer); - - #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 8c8d713078..06669917ff 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -175,7 +175,9 @@ struct pb_fence_ops; */ struct pb_manager * fenced_bufmgr_create(struct pb_manager *provider, - struct pb_fence_ops *ops); + struct pb_fence_ops *ops, + pb_size max_buffer_size, + pb_size max_cpu_total_size); struct pb_manager * diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 7b34c8e357..c1498318df 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -36,7 +36,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 6e3214ca9c..93f8960641 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_double_list.h" @@ -371,6 +371,9 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr, struct pb_desc real_desc; pb_size real_size; + assert(size); + assert(desc->alignment); + buf = CALLOC_STRUCT(pb_debug_buffer); if(!buf) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c deleted file mode 100644 index 97dd1427fd..0000000000 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/** - * \file - * A buffer manager that wraps buffers in fenced buffers. - * - * \author Jose Fonseca <jrfonseca@tungstengraphics.dot.com> - */ - - -#include "util/u_debug.h" -#include "util/u_memory.h" - -#include "pb_buffer.h" -#include "pb_buffer_fenced.h" -#include "pb_bufmgr.h" - - -struct fenced_pb_manager -{ - struct pb_manager base; - - struct pb_manager *provider; - - struct fenced_buffer_list *fenced_list; -}; - - -static INLINE struct fenced_pb_manager * -fenced_pb_manager(struct pb_manager *mgr) -{ - assert(mgr); - return (struct fenced_pb_manager *)mgr; -} - - -static struct pb_buffer * -fenced_bufmgr_create_buffer(struct pb_manager *mgr, - pb_size size, - const struct pb_desc *desc) -{ - struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); - struct pb_buffer *buf; - struct pb_buffer *fenced_buf; - - /* check for free buffers before allocating new ones */ - fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0); - - buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); - if(!buf) { - /* try harder to get a buffer */ - fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1); - - buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); - if(!buf) { -#if 0 - fenced_buffer_list_dump(fenced_mgr->fenced_list); -#endif - - /* give up */ - return NULL; - } - } - - fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf); - if(!fenced_buf) { - pb_reference(&buf, NULL); - } - - return fenced_buf; -} - - -static void -fenced_bufmgr_flush(struct pb_manager *mgr) -{ - struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); - - fenced_buffer_list_check_free(fenced_mgr->fenced_list, TRUE); - - assert(fenced_mgr->provider->flush); - if(fenced_mgr->provider->flush) - fenced_mgr->provider->flush(fenced_mgr->provider); -} - - -static void -fenced_bufmgr_destroy(struct pb_manager *mgr) -{ - struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); - - fenced_buffer_list_destroy(fenced_mgr->fenced_list); - - if(fenced_mgr->provider) - fenced_mgr->provider->destroy(fenced_mgr->provider); - - FREE(fenced_mgr); -} - - -struct pb_manager * -fenced_bufmgr_create(struct pb_manager *provider, - struct pb_fence_ops *ops) -{ - struct fenced_pb_manager *fenced_mgr; - - if(!provider) - return NULL; - - fenced_mgr = CALLOC_STRUCT(fenced_pb_manager); - if (!fenced_mgr) - return NULL; - - fenced_mgr->base.destroy = fenced_bufmgr_destroy; - fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; - fenced_mgr->base.flush = fenced_bufmgr_flush; - - fenced_mgr->provider = provider; - fenced_mgr->fenced_list = fenced_buffer_list_create(ops); - if(!fenced_mgr->fenced_list) { - FREE(fenced_mgr); - return NULL; - } - - return &fenced_mgr->base; -} diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 6400fc5b0a..63195715d6 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -35,7 +35,7 @@ #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_mm.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 7fd65ed226..fea234ae8c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,7 +37,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index d21910d0bf..c445cb578b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index ce40c0cf0e..903afc749d 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -39,7 +39,6 @@ #include "util/u_debug.h" #include "pb_buffer.h" -#include "pb_buffer_fenced.h" #include "pb_validate.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index ffed768f97..65d5ce795b 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -32,7 +32,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "rtasm_execmem.h" @@ -58,7 +58,7 @@ #include <unistd.h> #include <sys/mman.h> -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_mm.h" #define EXEC_HEAP_SIZE (10*1024*1024) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 1acf3c373e..f675427d98 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -673,6 +673,13 @@ void x86_and( struct x86_function *p, emit_op_modrm( p, 0x23, 0x21, dst, src ); } +void x86_div( struct x86_function *p, + struct x86_reg src ) +{ + assert(src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg(file_REG32, 6), src); +} + /*********************************************************************** diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 731a651796..f7612d416a 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -244,6 +244,7 @@ void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_sahf( struct x86_function *p ); +void x86_div( struct x86_function *p, struct x86_reg src ); void x86_cdecl_caller_push_regs( struct x86_function *p ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index de9cbc8630..0890078cd0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -103,10 +103,11 @@ tgsi_default_declaration( void ) declaration.File = TGSI_FILE_NULL; declaration.UsageMask = TGSI_WRITEMASK_XYZW; declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; + declaration.Dimension = 0; declaration.Semantic = 0; declaration.Centroid = 0; declaration.Invariant = 0; - declaration.Padding = 0; + declaration.CylindricalWrap = 0; return declaration; } @@ -116,9 +117,11 @@ tgsi_build_declaration( unsigned file, unsigned usage_mask, unsigned interpolate, + unsigned dimension, unsigned semantic, unsigned centroid, unsigned invariant, + unsigned cylindrical_wrap, struct tgsi_header *header ) { struct tgsi_declaration declaration; @@ -130,9 +133,11 @@ tgsi_build_declaration( declaration.File = file; declaration.UsageMask = usage_mask; declaration.Interpolate = interpolate; + declaration.Dimension = dimension; declaration.Semantic = semantic; declaration.Centroid = centroid; declaration.Invariant = invariant; + declaration.CylindricalWrap = cylindrical_wrap; header_bodysize_grow( header ); @@ -183,9 +188,11 @@ tgsi_build_full_declaration( full_decl->Declaration.File, full_decl->Declaration.UsageMask, full_decl->Declaration.Interpolate, + full_decl->Declaration.Dimension, full_decl->Declaration.Semantic, full_decl->Declaration.Centroid, full_decl->Declaration.Invariant, + full_decl->Declaration.CylindricalWrap, header ); if (maxsize <= size) @@ -199,6 +206,20 @@ tgsi_build_full_declaration( declaration, header ); + if (full_decl->Declaration.Dimension) { + struct tgsi_declaration_dimension *dd; + + if (maxsize <= size) { + return 0; + } + dd = (struct tgsi_declaration_dimension *)&tokens[size]; + size++; + + *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D, + declaration, + header); + } + if( full_decl->Declaration.Semantic ) { struct tgsi_declaration_semantic *ds; @@ -249,6 +270,34 @@ tgsi_build_declaration_range( return declaration_range; } +struct tgsi_declaration_dimension +tgsi_default_declaration_dimension(void) +{ + struct tgsi_declaration_dimension dd; + + dd.Index2D = 0; + dd.Padding = 0; + + return dd; +} + +struct tgsi_declaration_dimension +tgsi_build_declaration_dimension(unsigned index_2d, + struct tgsi_declaration *declaration, + struct tgsi_header *header) +{ + struct tgsi_declaration_dimension dd; + + assert(index_2d <= 0xFFFF); + + dd = tgsi_default_declaration_dimension(); + dd.Index2D = index_2d; + + declaration_grow(declaration, header); + + return dd; +} + struct tgsi_declaration_semantic tgsi_default_declaration_semantic( void ) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h index 9de2757fe4..13d7f5272d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -64,9 +64,11 @@ tgsi_build_declaration( unsigned file, unsigned usage_mask, unsigned interpolate, + unsigned dimension, unsigned semantic, unsigned centroid, unsigned invariant, + unsigned cylindrical_wrap, struct tgsi_header *header ); struct tgsi_full_declaration @@ -89,6 +91,14 @@ tgsi_build_declaration_range( struct tgsi_declaration *declaration, struct tgsi_header *header ); +struct tgsi_declaration_dimension +tgsi_default_declaration_dimension(void); + +struct tgsi_declaration_dimension +tgsi_build_declaration_dimension(unsigned index_2d, + struct tgsi_declaration *declaration, + struct tgsi_header *header); + struct tgsi_declaration_semantic tgsi_default_declaration_semantic( void ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index e2e5394f86..57031419f8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -123,7 +123,8 @@ static const char *semantic_names[] = "NORMAL", "FACE", "EDGEFLAG", - "PRIM_ID" + "PRIM_ID", + "INSTANCEID" }; static const char *immediate_type_names[] = @@ -158,7 +159,9 @@ static const char *property_names[] = { "GS_INPUT_PRIMITIVE", "GS_OUTPUT_PRIMITIVE", - "GS_MAX_OUTPUT_VERTICES" + "GS_MAX_OUTPUT_VERTICES", + "FS_COORD_ORIGIN", + "FS_COORD_PIXEL_CENTER" }; static const char *primitive_names[] = @@ -175,29 +178,18 @@ static const char *primitive_names[] = "POLYGON" }; +static const char *fs_coord_origin_names[] = +{ + "UPPER_LEFT", + "LOWER_LEFT" +}; -static void -_dump_register_decl( - struct dump_ctx *ctx, - uint file, - int first, - int last ) +static const char *fs_coord_pixel_center_names[] = { - ENM( file, file_names ); + "HALF_INTEGER", + "INTEGER" +}; - /* all geometry shader inputs are two dimensional */ - if (file == TGSI_FILE_INPUT && - ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) - TXT("[]"); - - CHR( '[' ); - SID( first ); - if (first != last) { - TXT( ".." ); - SID( last ); - } - CHR( ']' ); -} static void _dump_register_dst( @@ -218,8 +210,13 @@ _dump_register_src( struct dump_ctx *ctx, const struct tgsi_full_src_register *src ) { + ENM(src->Register.File, file_names); + if (src->Register.Dimension) { + CHR('['); + SID(src->Dimension.Index); + CHR(']'); + } if (src->Register.Indirect) { - ENM( src->Register.File, file_names ); CHR( '[' ); ENM( src->Indirect.File, file_names ); CHR( '[' ); @@ -233,16 +230,10 @@ _dump_register_src( } CHR( ']' ); } else { - ENM( src->Register.File, file_names ); CHR( '[' ); SID( src->Register.Index ); CHR( ']' ); } - if (src->Register.Dimension) { - CHR( '[' ); - SID( src->Dimension.Index ); - CHR( ']' ); - } } static void @@ -299,11 +290,28 @@ iter_declaration( TXT( "DCL " ); - _dump_register_decl( - ctx, - decl->Declaration.File, - decl->Range.First, - decl->Range.Last ); + ENM(decl->Declaration.File, file_names); + + /* all geometry shader inputs are two dimensional */ + if (decl->Declaration.File == TGSI_FILE_INPUT && + iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) { + TXT("[]"); + } + + if (decl->Declaration.Dimension) { + CHR('['); + SID(decl->Dim.Index2D); + CHR(']'); + } + + CHR('['); + SID(decl->Range.First); + if (decl->Range.First != decl->Range.Last) { + TXT(".."); + SID(decl->Range.Last); + } + CHR(']'); + _dump_writemask( ctx, decl->Declaration.UsageMask ); @@ -334,6 +342,22 @@ iter_declaration( TXT( ", INVARIANT" ); } + if (decl->Declaration.CylindricalWrap) { + TXT(", CYLWRAP_"); + if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { + CHR('X'); + } + if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { + CHR('Y'); + } + if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { + CHR('Z'); + } + if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { + CHR('W'); + } + } + EOL(); return TRUE; @@ -372,6 +396,12 @@ iter_property( case TGSI_PROPERTY_GS_OUTPUT_PRIM: ENM(prop->u[i].Data, primitive_names); break; + case TGSI_PROPERTY_FS_COORD_ORIGIN: + ENM(prop->u[i].Data, fs_coord_origin_names); + break; + case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER: + ENM(prop->u[i].Data, fs_coord_pixel_center_names); + break; default: SID( prop->u[i].Data ); break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c deleted file mode 100644 index 47fd1dd590..0000000000 --- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c +++ /dev/null @@ -1,462 +0,0 @@ -/************************************************************************** - * - * Copyright 2007-2008 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 "util/u_debug.h" -#include "util/u_string.h" -#include "tgsi_dump_c.h" -#include "tgsi_build.h" -#include "tgsi_info.h" -#include "tgsi_parse.h" - -static void -dump_enum( - const unsigned e, - const char **enums, - const unsigned enums_count ) -{ - if (e >= enums_count) { - debug_printf( "%u", e ); - } - else { - debug_printf( "%s", enums[e] ); - } -} - -#define EOL() debug_printf( "\n" ) -#define TXT(S) debug_printf( "%s", S ) -#define CHR(C) debug_printf( "%c", C ) -#define UIX(I) debug_printf( "0x%x", I ) -#define UID(I) debug_printf( "%u", I ) -#define SID(I) debug_printf( "%d", I ) -#define FLT(F) debug_printf( "%10.4f", F ) -#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) - -static const char *TGSI_PROCESSOR_TYPES[] = -{ - "PROCESSOR_FRAGMENT", - "PROCESSOR_VERTEX", - "PROCESSOR_GEOMETRY" -}; - -static const char *TGSI_TOKEN_TYPES[] = -{ - "TOKEN_TYPE_DECLARATION", - "TOKEN_TYPE_IMMEDIATE", - "TOKEN_TYPE_INSTRUCTION" -}; - -static const char *TGSI_FILES[TGSI_FILE_COUNT] = -{ - "FILE_NULL", - "FILE_CONSTANT", - "FILE_INPUT", - "FILE_OUTPUT", - "FILE_TEMPORARY", - "FILE_SAMPLER", - "FILE_ADDRESS", - "FILE_IMMEDIATE", - "FILE_LOOP", - "FILE_PREDICATE" -}; - -static const char *TGSI_INTERPOLATES[] = -{ - "INTERPOLATE_CONSTANT", - "INTERPOLATE_LINEAR", - "INTERPOLATE_PERSPECTIVE" -}; - -static const char *TGSI_SEMANTICS[] = -{ - "SEMANTIC_POSITION", - "SEMANTIC_COLOR", - "SEMANTIC_BCOLOR", - "SEMANTIC_FOG", - "SEMANTIC_PSIZE", - "SEMANTIC_GENERIC", - "SEMANTIC_NORMAL" -}; - -static const char *TGSI_IMMS[] = -{ - "IMM_FLOAT32" -}; - -static const char *TGSI_SATS[] = -{ - "SAT_NONE", - "SAT_ZERO_ONE", - "SAT_MINUS_PLUS_ONE" -}; - -static const char *TGSI_SWIZZLES[] = -{ - "SWIZZLE_X", - "SWIZZLE_Y", - "SWIZZLE_Z", - "SWIZZLE_W" -}; - -static const char *TGSI_TEXTURES[] = -{ - "TEXTURE_UNKNOWN", - "TEXTURE_1D", - "TEXTURE_2D", - "TEXTURE_3D", - "TEXTURE_CUBE", - "TEXTURE_RECT", - "TEXTURE_SHADOW1D", - "TEXTURE_SHADOW2D", - "TEXTURE_SHADOWRECT" -}; - -static const char *TGSI_WRITEMASKS[] = -{ - "0", - "WRITEMASK_X", - "WRITEMASK_Y", - "WRITEMASK_XY", - "WRITEMASK_Z", - "WRITEMASK_XZ", - "WRITEMASK_YZ", - "WRITEMASK_XYZ", - "WRITEMASK_W", - "WRITEMASK_XW", - "WRITEMASK_YW", - "WRITEMASK_XYW", - "WRITEMASK_ZW", - "WRITEMASK_XZW", - "WRITEMASK_YZW", - "WRITEMASK_XYZW" -}; - -static void -dump_declaration_verbose( - struct tgsi_full_declaration *decl, - unsigned ignored, - unsigned deflt, - struct tgsi_full_declaration *fd ) -{ - TXT( "\nFile : " ); - ENM( decl->Declaration.File, TGSI_FILES ); - if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { - TXT( "\nUsageMask : " ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { - CHR( 'X' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { - CHR( 'Y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { - CHR( 'Z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { - CHR( 'W' ); - } - } - if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { - TXT( "\nInterpolate: " ); - ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); - } - if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { - TXT( "\nSemantic : " ); - UID( decl->Declaration.Semantic ); - } - if (deflt || fd->Declaration.Centroid != decl->Declaration.Centroid) { - TXT("\nCentroid : "); - UID(decl->Declaration.Centroid); - } - if (deflt || fd->Declaration.Invariant != decl->Declaration.Invariant) { - TXT("\nInvariant : "); - UID(decl->Declaration.Invariant); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Declaration.Padding ); - } - - EOL(); - TXT( "\nFirst: " ); - UID( decl->Range.First ); - TXT( "\nLast : " ); - UID( decl->Range.Last ); - - if( decl->Declaration.Semantic ) { - EOL(); - TXT( "\nName : " ); - ENM( decl->Semantic.Name, TGSI_SEMANTICS ); - TXT( "\nIndex: " ); - UID( decl->Semantic.Index ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Semantic.Padding ); - } - } -} - -static void -dump_immediate_verbose( - struct tgsi_full_immediate *imm, - unsigned ignored ) -{ - unsigned i; - - TXT( "\nDataType : " ); - ENM( imm->Immediate.DataType, TGSI_IMMS ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( imm->Immediate.Padding ); - } - - assert( imm->Immediate.NrTokens <= 4 + 1 ); - for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) { - EOL(); - switch( imm->Immediate.DataType ) { - case TGSI_IMM_FLOAT32: - TXT( "\nFloat: " ); - FLT( imm->u[i].Float ); - break; - - default: - assert( 0 ); - } - } -} - -static void -dump_instruction_verbose( - struct tgsi_full_instruction *inst, - unsigned ignored, - unsigned deflt, - struct tgsi_full_instruction *fi ) -{ - unsigned i; - - TXT( "\nOpcode : OPCODE_" ); - TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic ); - if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { - TXT( "\nSaturate : " ); - ENM( inst->Instruction.Saturate, TGSI_SATS ); - } - if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { - TXT( "\nNumDstRegs : " ); - UID( inst->Instruction.NumDstRegs ); - } - if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { - TXT( "\nNumSrcRegs : " ); - UID( inst->Instruction.NumSrcRegs ); - } - if (deflt || fi->Instruction.Predicate != inst->Instruction.Predicate) { - TXT("\nPredicate : "); - UID(inst->Instruction.Predicate); - } - if (deflt || fi->Instruction.Label != inst->Instruction.Label) { - TXT("\nLabel : "); - UID(inst->Instruction.Label); - } - if (deflt || fi->Instruction.Texture != inst->Instruction.Texture) { - TXT("\nTexture : "); - UID(inst->Instruction.Texture); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->Instruction.Padding ); - } - - if (deflt || inst->Instruction.Label) { - EOL(); - if (deflt || fi->Label.Label != inst->Label.Label) { - TXT( "\nLabel : " ); - UID(inst->Label.Label); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX(inst->Label.Padding); - } - } - - if (deflt || inst->Instruction.Texture) { - EOL(); - if (deflt || fi->Texture.Texture != inst->Texture.Texture) { - TXT( "\nTexture : " ); - ENM(inst->Texture.Texture, TGSI_TEXTURES); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX(inst->Texture.Padding); - } - } - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->Dst[i]; - struct tgsi_full_dst_register *fd = &fi->Dst[i]; - - EOL(); - TXT( "\nFile : " ); - ENM( dst->Register.File, TGSI_FILES ); - if( deflt || fd->Register.WriteMask != dst->Register.WriteMask ) { - TXT( "\nWriteMask: " ); - ENM( dst->Register.WriteMask, TGSI_WRITEMASKS ); - } - if( ignored ) { - if( deflt || fd->Register.Indirect != dst->Register.Indirect ) { - TXT( "\nIndirect : " ); - UID( dst->Register.Indirect ); - } - if( deflt || fd->Register.Dimension != dst->Register.Dimension ) { - TXT( "\nDimension: " ); - UID( dst->Register.Dimension ); - } - } - if( deflt || fd->Register.Index != dst->Register.Index ) { - TXT( "\nIndex : " ); - SID( dst->Register.Index ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->Register.Padding ); - } - } - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->Src[i]; - struct tgsi_full_src_register *fs = &fi->Src[i]; - - EOL(); - TXT( "\nFile : "); - ENM( src->Register.File, TGSI_FILES ); - if( deflt || fs->Register.SwizzleX != src->Register.SwizzleX ) { - TXT( "\nSwizzleX : " ); - ENM( src->Register.SwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fs->Register.SwizzleY != src->Register.SwizzleY ) { - TXT( "\nSwizzleY : " ); - ENM( src->Register.SwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fs->Register.SwizzleZ != src->Register.SwizzleZ ) { - TXT( "\nSwizzleZ : " ); - ENM( src->Register.SwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fs->Register.SwizzleW != src->Register.SwizzleW ) { - TXT( "\nSwizzleW : " ); - ENM( src->Register.SwizzleW, TGSI_SWIZZLES ); - } - if (deflt || fs->Register.Absolute != src->Register.Absolute) { - TXT("\nAbsolute : "); - UID(src->Register.Absolute); - } - if( deflt || fs->Register.Negate != src->Register.Negate ) { - TXT( "\nNegate : " ); - UID( src->Register.Negate ); - } - if( ignored ) { - if( deflt || fs->Register.Indirect != src->Register.Indirect ) { - TXT( "\nIndirect : " ); - UID( src->Register.Indirect ); - } - if( deflt || fs->Register.Dimension != src->Register.Dimension ) { - TXT( "\nDimension: " ); - UID( src->Register.Dimension ); - } - } - if( deflt || fs->Register.Index != src->Register.Index ) { - TXT( "\nIndex : " ); - SID( src->Register.Index ); - } - } -} - -void -tgsi_dump_c( - const struct tgsi_token *tokens, - uint flags ) -{ - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - uint ignored = flags & TGSI_DUMP_C_IGNORED; - uint deflt = flags & TGSI_DUMP_C_DEFAULT; - - tgsi_parse_init( &parse, tokens ); - - TXT( "tgsi-dump begin -----------------" ); - - TXT( "\nHeaderSize: " ); - UID( parse.FullHeader.Header.HeaderSize ); - TXT( "\nBodySize : " ); - UID( parse.FullHeader.Header.BodySize ); - TXT( "\nProcessor : " ); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - EOL(); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - tgsi_parse_token( &parse ); - - TXT( "\nType : " ); - ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); - if( ignored ) { - TXT( "\nSize : " ); - UID( parse.FullToken.Token.NrTokens ); - } - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_verbose( - &parse.FullToken.FullDeclaration, - ignored, - deflt, - &fd ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_verbose( - &parse.FullToken.FullImmediate, - ignored ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_verbose( - &parse.FullToken.FullInstruction, - ignored, - deflt, - &fi ); - break; - - default: - assert( 0 ); - } - - EOL(); - } - - TXT( "\ntgsi-dump end -------------------\n" ); - - tgsi_parse_free( &parse ); -} diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 2bcb33392a..262422364b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -264,6 +264,12 @@ static void micro_rcp(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { +#if 0 /* for debugging */ + assert(src->f[0] != 0.0f); + assert(src->f[1] != 0.0f); + assert(src->f[2] != 0.0f); + assert(src->f[3] != 0.0f); +#endif dst->f[0] = 1.0f / src->f[0]; dst->f[1] = 1.0f / src->f[1]; dst->f[2] = 1.0f / src->f[2]; @@ -284,6 +290,12 @@ static void micro_rsq(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { +#if 0 /* for debugging */ + assert(src->f[0] != 0.0f); + assert(src->f[1] != 0.0f); + assert(src->f[2] != 0.0f); + assert(src->f[3] != 0.0f); +#endif dst->f[0] = 1.0f / sqrtf(fabsf(src->f[0])); dst->f[1] = 1.0f / sqrtf(fabsf(src->f[1])); dst->f[2] = 1.0f / sqrtf(fabsf(src->f[2])); @@ -450,12 +462,20 @@ static const union tgsi_exec_channel ZeroVec = { { 0.0, 0.0, 0.0, 0.0 } }; -#define CHECK_INF_OR_NAN(chan) do {\ - assert(!util_is_inf_or_nan((chan)->f[0]));\ - assert(!util_is_inf_or_nan((chan)->f[1]));\ - assert(!util_is_inf_or_nan((chan)->f[2]));\ - assert(!util_is_inf_or_nan((chan)->f[3]));\ - } while (0) +/** + * Assert that none of the float values in 'chan' are infinite or NaN. + * NaN and Inf may occur normally during program execution and should + * not lead to crashes, etc. But when debugging, it's helpful to catch + * them. + */ +static INLINE void +check_inf_or_nan(const union tgsi_exec_channel *chan) +{ + assert(!util_is_inf_or_nan((chan)->f[0])); + assert(!util_is_inf_or_nan((chan)->f[1])); + assert(!util_is_inf_or_nan((chan)->f[2])); + assert(!util_is_inf_or_nan((chan)->f[3])); +} #ifdef DEBUG @@ -953,99 +973,90 @@ micro_sub( } static void -fetch_src_file_channel( - const struct tgsi_exec_machine *mach, - const uint file, - const uint swizzle, - const union tgsi_exec_channel *index, - union tgsi_exec_channel *chan ) -{ - switch( swizzle ) { - case TGSI_SWIZZLE_X: - case TGSI_SWIZZLE_Y: - case TGSI_SWIZZLE_Z: - case TGSI_SWIZZLE_W: - switch( file ) { - case TGSI_FILE_CONSTANT: - assert(mach->Consts); - if (index->i[0] < 0) - chan->f[0] = 0.0f; - else - chan->f[0] = mach->Consts[index->i[0]][swizzle]; - if (index->i[1] < 0) - chan->f[1] = 0.0f; - else - chan->f[1] = mach->Consts[index->i[1]][swizzle]; - if (index->i[2] < 0) - chan->f[2] = 0.0f; - else - chan->f[2] = mach->Consts[index->i[2]][swizzle]; - if (index->i[3] < 0) - chan->f[3] = 0.0f; - else - chan->f[3] = mach->Consts[index->i[3]][swizzle]; - break; +fetch_src_file_channel(const struct tgsi_exec_machine *mach, + const uint file, + const uint swizzle, + const union tgsi_exec_channel *index, + const union tgsi_exec_channel *index2D, + union tgsi_exec_channel *chan) +{ + uint i; - case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: - chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; - break; + switch (file) { + case TGSI_FILE_CONSTANT: + for (i = 0; i < QUAD_SIZE; i++) { + assert(index2D->i[i] >= 0 && index2D->i[i] < PIPE_MAX_CONSTANT_BUFFERS); + assert(mach->Consts[index2D->i[i]]); - case TGSI_FILE_TEMPORARY: - assert(index->i[0] < TGSI_EXEC_NUM_TEMPS); - chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; - break; + if (index->i[i] < 0) { + chan->u[i] = 0; + } else { + const uint *p = (const uint *)mach->Consts[index2D->i[i]]; - case TGSI_FILE_IMMEDIATE: - assert( index->i[0] < (int) mach->ImmLimit ); - chan->f[0] = mach->Imms[index->i[0]][swizzle]; - assert( index->i[1] < (int) mach->ImmLimit ); - chan->f[1] = mach->Imms[index->i[1]][swizzle]; - assert( index->i[2] < (int) mach->ImmLimit ); - chan->f[2] = mach->Imms[index->i[2]][swizzle]; - assert( index->i[3] < (int) mach->ImmLimit ); - chan->f[3] = mach->Imms[index->i[3]][swizzle]; - break; + chan->u[i] = p[index->i[i] * 4 + swizzle]; + } + } + break; - case TGSI_FILE_ADDRESS: - chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; - break; + case TGSI_FILE_INPUT: + case TGSI_FILE_SYSTEM_VALUE: + for (i = 0; i < QUAD_SIZE; i++) { + /* XXX: 2D indexing */ + chan->u[i] = mach->Inputs[index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]].xyzw[swizzle].u[i]; + } + break; - case TGSI_FILE_PREDICATE: - assert(index->i[0] < TGSI_EXEC_NUM_PREDS); - assert(index->i[1] < TGSI_EXEC_NUM_PREDS); - assert(index->i[2] < TGSI_EXEC_NUM_PREDS); - assert(index->i[3] < TGSI_EXEC_NUM_PREDS); - chan->u[0] = mach->Predicates[0].xyzw[swizzle].u[0]; - chan->u[1] = mach->Predicates[0].xyzw[swizzle].u[1]; - chan->u[2] = mach->Predicates[0].xyzw[swizzle].u[2]; - chan->u[3] = mach->Predicates[0].xyzw[swizzle].u[3]; - break; + case TGSI_FILE_TEMPORARY: + for (i = 0; i < QUAD_SIZE; i++) { + assert(index->i[i] < TGSI_EXEC_NUM_TEMPS); + assert(index2D->i[i] == 0); - case TGSI_FILE_OUTPUT: - /* vertex/fragment output vars can be read too */ - chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; - break; + chan->u[i] = mach->Temps[index->i[i]].xyzw[swizzle].u[i]; + } + break; - default: - assert( 0 ); + case TGSI_FILE_IMMEDIATE: + for (i = 0; i < QUAD_SIZE; i++) { + assert(index->i[i] >= 0 && index->i[i] < (int)mach->ImmLimit); + assert(index2D->i[i] == 0); + + chan->f[i] = mach->Imms[index->i[i]][swizzle]; + } + break; + + case TGSI_FILE_ADDRESS: + for (i = 0; i < QUAD_SIZE; i++) { + assert(index->i[i] >= 0); + assert(index2D->i[i] == 0); + + chan->u[i] = mach->Addrs[index->i[i]].xyzw[swizzle].u[i]; + } + break; + + case TGSI_FILE_PREDICATE: + for (i = 0; i < QUAD_SIZE; i++) { + assert(index->i[i] >= 0 && index->i[i] < TGSI_EXEC_NUM_PREDS); + assert(index2D->i[i] == 0); + + chan->u[i] = mach->Predicates[0].xyzw[swizzle].u[i]; + } + break; + + case TGSI_FILE_OUTPUT: + /* vertex/fragment output vars can be read too */ + for (i = 0; i < QUAD_SIZE; i++) { + assert(index->i[i] >= 0); + assert(index2D->i[i] == 0); + + chan->u[i] = mach->Outputs[index->i[i]].xyzw[swizzle].u[i]; } break; default: - assert( 0 ); + assert(0); + for (i = 0; i < QUAD_SIZE; i++) { + chan->u[i] = 0; + } } } @@ -1057,6 +1068,7 @@ fetch_source(const struct tgsi_exec_machine *mach, enum tgsi_exec_datatype src_datatype) { union tgsi_exec_channel index; + union tgsi_exec_channel index2D; uint swizzle; /* We start with a direct index into a register file. @@ -1095,12 +1107,12 @@ fetch_source(const struct tgsi_exec_machine *mach, /* get current value of address register[swizzle] */ swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X ); - fetch_src_file_channel( - mach, - reg->Indirect.File, - swizzle, - &index2, - &indir_index ); + fetch_src_file_channel(mach, + reg->Indirect.File, + swizzle, + &index2, + &ZeroVec, + &indir_index); /* add value of address register to the offset */ index.i[0] += indir_index.i[0]; @@ -1121,44 +1133,22 @@ fetch_source(const struct tgsi_exec_machine *mach, * subscript to a register file. Effectively it means that * the register file is actually a 2D array of registers. * - * file[1][3] == file[1*sizeof(file[1])+3], + * file[3][1], * where: * [3] = Dimension.Index */ if (reg->Register.Dimension) { - /* The size of the first-order array depends on the register file type. - * We need to multiply the index to the first array to get an effective, - * "flat" index that points to the beginning of the second-order array. - */ - switch (reg->Register.File) { - case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: - index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; - index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; - index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; - index.i[3] *= TGSI_EXEC_MAX_INPUT_ATTRIBS; - break; - case TGSI_FILE_CONSTANT: - index.i[0] *= TGSI_EXEC_MAX_CONST_BUFFER; - index.i[1] *= TGSI_EXEC_MAX_CONST_BUFFER; - index.i[2] *= TGSI_EXEC_MAX_CONST_BUFFER; - index.i[3] *= TGSI_EXEC_MAX_CONST_BUFFER; - break; - default: - assert( 0 ); - } - - index.i[0] += reg->Dimension.Index; - index.i[1] += reg->Dimension.Index; - index.i[2] += reg->Dimension.Index; - index.i[3] += reg->Dimension.Index; + index2D.i[0] = + index2D.i[1] = + index2D.i[2] = + index2D.i[3] = reg->Dimension.Index; /* Again, the second subscript index can be addressed indirectly * identically to the first one. * Nothing stops us from indirectly addressing the indirect register, * but there is no need for that, so we won't exercise it. * - * file[1][ind[4].y+3], + * file[ind[4].y+3][1], * where: * ind = DimIndirect.File * [4] = DimIndirect.Index @@ -1176,24 +1166,25 @@ fetch_source(const struct tgsi_exec_machine *mach, index2.i[3] = reg->DimIndirect.Index; swizzle = tgsi_util_get_src_register_swizzle( ®->DimIndirect, CHAN_X ); - fetch_src_file_channel( - mach, - reg->DimIndirect.File, - swizzle, - &index2, - &indir_index ); - - index.i[0] += indir_index.i[0]; - index.i[1] += indir_index.i[1]; - index.i[2] += indir_index.i[2]; - index.i[3] += indir_index.i[3]; + fetch_src_file_channel(mach, + reg->DimIndirect.File, + swizzle, + &index2, + &ZeroVec, + &indir_index); + + index2D.i[0] += indir_index.i[0]; + index2D.i[1] += indir_index.i[1]; + index2D.i[2] += indir_index.i[2]; + index2D.i[3] += indir_index.i[3]; /* for disabled execution channels, zero-out the index to * avoid using a potential garbage value. */ for (i = 0; i < QUAD_SIZE; i++) { - if ((execmask & (1 << i)) == 0) - index.i[i] = 0; + if ((execmask & (1 << i)) == 0) { + index2D.i[i] = 0; + } } } @@ -1201,15 +1192,20 @@ fetch_source(const struct tgsi_exec_machine *mach, * files, we would have to check whether Dimension is followed * by a dimension register and continue the saga. */ + } else { + index2D.i[0] = + index2D.i[1] = + index2D.i[2] = + index2D.i[3] = 0; } swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index ); - fetch_src_file_channel( - mach, - reg->Register.File, - swizzle, - &index, - chan ); + fetch_src_file_channel(mach, + reg->Register.File, + swizzle, + &index, + &index2D, + chan); if (reg->Register.Absolute) { if (src_datatype == TGSI_EXEC_DATA_FLOAT) { @@ -1243,8 +1239,9 @@ store_dest(struct tgsi_exec_machine *mach, int offset = 0; /* indirection offset */ int index; - if (dst_datatype == TGSI_EXEC_DATA_FLOAT) { - CHECK_INF_OR_NAN(chan); + /* for debugging */ + if (0 && dst_datatype == TGSI_EXEC_DATA_FLOAT) { + check_inf_or_nan(chan); } /* There is an extra source register that indirectly subscripts @@ -1272,12 +1269,12 @@ store_dest(struct tgsi_exec_machine *mach, swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X ); /* fetch values from the address/indirection register */ - fetch_src_file_channel( - mach, - reg->Indirect.File, - swizzle, - &index, - &indir_index ); + fetch_src_file_channel(mach, + reg->Indirect.File, + swizzle, + &index, + &ZeroVec, + &indir_index); /* save indirection offset */ offset = indir_index.i[0]; @@ -1502,7 +1499,7 @@ emit_primitive(struct tgsi_exec_machine *mach) } /* - * Fetch a four texture samples using STR texture coordinates. + * Fetch four texture samples using STR texture coordinates. */ static void fetch_texel( struct tgsi_sampler *sampler, @@ -1764,13 +1761,7 @@ exec_declaration(struct tgsi_exec_machine *mach, last = decl->Range.Last; mask = decl->Declaration.UsageMask; - if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) { - assert(decl->Semantic.Index == 0); - assert(first == last); - assert(mask == TGSI_WRITEMASK_XYZW); - - mach->Inputs[first] = mach->QuadPos; - } else if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) { + if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) { uint i; assert(decl->Semantic.Index == 0); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 59e3b445cc..a22873e4c2 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -260,7 +260,7 @@ struct tgsi_exec_machine struct tgsi_sampler **Samplers; unsigned ImmLimit; - const float (*Consts)[4]; + const void *Consts[PIPE_MAX_CONSTANT_BUFFERS]; const struct tgsi_token *Tokens; /**< Declarations, instructions */ unsigned Processor; /**< TGSI_PROCESSOR_x */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index 8c7062d850..7e19e1fe36 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -109,6 +109,10 @@ tgsi_parse_token( next_token( ctx, &decl->Range ); + if (decl->Declaration.Dimension) { + next_token(ctx, &decl->Dim); + } + if( decl->Declaration.Semantic ) { next_token( ctx, &decl->Semantic ); } @@ -280,3 +284,14 @@ tgsi_dup_tokens(const struct tgsi_token *tokens) memcpy(new_tokens, tokens, bytes); return new_tokens; } + + +/** + * Allocate memory for num_tokens tokens. + */ +struct tgsi_token * +tgsi_alloc_tokens(unsigned num_tokens) +{ + unsigned bytes = num_tokens * sizeof(struct tgsi_token); + return (struct tgsi_token *) MALLOC(bytes); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index 439a57269b..b45ccee2f6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -58,6 +58,7 @@ struct tgsi_full_declaration { struct tgsi_declaration Declaration; struct tgsi_declaration_range Range; + struct tgsi_declaration_dimension Dim; struct tgsi_declaration_semantic Semantic; }; @@ -129,6 +130,10 @@ tgsi_num_tokens(const struct tgsi_token *tokens); struct tgsi_token * tgsi_dup_tokens(const struct tgsi_token *tokens); +struct tgsi_token * +tgsi_alloc_tokens(unsigned num_tokens); + + #if defined __cplusplus } #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 138d2d095b..ad553c71a5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -51,7 +51,8 @@ * Since it's pretty much impossible to form PPC vector immediates, load * them from memory here: */ -const float ppc_builtin_constants[] ALIGN16_ATTRIB = { +PIPE_ALIGN_VAR(16) const float +ppc_builtin_constants[] = { 1.0f, -128.0f, 128.0, 0.0 }; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 7f1c8e5dd6..91e1b27da1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -335,13 +335,9 @@ iter_instruction( fill_scan_register1d(ind_reg, inst->Src[i].Indirect.File, inst->Src[i].Indirect.Index); - if (!(reg->file == TGSI_FILE_ADDRESS || reg->file == TGSI_FILE_LOOP) || - reg->indices[0] != 0) { - report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]"); - } check_register_usage( ctx, - reg, + ind_reg, "indirect", FALSE ); } @@ -412,12 +408,16 @@ iter_declaration( uint vert; for (vert = 0; vert < ctx->implied_array_size; ++vert) { scan_register *reg = MALLOC(sizeof(scan_register)); - fill_scan_register2d(reg, file, vert, i); + fill_scan_register2d(reg, file, i, vert); check_and_declare(ctx, reg); } } else { scan_register *reg = MALLOC(sizeof(scan_register)); - fill_scan_register1d(reg, file, i); + if (decl->Declaration.Dimension) { + fill_scan_register2d(reg, file, i, decl->Dim.Index2D); + } else { + fill_scan_register1d(reg, file, i); + } check_and_declare(ctx, reg); } } diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index a6cc773003..232fc537c1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -101,12 +101,10 @@ tgsi_scan_shader(const struct tgsi_token *tokens, src->Register.File == TGSI_FILE_SYSTEM_VALUE) { const int ind = src->Register.Index; if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) { - if (src->Register.SwizzleX == TGSI_SWIZZLE_X) { - info->uses_fogcoord = TRUE; - } - else if (src->Register.SwizzleX == TGSI_SWIZZLE_Y) { - info->uses_frontfacing = TRUE; - } + info->uses_fogcoord = TRUE; + } + else if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FACE) { + info->uses_frontfacing = TRUE; } } } @@ -133,6 +131,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate; + info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Declaration.CylindricalWrap; info->num_inputs++; } else if (file == TGSI_FILE_OUTPUT) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h index dae5376c24..741aa7d5c4 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -45,6 +45,7 @@ struct tgsi_shader_info ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; ubyte input_interpolate[PIPE_MAX_SHADER_INPUTS]; + ubyte input_cylindrical_wrap[PIPE_MAX_SHADER_INPUTS]; ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 9fcffeda36..f918151daa 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -29,7 +29,7 @@ #include "util/u_memory.h" #include "util/u_prim.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi_text.h" #include "tgsi_build.h" #include "tgsi_info.h" @@ -553,7 +553,7 @@ parse_register_dcl_bracket( report_error( ctx, "Expected literal unsigned integer" ); return FALSE; } - bracket->first = (int) uindex; + bracket->first = uindex; eat_opt_white( &ctx->cur ); @@ -617,10 +617,12 @@ parse_register_dcl( * input primitive. so we want to declare just * the index relevant to the semantics which is in * the second bracket */ - if (ctx->processor == TGSI_PROCESSOR_GEOMETRY) { + if (ctx->processor == TGSI_PROCESSOR_GEOMETRY && *file == TGSI_FILE_INPUT) { brackets[0] = brackets[1]; + *num_brackets = 1; + } else { + *num_brackets = 2; } - *num_brackets = 2; } return TRUE; @@ -738,6 +740,13 @@ parse_src_operand( return FALSE; src->Register.File = file; + if (parsed_opt_brackets) { + src->Register.Dimension = 1; + src->Dimension.Indirect = 0; + src->Dimension.Dimension = 0; + src->Dimension.Index = bracket[0].index; + bracket[0] = bracket[1]; + } src->Register.Index = bracket[0].index; if (bracket[0].ind_file != TGSI_FILE_NULL) { src->Register.Indirect = 1; @@ -748,12 +757,6 @@ parse_src_operand( src->Indirect.SwizzleZ = bracket[0].ind_comp; src->Indirect.SwizzleW = bracket[0].ind_comp; } - if (parsed_opt_brackets) { - src->Register.Dimension = 1; - src->Dimension.Indirect = 0; - src->Dimension.Dimension = 0; - src->Dimension.Index = bracket[1].index; - } /* Parse optional swizzle. */ @@ -933,7 +936,8 @@ static const char *semantic_names[TGSI_SEMANTIC_COUNT] = "NORMAL", "FACE", "EDGEFLAG", - "PRIM_ID" + "PRIM_ID", + "INSTANCEID" }; static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = @@ -968,8 +972,17 @@ static boolean parse_declaration( struct translate_ctx *ctx ) decl = tgsi_default_full_declaration(); decl.Declaration.File = file; decl.Declaration.UsageMask = writemask; - decl.Range.First = brackets[0].first; - decl.Range.Last = brackets[0].last; + + if (num_brackets == 1) { + decl.Range.First = brackets[0].first; + decl.Range.Last = brackets[0].last; + } else { + decl.Range.First = brackets[1].first; + decl.Range.Last = brackets[1].last; + + decl.Declaration.Dimension = 1; + decl.Dim.Index2D = brackets[0].first; + } cur = ctx->cur; eat_opt_white( &cur ); @@ -1116,7 +1129,9 @@ static const char *property_names[] = { "GS_INPUT_PRIMITIVE", "GS_OUTPUT_PRIMITIVE", - "GS_MAX_OUTPUT_VERTICES" + "GS_MAX_OUTPUT_VERTICES", + "FS_COORD_ORIGIN", + "FS_COORD_PIXEL_CENTER" }; static const char *primitive_names[] = @@ -1133,6 +1148,19 @@ static const char *primitive_names[] = "POLYGON" }; +static const char *fs_coord_origin_names[] = +{ + "UPPER_LEFT", + "LOWER_LEFT" +}; + +static const char *fs_coord_pixel_center_names[] = +{ + "HALF_INTEGER", + "INTEGER" +}; + + static boolean parse_primitive( const char **pcur, uint *primitive ) { @@ -1150,6 +1178,40 @@ parse_primitive( const char **pcur, uint *primitive ) return FALSE; } +static boolean +parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin ) +{ + uint i; + + for (i = 0; i < sizeof(fs_coord_origin_names) / sizeof(fs_coord_origin_names[0]); i++) { + const char *cur = *pcur; + + if (str_match_no_case( &cur, fs_coord_origin_names[i])) { + *fs_coord_origin = i; + *pcur = cur; + return TRUE; + } + } + return FALSE; +} + +static boolean +parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center ) +{ + uint i; + + for (i = 0; i < sizeof(fs_coord_pixel_center_names) / sizeof(fs_coord_pixel_center_names[0]); i++) { + const char *cur = *pcur; + + if (str_match_no_case( &cur, fs_coord_pixel_center_names[i])) { + *fs_coord_pixel_center = i; + *pcur = cur; + return TRUE; + } + } + return FALSE; +} + static boolean parse_property( struct translate_ctx *ctx ) { @@ -1191,6 +1253,18 @@ static boolean parse_property( struct translate_ctx *ctx ) ctx->implied_array_size = u_vertices_per_prim(values[0]); } break; + case TGSI_PROPERTY_FS_COORD_ORIGIN: + if (!parse_fs_coord_origin(&ctx->cur, &values[0] )) { + report_error( ctx, "Unknown coord origin as property: must be UPPER_LEFT or LOWER_LEFT!" ); + return FALSE; + } + break; + case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER: + if (!parse_fs_coord_pixel_center(&ctx->cur, &values[0] )) { + report_error( ctx, "Unknown coord pixel center as property: must be HALF_INTEGER or INTEGER!" ); + return FALSE; + } + break; default: if (!parse_uint(&ctx->cur, &values[0] )) { report_error( ctx, "Expected unsigned integer as property!" ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index e64e2b731d..3d0455de7c 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -33,6 +33,7 @@ #include "tgsi/tgsi_info.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_sanity.h" +#include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_math.h" @@ -40,8 +41,11 @@ union tgsi_any_token { struct tgsi_header header; struct tgsi_processor processor; struct tgsi_token token; + struct tgsi_property prop; + struct tgsi_property_data prop_data; struct tgsi_declaration decl; struct tgsi_declaration_range decl_range; + struct tgsi_declaration_dimension decl_dim; struct tgsi_declaration_semantic decl_semantic; struct tgsi_immediate imm; union tgsi_immediate_data imm_data; @@ -64,6 +68,7 @@ struct ureg_tokens { }; #define UREG_MAX_INPUT PIPE_MAX_ATTRIBS +#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS #define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS #define UREG_MAX_CONSTANT_RANGE 32 #define UREG_MAX_IMMEDIATE 32 @@ -72,6 +77,14 @@ struct ureg_tokens { #define UREG_MAX_LOOP 1 #define UREG_MAX_PRED 1 +struct const_decl { + struct { + unsigned first; + unsigned last; + } constant_range[UREG_MAX_CONSTANT_RANGE]; + unsigned nr_constant_ranges; +}; + #define DOMAIN_DECL 0 #define DOMAIN_INSN 1 @@ -84,6 +97,7 @@ struct ureg_program unsigned semantic_name; unsigned semantic_index; unsigned interp; + unsigned cylindrical_wrap; } fs_input[UREG_MAX_INPUT]; unsigned nr_fs_inputs; @@ -91,10 +105,19 @@ struct ureg_program struct { unsigned index; + unsigned semantic_name; + unsigned semantic_index; } gs_input[UREG_MAX_INPUT]; unsigned nr_gs_inputs; struct { + unsigned index; + unsigned semantic_name; + unsigned semantic_index; + } system_value[UREG_MAX_SYSTEM_VALUE]; + unsigned nr_system_values; + + struct { unsigned semantic_name; unsigned semantic_index; } output[UREG_MAX_OUTPUT]; @@ -117,11 +140,14 @@ struct ureg_program unsigned temps_active[UREG_MAX_TEMP / 32]; unsigned nr_temps; - struct { - unsigned first; - unsigned last; - } constant_range[UREG_MAX_CONSTANT_RANGE]; - unsigned nr_constant_ranges; + struct const_decl const_decls; + struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS]; + + unsigned property_gs_input_prim; + unsigned property_gs_output_prim; + unsigned property_gs_max_vertices; + unsigned char property_fs_coord_origin; /* = TGSI_FS_COORD_ORIGIN_* */ + unsigned char property_fs_coord_pixel_center; /* = TGSI_FS_COORD_PIXEL_CENTER_* */ unsigned nr_addrs; unsigned nr_preds; @@ -223,57 +249,72 @@ ureg_dst_register( unsigned file, return dst; } -static INLINE struct ureg_src -ureg_src_register( unsigned file, - unsigned index ) + +void +ureg_property_gs_input_prim(struct ureg_program *ureg, + unsigned input_prim) { - struct ureg_src src; - - src.File = file; - src.SwizzleX = TGSI_SWIZZLE_X; - src.SwizzleY = TGSI_SWIZZLE_Y; - src.SwizzleZ = TGSI_SWIZZLE_Z; - src.SwizzleW = TGSI_SWIZZLE_W; - src.Pad = 0; - src.Indirect = 0; - src.IndirectIndex = 0; - src.IndirectSwizzle = 0; - src.Absolute = 0; - src.Index = index; - src.Negate = 0; - - return src; + ureg->property_gs_input_prim = input_prim; } +void +ureg_property_gs_output_prim(struct ureg_program *ureg, + unsigned output_prim) +{ + ureg->property_gs_output_prim = output_prim; +} +void +ureg_property_gs_max_vertices(struct ureg_program *ureg, + unsigned max_vertices) +{ + ureg->property_gs_max_vertices = max_vertices; +} +void +ureg_property_fs_coord_origin(struct ureg_program *ureg, + unsigned fs_coord_origin) +{ + ureg->property_fs_coord_origin = fs_coord_origin; +} -struct ureg_src -ureg_DECL_fs_input( struct ureg_program *ureg, - unsigned name, - unsigned index, - unsigned interp_mode ) +void +ureg_property_fs_coord_pixel_center(struct ureg_program *ureg, + unsigned fs_coord_pixel_center) +{ + ureg->property_fs_coord_pixel_center = fs_coord_pixel_center; +} + + + +struct ureg_src +ureg_DECL_fs_input_cyl(struct ureg_program *ureg, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp_mode, + unsigned cylindrical_wrap) { unsigned i; for (i = 0; i < ureg->nr_fs_inputs; i++) { - if (ureg->fs_input[i].semantic_name == name && - ureg->fs_input[i].semantic_index == index) + if (ureg->fs_input[i].semantic_name == semantic_name && + ureg->fs_input[i].semantic_index == semantic_index) { goto out; + } } if (ureg->nr_fs_inputs < UREG_MAX_INPUT) { - ureg->fs_input[i].semantic_name = name; - ureg->fs_input[i].semantic_index = index; + ureg->fs_input[i].semantic_name = semantic_name; + ureg->fs_input[i].semantic_index = semantic_index; ureg->fs_input[i].interp = interp_mode; + ureg->fs_input[i].cylindrical_wrap = cylindrical_wrap; ureg->nr_fs_inputs++; - } - else { - set_bad( ureg ); + } else { + set_bad(ureg); } out: - return ureg_src_register( TGSI_FILE_INPUT, i ); + return ureg_src_register(TGSI_FILE_INPUT, i); } @@ -290,10 +331,14 @@ ureg_DECL_vs_input( struct ureg_program *ureg, struct ureg_src ureg_DECL_gs_input(struct ureg_program *ureg, - unsigned index) + unsigned index, + unsigned semantic_name, + unsigned semantic_index) { if (ureg->nr_gs_inputs < UREG_MAX_INPUT) { ureg->gs_input[ureg->nr_gs_inputs].index = index; + ureg->gs_input[ureg->nr_gs_inputs].semantic_name = semantic_name; + ureg->gs_input[ureg->nr_gs_inputs].semantic_index = semantic_index; ureg->nr_gs_inputs++; } else { set_bad(ureg); @@ -304,6 +349,25 @@ ureg_DECL_gs_input(struct ureg_program *ureg, } +struct ureg_src +ureg_DECL_system_value(struct ureg_program *ureg, + unsigned index, + unsigned semantic_name, + unsigned semantic_index) +{ + if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) { + ureg->system_value[ureg->nr_system_values].index = index; + ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name; + ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index; + ureg->nr_system_values++; + } else { + set_bad(ureg); + } + + return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, index); +} + + struct ureg_dst ureg_DECL_output( struct ureg_program *ureg, unsigned name, @@ -334,62 +398,92 @@ out: /* Returns a new constant register. Keep track of which have been * referred to so that we can emit decls later. * + * Constant operands declared with this function must be addressed + * with a two-dimensional index. + * * There is nothing in this code to bind this constant to any tracked * value or manage any constant_buffer contents -- that's the * resposibility of the calling code. */ -struct ureg_src ureg_DECL_constant(struct ureg_program *ureg, - unsigned index ) +void +ureg_DECL_constant2D(struct ureg_program *ureg, + unsigned first, + unsigned last, + unsigned index2D) { + struct const_decl *decl = &ureg->const_decls2D[index2D]; + + assert(index2D < PIPE_MAX_CONSTANT_BUFFERS); + + if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { + uint i = decl->nr_constant_ranges++; + + decl->constant_range[i].first = first; + decl->constant_range[i].last = last; + } +} + + +/* A one-dimensional, depricated version of ureg_DECL_constant2D(). + * + * Constant operands declared with this function must be addressed + * with a one-dimensional index. + */ +struct ureg_src +ureg_DECL_constant(struct ureg_program *ureg, + unsigned index) +{ + struct const_decl *decl = &ureg->const_decls; unsigned minconst = index, maxconst = index; unsigned i; /* Inside existing range? */ - for (i = 0; i < ureg->nr_constant_ranges; i++) { - if (ureg->constant_range[i].first <= index && - ureg->constant_range[i].last >= index) + for (i = 0; i < decl->nr_constant_ranges; i++) { + if (decl->constant_range[i].first <= index && + decl->constant_range[i].last >= index) { goto out; + } } /* Extend existing range? */ - for (i = 0; i < ureg->nr_constant_ranges; i++) { - if (ureg->constant_range[i].last == index - 1) { - ureg->constant_range[i].last = index; + for (i = 0; i < decl->nr_constant_ranges; i++) { + if (decl->constant_range[i].last == index - 1) { + decl->constant_range[i].last = index; goto out; } - if (ureg->constant_range[i].first == index + 1) { - ureg->constant_range[i].first = index; + if (decl->constant_range[i].first == index + 1) { + decl->constant_range[i].first = index; goto out; } - minconst = MIN2(minconst, ureg->constant_range[i].first); - maxconst = MAX2(maxconst, ureg->constant_range[i].last); + minconst = MIN2(minconst, decl->constant_range[i].first); + maxconst = MAX2(maxconst, decl->constant_range[i].last); } /* Create new range? */ - if (ureg->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { - i = ureg->nr_constant_ranges++; - ureg->constant_range[i].first = index; - ureg->constant_range[i].last = index; + if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { + i = decl->nr_constant_ranges++; + decl->constant_range[i].first = index; + decl->constant_range[i].last = index; goto out; } /* Collapse all ranges down to one: */ i = 0; - ureg->constant_range[0].first = minconst; - ureg->constant_range[0].last = maxconst; - ureg->nr_constant_ranges = 1; + decl->constant_range[0].first = minconst; + decl->constant_range[0].last = maxconst; + decl->nr_constant_ranges = 1; out: - assert(i < ureg->nr_constant_ranges); - assert(ureg->constant_range[i].first <= index); - assert(ureg->constant_range[i].last >= index); - return ureg_src_register( TGSI_FILE_CONSTANT, index ); + assert(i < decl->nr_constant_ranges); + assert(decl->constant_range[i].first <= index); + assert(decl->constant_range[i].last >= index); + return ureg_src_register(TGSI_FILE_CONSTANT, index); } @@ -538,7 +632,7 @@ decl_immediate( struct ureg_program *ureg, unsigned type ) { unsigned i, j; - unsigned swizzle; + unsigned swizzle = 0; /* Could do a first pass where we examine all existing immediates * without expanding. @@ -616,6 +710,35 @@ ureg_DECL_immediate_uint( struct ureg_program *ureg, struct ureg_src +ureg_DECL_immediate_block_uint( struct ureg_program *ureg, + const unsigned *v, + unsigned nr ) +{ + uint index; + uint i; + + if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) { + set_bad(ureg); + return ureg_src_register(TGSI_FILE_IMMEDIATE, 0); + } + + index = ureg->nr_immediates; + ureg->nr_immediates += (nr + 3) / 4; + + for (i = index; i < ureg->nr_immediates; i++) { + ureg->immediate[i].type = TGSI_IMM_UINT32; + ureg->immediate[i].nr = nr > 4 ? 4 : nr; + memcpy(ureg->immediate[i].value.u, + &v[(i - index) * 4], + ureg->immediate[i].nr * sizeof(uint)); + nr -= 4; + } + + return ureg_src_register(TGSI_FILE_IMMEDIATE, index); +} + + +struct ureg_src ureg_DECL_immediate_int( struct ureg_program *ureg, const int *v, unsigned nr ) @@ -628,7 +751,7 @@ void ureg_emit_src( struct ureg_program *ureg, struct ureg_src src ) { - unsigned size = 1 + (src.Indirect ? 1 : 0); + unsigned size = 1 + (src.Indirect ? 1 : 0) + (src.Dimension ? 1 : 0); union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); unsigned n = 0; @@ -651,7 +774,7 @@ ureg_emit_src( struct ureg_program *ureg, if (src.Indirect) { out[0].src.Indirect = 1; out[n].value = 0; - out[n].src.File = TGSI_FILE_ADDRESS; + out[n].src.File = src.IndirectFile; out[n].src.SwizzleX = src.IndirectSwizzle; out[n].src.SwizzleY = src.IndirectSwizzle; out[n].src.SwizzleZ = src.IndirectSwizzle; @@ -660,6 +783,15 @@ ureg_emit_src( struct ureg_program *ureg, n++; } + if (src.Dimension) { + out[0].src.Dimension = 1; + out[n].dim.Indirect = 0; + out[n].dim.Dimension = 0; + out[n].dim.Padding = 0; + out[n].dim.Index = src.DimensionIndex; + n++; + } + assert(n == size); } @@ -959,32 +1091,59 @@ ureg_label_insn(struct ureg_program *ureg, } - -static void emit_decl( struct ureg_program *ureg, - unsigned file, - unsigned index, - unsigned semantic_name, - unsigned semantic_index, - unsigned interp ) +static void +emit_decl_semantic(struct ureg_program *ureg, + unsigned file, + unsigned index, + unsigned semantic_name, + unsigned semantic_index) { - union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 ); + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); out[0].value = 0; out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; out[0].decl.NrTokens = 3; out[0].decl.File = file; out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */ - out[0].decl.Interpolate = interp; out[0].decl.Semantic = 1; out[1].value = 0; - out[1].decl_range.First = - out[1].decl_range.Last = index; + out[1].decl_range.First = index; + out[1].decl_range.Last = index; out[2].value = 0; out[2].decl_semantic.Name = semantic_name; out[2].decl_semantic.Index = semantic_index; +} + + +static void +emit_decl_fs(struct ureg_program *ureg, + unsigned file, + unsigned index, + unsigned semantic_name, + unsigned semantic_index, + unsigned interpolate, + unsigned cylindrical_wrap) +{ + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 3; + out[0].decl.File = file; + out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */ + out[0].decl.Interpolate = interpolate; + out[0].decl.Semantic = 1; + out[0].decl.CylindricalWrap = cylindrical_wrap; + + out[1].value = 0; + out[1].decl_range.First = index; + out[1].decl_range.Last = index; + out[2].value = 0; + out[2].decl_semantic.Name = semantic_name; + out[2].decl_semantic.Index = semantic_index; } @@ -1009,6 +1168,31 @@ static void emit_decl_range( struct ureg_program *ureg, } static void +emit_decl_range2D(struct ureg_program *ureg, + unsigned file, + unsigned first, + unsigned last, + unsigned index2D) +{ + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 3; + out[0].decl.File = file; + out[0].decl.UsageMask = 0xf; + out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; + out[0].decl.Dimension = 1; + + out[1].value = 0; + out[1].decl_range.First = first; + out[1].decl_range.Last = last; + + out[2].value = 0; + out[2].decl_dim.Index2D = index2D; +} + +static void emit_immediate( struct ureg_program *ureg, const unsigned *v, unsigned type ) @@ -1027,13 +1211,66 @@ emit_immediate( struct ureg_program *ureg, out[4].imm_data.Uint = v[3]; } +static void +emit_property(struct ureg_program *ureg, + unsigned name, + unsigned data) +{ + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); + out[0].value = 0; + out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY; + out[0].prop.NrTokens = 2; + out[0].prop.PropertyName = name; + + out[1].prop_data.Data = data; +} static void emit_decls( struct ureg_program *ureg ) { unsigned i; + if (ureg->property_gs_input_prim != ~0) { + assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY); + + emit_property(ureg, + TGSI_PROPERTY_GS_INPUT_PRIM, + ureg->property_gs_input_prim); + } + + if (ureg->property_gs_output_prim != ~0) { + assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY); + + emit_property(ureg, + TGSI_PROPERTY_GS_OUTPUT_PRIM, + ureg->property_gs_output_prim); + } + + if (ureg->property_gs_max_vertices != ~0) { + assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY); + + emit_property(ureg, + TGSI_PROPERTY_GS_MAX_VERTICES, + ureg->property_gs_max_vertices); + } + + if (ureg->property_fs_coord_origin) { + assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT); + + emit_property(ureg, + TGSI_PROPERTY_FS_COORD_ORIGIN, + ureg->property_fs_coord_origin); + } + + if (ureg->property_fs_coord_pixel_center) { + assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT); + + emit_property(ureg, + TGSI_PROPERTY_FS_COORD_PIXEL_CENTER, + ureg->property_fs_coord_pixel_center); + } + if (ureg->processor == TGSI_PROCESSOR_VERTEX) { for (i = 0; i < UREG_MAX_INPUT; i++) { if (ureg->vs_inputs[i/32] & (1 << (i%32))) { @@ -1042,29 +1279,38 @@ static void emit_decls( struct ureg_program *ureg ) } } else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) { for (i = 0; i < ureg->nr_fs_inputs; i++) { - emit_decl( ureg, - TGSI_FILE_INPUT, - i, - ureg->fs_input[i].semantic_name, - ureg->fs_input[i].semantic_index, - ureg->fs_input[i].interp ); + emit_decl_fs(ureg, + TGSI_FILE_INPUT, + i, + ureg->fs_input[i].semantic_name, + ureg->fs_input[i].semantic_index, + ureg->fs_input[i].interp, + ureg->fs_input[i].cylindrical_wrap); } } else { for (i = 0; i < ureg->nr_gs_inputs; i++) { - emit_decl_range(ureg, - TGSI_FILE_INPUT, - ureg->gs_input[i].index, - 1); + emit_decl_semantic(ureg, + TGSI_FILE_INPUT, + ureg->gs_input[i].index, + ureg->gs_input[i].semantic_name, + ureg->gs_input[i].semantic_index); } } + for (i = 0; i < ureg->nr_system_values; i++) { + emit_decl_semantic(ureg, + TGSI_FILE_SYSTEM_VALUE, + ureg->system_value[i].index, + ureg->system_value[i].semantic_name, + ureg->system_value[i].semantic_index); + } + for (i = 0; i < ureg->nr_outputs; i++) { - emit_decl( ureg, - TGSI_FILE_OUTPUT, - i, - ureg->output[i].semantic_name, - ureg->output[i].semantic_index, - TGSI_INTERPOLATE_CONSTANT ); + emit_decl_semantic(ureg, + TGSI_FILE_OUTPUT, + i, + ureg->output[i].semantic_name, + ureg->output[i].semantic_index); } for (i = 0; i < ureg->nr_samplers; i++) { @@ -1073,13 +1319,29 @@ static void emit_decls( struct ureg_program *ureg ) ureg->sampler[i].Index, 1 ); } - if (ureg->nr_constant_ranges) { - for (i = 0; i < ureg->nr_constant_ranges; i++) - emit_decl_range( ureg, - TGSI_FILE_CONSTANT, - ureg->constant_range[i].first, - (ureg->constant_range[i].last + 1 - - ureg->constant_range[i].first) ); + if (ureg->const_decls.nr_constant_ranges) { + for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) { + emit_decl_range(ureg, + TGSI_FILE_CONSTANT, + ureg->const_decls.constant_range[i].first, + ureg->const_decls.constant_range[i].last - ureg->const_decls.constant_range[i].first + 1); + } + } + + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + struct const_decl *decl = &ureg->const_decls2D[i]; + + if (decl->nr_constant_ranges) { + uint j; + + for (j = 0; j < decl->nr_constant_ranges; j++) { + emit_decl_range2D(ureg, + TGSI_FILE_CONSTANT, + decl->constant_range[j].first, + decl->constant_range[j].last, + i); + } + } } if (ureg->nr_temps) { @@ -1234,6 +1496,9 @@ struct ureg_program *ureg_create( unsigned processor ) return NULL; ureg->processor = processor; + ureg->property_gs_input_prim = ~0; + ureg->property_gs_output_prim = ~0; + ureg->property_gs_max_vertices = ~0; return ureg; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index 6f11273320..0130a77aad 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_shader_tokens.h" +#include "util/u_debug.h" #ifdef __cplusplus extern "C" { @@ -47,13 +48,15 @@ struct ureg_src unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */ unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */ unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */ - unsigned Pad : 1; /* BOOL */ unsigned Indirect : 1; /* BOOL */ + unsigned Dimension : 1; /* BOOL */ unsigned Absolute : 1; /* BOOL */ - int Index : 16; /* SINT */ unsigned Negate : 1; /* BOOL */ + int Index : 16; /* SINT */ + unsigned IndirectFile : 4; /* TGSI_FILE_ */ int IndirectIndex : 16; /* SINT */ - int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ + unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ + int DimensionIndex : 16; /* SINT */ }; /* Very similar to a tgsi_dst_register, removing unsupported fields @@ -118,16 +121,53 @@ ureg_create_shader_and_destroy( struct ureg_program *p, } +/*********************************************************************** + * Build shader properties: + */ + +void +ureg_property_gs_input_prim(struct ureg_program *ureg, + unsigned input_prim); + +void +ureg_property_gs_output_prim(struct ureg_program *ureg, + unsigned output_prim); + +void +ureg_property_gs_max_vertices(struct ureg_program *ureg, + unsigned max_vertices); + +void +ureg_property_fs_coord_origin(struct ureg_program *ureg, + unsigned fs_coord_origin); + +void +ureg_property_fs_coord_pixel_center(struct ureg_program *ureg, + unsigned fs_coord_pixel_center); /*********************************************************************** * Build shader declarations: */ struct ureg_src -ureg_DECL_fs_input( struct ureg_program *, - unsigned semantic_name, - unsigned semantic_index, - unsigned interp_mode ); +ureg_DECL_fs_input_cyl(struct ureg_program *, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp_mode, + unsigned cylindrical_wrap); + +static INLINE struct ureg_src +ureg_DECL_fs_input(struct ureg_program *ureg, + unsigned semantic_name, + unsigned semantic_index, + unsigned interp_mode) +{ + return ureg_DECL_fs_input_cyl(ureg, + semantic_name, + semantic_index, + interp_mode, + 0); +} struct ureg_src ureg_DECL_vs_input( struct ureg_program *, @@ -135,7 +175,15 @@ ureg_DECL_vs_input( struct ureg_program *, struct ureg_src ureg_DECL_gs_input(struct ureg_program *, - unsigned index); + unsigned index, + unsigned semantic_name, + unsigned semantic_index); + +struct ureg_src +ureg_DECL_system_value(struct ureg_program *, + unsigned index, + unsigned semantic_name, + unsigned semantic_index); struct ureg_dst ureg_DECL_output( struct ureg_program *, @@ -153,10 +201,21 @@ ureg_DECL_immediate_uint( struct ureg_program *, unsigned nr ); struct ureg_src +ureg_DECL_immediate_block_uint( struct ureg_program *, + const unsigned *v, + unsigned nr ); + +struct ureg_src ureg_DECL_immediate_int( struct ureg_program *, const int *v, unsigned nr ); +void +ureg_DECL_constant2D(struct ureg_program *ureg, + unsigned first, + unsigned last, + unsigned index2D); + struct ureg_src ureg_DECL_constant( struct ureg_program *, unsigned index ); @@ -753,18 +812,30 @@ static INLINE struct ureg_src ureg_src_indirect( struct ureg_src reg, struct ureg_src addr ) { assert(reg.File != TGSI_FILE_NULL); - assert(addr.File == TGSI_FILE_ADDRESS); + assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY); reg.Indirect = 1; + reg.IndirectFile = addr.File; reg.IndirectIndex = addr.Index; reg.IndirectSwizzle = addr.SwizzleX; return reg; } +static INLINE struct ureg_src +ureg_src_dimension( struct ureg_src reg, int index ) +{ + assert(reg.File != TGSI_FILE_NULL); + reg.Dimension = 1; + reg.DimensionIndex = index; + return reg; +} + static INLINE struct ureg_dst ureg_dst( struct ureg_src src ) { struct ureg_dst dst; + assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS); + dst.File = src.File; dst.WriteMask = TGSI_WRITEMASK_XYZW; dst.Indirect = src.Indirect; @@ -783,6 +854,30 @@ ureg_dst( struct ureg_src src ) } static INLINE struct ureg_src +ureg_src_register(unsigned file, + unsigned index) +{ + struct ureg_src src; + + src.File = file; + src.SwizzleX = TGSI_SWIZZLE_X; + src.SwizzleY = TGSI_SWIZZLE_Y; + src.SwizzleZ = TGSI_SWIZZLE_Z; + src.SwizzleW = TGSI_SWIZZLE_W; + src.Indirect = 0; + src.IndirectFile = TGSI_FILE_NULL; + src.IndirectIndex = 0; + src.IndirectSwizzle = 0; + src.Absolute = 0; + src.Index = index; + src.Negate = 0; + src.Dimension = 0; + src.DimensionIndex = 0; + + return src; +} + +static INLINE struct ureg_src ureg_src( struct ureg_dst dst ) { struct ureg_src src; @@ -792,13 +887,15 @@ ureg_src( struct ureg_dst dst ) src.SwizzleY = TGSI_SWIZZLE_Y; src.SwizzleZ = TGSI_SWIZZLE_Z; src.SwizzleW = TGSI_SWIZZLE_W; - src.Pad = 0; src.Indirect = dst.Indirect; + src.IndirectFile = TGSI_FILE_ADDRESS; src.IndirectIndex = dst.IndirectIndex; src.IndirectSwizzle = dst.IndirectSwizzle; src.Absolute = 0; src.Index = dst.Index; src.Negate = 0; + src.Dimension = 0; + src.DimensionIndex = 0; return src; } @@ -837,13 +934,15 @@ ureg_src_undef( void ) src.SwizzleY = 0; src.SwizzleZ = 0; src.SwizzleW = 0; - src.Pad = 0; src.Indirect = 0; + src.IndirectFile = TGSI_FILE_NULL; src.IndirectIndex = 0; src.IndirectSwizzle = 0; src.Absolute = 0; src.Index = 0; src.Negate = 0; + src.Dimension = 0; + src.DimensionIndex = 0; return src; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c index f4ca9e21ed..0a7e4105a8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/tgsi_util.c @@ -28,7 +28,6 @@ #include "util/u_debug.h" #include "pipe/p_shader_tokens.h" #include "tgsi_parse.h" -#include "tgsi_build.h" #include "tgsi_util.h" union pointer_hack diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index 34526eb061..54ed2c1a4b 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -44,12 +44,19 @@ #include "pipe/p_format.h" #include "pipe/p_state.h" +enum translate_element_type { + TRANSLATE_ELEMENT_NORMAL, + TRANSLATE_ELEMENT_INSTANCE_ID +}; + struct translate_element { + enum translate_element_type type; enum pipe_format input_format; enum pipe_format output_format; unsigned input_buffer:8; unsigned input_offset:24; + unsigned instance_divisor; unsigned output_offset; }; @@ -74,11 +81,13 @@ struct translate { void (PIPE_CDECL *run_elts)( struct translate *, const unsigned *elts, unsigned count, + unsigned instance_id, void *output_buffer); void (PIPE_CDECL *run)( struct translate *, unsigned start, unsigned count, + unsigned instance_id, void *output_buffer); }; @@ -103,8 +112,13 @@ static INLINE int translate_keysize( const struct translate_key *key ) static INLINE int translate_key_compare( const struct translate_key *a, const struct translate_key *b ) { - int keysize = translate_keysize(a); - return memcmp(a, b, keysize); + int keysize_a = translate_keysize(a); + int keysize_b = translate_keysize(b); + + if (keysize_a != keysize_b) { + return keysize_a - keysize_b; + } + return memcmp(a, b, keysize_a); } diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 266e7ee81e..24727d4988 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -46,9 +46,12 @@ struct translate_generic { struct translate translate; struct { + enum translate_element_type type; + fetch_func fetch; unsigned buffer; unsigned input_offset; + unsigned instance_divisor; emit_func emit; unsigned output_offset; @@ -568,6 +571,7 @@ static emit_func get_emit_func( enum pipe_format format ) static void PIPE_CDECL generic_run_elts( struct translate *translate, const unsigned *elts, unsigned count, + unsigned instance_id, void *output_buffer ) { struct translate_generic *tg = translate_generic(translate); @@ -583,13 +587,20 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - - const char *src = (tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt); + const char *src; char *dst = (vert + tg->attrib[attr].output_offset); + if (tg->attrib[attr].instance_divisor) { + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * + (instance_id / tg->attrib[attr].instance_divisor); + } else { + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt; + } + tg->attrib[attr].fetch( src, data ); if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", @@ -607,6 +618,7 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, static void PIPE_CDECL generic_run( struct translate *translate, unsigned start, unsigned count, + unsigned instance_id, void *output_buffer ) { struct translate_generic *tg = translate_generic(translate); @@ -623,13 +635,25 @@ static void PIPE_CDECL generic_run( struct translate *translate, for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - const char *src = (tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt); - char *dst = (vert + tg->attrib[attr].output_offset); - tg->attrib[attr].fetch( src, data ); + if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { + const char *src; + + if (tg->attrib[attr].instance_divisor) { + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * + (instance_id / tg->attrib[attr].instance_divisor); + } else { + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt; + } + + tg->attrib[attr].fetch( src, data ); + } else { + data[0] = (float)instance_id; + } if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", i, attr, data[0], data[1], data[2], data[3]); @@ -683,10 +707,12 @@ struct translate *translate_generic_create( const struct translate_key *key ) tg->translate.run = generic_run; for (i = 0; i < key->nr_elements; i++) { + tg->attrib[i].type = key->element[i].type; tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format); tg->attrib[i].buffer = key->element[i].input_buffer; tg->attrib[i].input_offset = key->element[i].input_offset; + tg->attrib[i].instance_divisor = key->element[i].instance_divisor; tg->attrib[i].emit = get_emit_func(key->element[i].output_format); tg->attrib[i].output_offset = key->element[i].output_offset; diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index b62db8d8f3..c13e742738 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -49,19 +49,29 @@ typedef void (PIPE_CDECL *run_func)( struct translate *translate, unsigned start, unsigned count, - void *output_buffer ); + unsigned instance_id, + void *output_buffer); typedef void (PIPE_CDECL *run_elts_func)( struct translate *translate, const unsigned *elts, unsigned count, - void *output_buffer ); + unsigned instance_id, + void *output_buffer); struct translate_buffer { const void *base_ptr; unsigned stride; - void *ptr; /* updated per vertex */ }; +struct translate_buffer_varient { + unsigned buffer_index; + unsigned instance_divisor; + void *ptr; /* updated either per vertex or per instance */ +}; + + +#define ELEMENT_BUFFER_INSTANCE_ID 1001 + struct translate_sse { struct translate translate; @@ -81,6 +91,16 @@ struct translate_sse { struct translate_buffer buffer[PIPE_MAX_ATTRIBS]; unsigned nr_buffers; + /* Multiple buffer varients can map to a single buffer. */ + struct translate_buffer_varient buffer_varient[PIPE_MAX_ATTRIBS]; + unsigned nr_buffer_varients; + + /* Multiple elements can map to a single buffer varient. */ + unsigned element_to_buffer_varient[PIPE_MAX_ATTRIBS]; + + boolean use_instancing; + unsigned instance_id; + run_func gen_run; run_elts_func gen_run_elts; @@ -359,32 +379,61 @@ static boolean init_inputs( struct translate_sse *p, boolean linear ) { unsigned i; - if (linear) { - for (i = 0; i < p->nr_buffers; i++) { + struct x86_reg instance_id = x86_make_disp(p->machine_EDX, + get_offset(p, &p->instance_id)); + + for (i = 0; i < p->nr_buffer_varients; i++) { + struct translate_buffer_varient *varient = &p->buffer_varient[i]; + struct translate_buffer *buffer = &p->buffer[varient->buffer_index]; + + if (linear || varient->instance_divisor) { struct x86_reg buf_stride = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[i].stride)); + get_offset(p, &buffer->stride)); struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[i].ptr)); + get_offset(p, &varient->ptr)); struct x86_reg buf_base_ptr = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[i].base_ptr)); + get_offset(p, &buffer->base_ptr)); struct x86_reg elt = p->idx_EBX; - struct x86_reg tmp = p->tmp_EAX; - + struct x86_reg tmp_EAX = p->tmp_EAX; /* Calculate pointer to first attrib: + * base_ptr + stride * index, where index depends on instance divisor */ - x86_mov(p->func, tmp, buf_stride); - x86_imul(p->func, tmp, elt); - x86_add(p->func, tmp, buf_base_ptr); + if (varient->instance_divisor) { + /* Our index is instance ID divided by instance divisor. + */ + x86_mov(p->func, tmp_EAX, instance_id); + + if (varient->instance_divisor != 1) { + struct x86_reg tmp_EDX = p->machine_EDX; + struct x86_reg tmp_ECX = p->outbuf_ECX; + + /* TODO: Add x86_shr() to rtasm and use it whenever + * instance divisor is power of two. + */ + + x86_push(p->func, tmp_EDX); + x86_push(p->func, tmp_ECX); + x86_xor(p->func, tmp_EDX, tmp_EDX); + x86_mov_reg_imm(p->func, tmp_ECX, varient->instance_divisor); + x86_div(p->func, tmp_ECX); /* EAX = EDX:EAX / ECX */ + x86_pop(p->func, tmp_ECX); + x86_pop(p->func, tmp_EDX); + } + } else { + x86_mov(p->func, tmp_EAX, elt); + } + x86_imul(p->func, tmp_EAX, buf_stride); + x86_add(p->func, tmp_EAX, buf_base_ptr); /* In the linear case, keep the buffer pointer instead of the * index number. */ - if (p->nr_buffers == 1) - x86_mov( p->func, elt, tmp ); + if (linear && p->nr_buffer_varients == 1) + x86_mov(p->func, elt, tmp_EAX); else - x86_mov( p->func, buf_ptr, tmp ); + x86_mov(p->func, buf_ptr, tmp_EAX); } } @@ -394,31 +443,36 @@ static boolean init_inputs( struct translate_sse *p, static struct x86_reg get_buffer_ptr( struct translate_sse *p, boolean linear, - unsigned buf_idx, + unsigned var_idx, struct x86_reg elt ) { - if (linear && p->nr_buffers == 1) { + if (var_idx == ELEMENT_BUFFER_INSTANCE_ID) { + return x86_make_disp(p->machine_EDX, + get_offset(p, &p->instance_id)); + } + if (linear && p->nr_buffer_varients == 1) { return p->idx_EBX; } - else if (linear) { + else if (linear || p->buffer_varient[var_idx].instance_divisor) { struct x86_reg ptr = p->tmp_EAX; struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[buf_idx].ptr)); + get_offset(p, &p->buffer_varient[var_idx].ptr)); x86_mov(p->func, ptr, buf_ptr); return ptr; } else { struct x86_reg ptr = p->tmp_EAX; + const struct translate_buffer_varient *varient = &p->buffer_varient[var_idx]; struct x86_reg buf_stride = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[buf_idx].stride)); + get_offset(p, &p->buffer[varient->buffer_index].stride)); struct x86_reg buf_base_ptr = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[buf_idx].base_ptr)); + get_offset(p, &p->buffer[varient->buffer_index].base_ptr)); @@ -436,28 +490,33 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p, static boolean incr_inputs( struct translate_sse *p, boolean linear ) { - if (linear && p->nr_buffers == 1) { + if (linear && p->nr_buffer_varients == 1) { struct x86_reg stride = x86_make_disp(p->machine_EDX, get_offset(p, &p->buffer[0].stride)); - x86_add(p->func, p->idx_EBX, stride); - sse_prefetchnta(p->func, x86_make_disp(p->idx_EBX, 192)); + if (p->buffer_varient[0].instance_divisor == 0) { + x86_add(p->func, p->idx_EBX, stride); + sse_prefetchnta(p->func, x86_make_disp(p->idx_EBX, 192)); + } } else if (linear) { unsigned i; /* Is this worthwhile?? */ - for (i = 0; i < p->nr_buffers; i++) { + for (i = 0; i < p->nr_buffer_varients; i++) { + struct translate_buffer_varient *varient = &p->buffer_varient[i]; struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[i].ptr)); + get_offset(p, &varient->ptr)); struct x86_reg buf_stride = x86_make_disp(p->machine_EDX, - get_offset(p, &p->buffer[i].stride)); + get_offset(p, &p->buffer[varient->buffer_index].stride)); - x86_mov(p->func, p->tmp_EAX, buf_ptr); - x86_add(p->func, p->tmp_EAX, buf_stride); - if (i == 0) sse_prefetchnta(p->func, x86_make_disp(p->tmp_EAX, 192)); - x86_mov(p->func, buf_ptr, p->tmp_EAX); + if (varient->instance_divisor == 0) { + x86_mov(p->func, p->tmp_EAX, buf_ptr); + x86_add(p->func, p->tmp_EAX, buf_stride); + if (i == 0) sse_prefetchnta(p->func, x86_make_disp(p->tmp_EAX, 192)); + x86_mov(p->func, buf_ptr, p->tmp_EAX); + } } } else { @@ -514,7 +573,18 @@ static boolean build_vertex_emit( struct translate_sse *p, x86_mov(p->func, p->machine_EDX, x86_fn_arg(p->func, 1)); x86_mov(p->func, p->idx_EBX, x86_fn_arg(p->func, 2)); x86_mov(p->func, p->count_ESI, x86_fn_arg(p->func, 3)); - x86_mov(p->func, p->outbuf_ECX, x86_fn_arg(p->func, 4)); + x86_mov(p->func, p->outbuf_ECX, x86_fn_arg(p->func, 5)); + + /* Load instance ID. + */ + if (p->use_instancing) { + x86_mov(p->func, + p->tmp_EAX, + x86_fn_arg(p->func, 4)); + x86_mov(p->func, + x86_make_disp(p->machine_EDX, get_offset(p, &p->instance_id)), + p->tmp_EAX); + } /* Get vertex count, compare to zero */ @@ -531,17 +601,18 @@ static boolean build_vertex_emit( struct translate_sse *p, label = x86_get_label(p->func); { struct x86_reg elt = linear ? p->idx_EBX : x86_deref(p->idx_EBX); - int last_vb = -1; + int last_varient = -1; struct x86_reg vb; for (j = 0; j < p->translate.key.nr_elements; j++) { const struct translate_element *a = &p->translate.key.element[j]; + unsigned varient = p->element_to_buffer_varient[j]; /* Figure out source pointer address: */ - if (a->input_buffer != last_vb) { - last_vb = a->input_buffer; - vb = get_buffer_ptr(p, linear, a->input_buffer, elt); + if (varient != last_varient) { + last_varient = varient; + vb = get_buffer_ptr(p, linear, varient, elt); } if (!translate_attr( p, a, @@ -624,6 +695,7 @@ static void translate_sse_release( struct translate *translate ) static void PIPE_CDECL translate_sse_run_elts( struct translate *translate, const unsigned *elts, unsigned count, + unsigned instance_id, void *output_buffer ) { struct translate_sse *p = (struct translate_sse *)translate; @@ -631,12 +703,14 @@ static void PIPE_CDECL translate_sse_run_elts( struct translate *translate, p->gen_run_elts( translate, elts, count, - output_buffer ); + instance_id, + output_buffer); } static void PIPE_CDECL translate_sse_run( struct translate *translate, unsigned start, unsigned count, + unsigned instance_id, void *output_buffer ) { struct translate_sse *p = (struct translate_sse *)translate; @@ -644,7 +718,8 @@ static void PIPE_CDECL translate_sse_run( struct translate *translate, p->gen_run( translate, start, count, - output_buffer ); + instance_id, + output_buffer); } @@ -666,8 +741,37 @@ struct translate *translate_sse2_create( const struct translate_key *key ) p->translate.run_elts = translate_sse_run_elts; p->translate.run = translate_sse_run; - for (i = 0; i < key->nr_elements; i++) - p->nr_buffers = MAX2( p->nr_buffers, key->element[i].input_buffer + 1 ); + for (i = 0; i < key->nr_elements; i++) { + if (key->element[i].type == TRANSLATE_ELEMENT_NORMAL) { + unsigned j; + + p->nr_buffers = MAX2(p->nr_buffers, key->element[i].input_buffer + 1); + + if (key->element[i].instance_divisor) { + p->use_instancing = TRUE; + } + + /* + * Map vertex element to vertex buffer varient. + */ + for (j = 0; j < p->nr_buffer_varients; j++) { + if (p->buffer_varient[j].buffer_index == key->element[i].input_buffer && + p->buffer_varient[j].instance_divisor == key->element[i].instance_divisor) { + break; + } + } + if (j == p->nr_buffer_varients) { + p->buffer_varient[j].buffer_index = key->element[i].input_buffer; + p->buffer_varient[j].instance_divisor = key->element[i].instance_divisor; + p->nr_buffer_varients++; + } + p->element_to_buffer_varient[i] = j; + } else { + assert(key->element[i].type == TRANSLATE_ELEMENT_INSTANCE_ID); + + p->element_to_buffer_varient[i] = ELEMENT_BUFFER_INSTANCE_ID; + } + } if (0) debug_printf("nr_buffers: %d\n", p->nr_buffers); diff --git a/src/gallium/auxiliary/util/u_atomic.h b/src/gallium/auxiliary/util/u_atomic.h new file mode 100644 index 0000000000..3c42477ad4 --- /dev/null +++ b/src/gallium/auxiliary/util/u_atomic.h @@ -0,0 +1,305 @@ +/** + * Many similar implementations exist. See for example libwsbm + * or the linux kernel include/atomic.h + * + * No copyright claimed on this file. + * + */ + +#ifndef U_ATOMIC_H +#define U_ATOMIC_H + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" + +/* Favor OS-provided implementations. + * + * Where no OS-provided implementation is available, fall back to + * locally coded assembly, compiler intrinsic or ultimately a + * mutex-based implementation. + */ +#if (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \ + defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)) +#define PIPE_ATOMIC_OS_UNLOCKED +#elif defined(PIPE_OS_SOLARIS) +#define PIPE_ATOMIC_OS_SOLARIS +#elif defined(PIPE_CC_MSVC) +#define PIPE_ATOMIC_MSVC_INTRINSIC +#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_MSVC_X86 +#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_GCC_X86 +#elif defined(PIPE_CC_GCC) +#define PIPE_ATOMIC_GCC_INTRINSIC +#else +#error "Unsupported platform" +#endif + + + +#if defined(PIPE_ATOMIC_ASM_GCC_X86) + +#define PIPE_ATOMIC "GCC x86 assembly" + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) + ::"memory"); + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm__ __volatile__("lock; incl %0":"+m"(*v)); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm__ __volatile__("lock; decl %0":"+m"(*v)); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} + +#ifdef __cplusplus +} +#endif + +#endif + + + +/* Implementation using GCC-provided synchronization intrinsics + */ +#if defined(PIPE_ATOMIC_GCC_INTRINSIC) + +#define PIPE_ATOMIC "GCC Sync Intrinsics" + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return (__sync_sub_and_fetch(v, 1) == 0); +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + (void) __sync_add_and_fetch(v, 1); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + (void) __sync_sub_and_fetch(v, 1); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} + +#ifdef __cplusplus +} +#endif + +#endif + + + +/* Unlocked version for single threaded environments, such as some + * windows kernel modules. + */ +#if defined(PIPE_ATOMIC_OS_UNLOCKED) + +#define PIPE_ATOMIC "Unlocked" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) +#define p_atomic_dec_zero(_v) ((boolean) --(*(_v))) +#define p_atomic_inc(_v) ((void) (*(_v))++) +#define p_atomic_dec(_v) ((void) (*(_v))--) +#define p_atomic_cmpxchg(_v, old, _new) (*(_v) == old ? *(_v) = (_new) : *(_v)) + +#endif + + +/* Locally coded assembly for MSVC on x86: + */ +#if defined(PIPE_ATOMIC_ASM_MSVC_X86) + +#define PIPE_ATOMIC "MSVC x86 assembly" + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm { + mov eax, [v] + lock dec dword ptr [eax] + sete byte ptr [c] + } + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm { + mov eax, [v] + lock inc dword ptr [eax] + } +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm { + mov eax, [v] + lock dec dword ptr [eax] + } +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + int32_t orig; + + __asm { + mov ecx, [v] + mov eax, [old] + mov edx, [_new] + lock cmpxchg [ecx], edx + mov [orig], eax + } + + return orig; +} + +#ifdef __cplusplus +} +#endif + +#endif + + +#if defined(PIPE_ATOMIC_MSVC_INTRINSIC) + +#define PIPE_ATOMIC "MSVC Intrinsics" + +#include <intrin.h> + +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedCompareExchange) + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return _InterlockedDecrement((long *)v) == 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + _InterlockedIncrement((long *)v); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + _InterlockedDecrement((long *)v); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return _InterlockedCompareExchange((long *)v, _new, old); +} + +#ifdef __cplusplus +} +#endif + +#endif + +#if defined(PIPE_ATOMIC_OS_SOLARIS) + +#define PIPE_ATOMIC "Solaris OS atomic functions" + +#include <atomic.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + uint32_t n = atomic_dec_32_nv((uint32_t *) v); + + return n != 0; +} + +#define p_atomic_inc(_v) atomic_inc_32((uint32_t *) _v) +#define p_atomic_dec(_v) atomic_dec_32((uint32_t *) _v) + +#define p_atomic_cmpxchg(_v, _old, _new) \ + atomic_cas_32( (uint32_t *) _v, (uint32_t) _old, (uint32_t) _new) + +#ifdef __cplusplus +} +#endif + +#endif + + +#ifndef PIPE_ATOMIC +#error "No pipe_atomic implementation selected" +#endif + + + +#endif /* U_ATOMIC_H */ diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 3f74e2aa8b..f0bc58a558 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "util/u_debug.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" @@ -92,7 +92,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) /* disabled blending/masking */ memset(&ctx->blend, 0, sizeof(ctx->blend)); - ctx->blend.colormask = PIPE_MASK_RGBA; + ctx->blend.rt[0].colormask = PIPE_MASK_RGBA; /* no-op depth/stencil/alpha */ memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); @@ -226,8 +226,8 @@ setup_vertex_data_tex(struct blit_state *ctx, offset = get_next_slot( ctx ); - pipe_buffer_write(ctx->pipe->screen, ctx->vbuf, - offset, sizeof(ctx->vertices), ctx->vertices); + pipe_buffer_write_nooverlap(ctx->pipe->screen, ctx->vbuf, + offset, sizeof(ctx->vertices), ctx->vertices); return offset; } @@ -262,6 +262,10 @@ regions_overlap(int srcX0, int srcY0, * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. * Flipping and stretching are supported. + * \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR + * \param writemask controls which channels in the dest surface are sourced + * from the src surface. Disabled channels are sourced + * from (0,0,0,1). * XXX what about clipping??? * XXX need some control over blitting Z and/or stencil. */ diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 46b4706b76..f3b4491d17 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -34,7 +34,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" @@ -125,7 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) memset(&blend, 0, sizeof(blend)); ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend); - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].colormask = PIPE_MASK_RGBA; ctx->blend_write_color = pipe->create_blend_state(pipe, &blend); /* depth stencil alpha state objects */ @@ -379,9 +379,16 @@ static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx, float t1 = y1 / (float)surf->height; float s2 = x2 / (float)surf->width; float t2 = y2 / (float)surf->height; - const float st[4][2] = { - {s1, t1}, {s2, t1}, {s2, t2}, {s1, t2} - }; + float st[4][2]; + + st[0][0] = s1; + st[0][1] = t1; + st[1][0] = s2; + st[1][1] = t1; + st[2][0] = s2; + st[2][1] = t2; + st[3][0] = s1; + st[3][1] = t2; util_map_texcoords2d_onto_cubemap(surf->face, /* pointer, stride in floats */ diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 9b4e6ca2a7..4821b8a143 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -29,125 +29,30 @@ #include "pipe/p_config.h" -#include <stdarg.h> - - -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY - -#include <windows.h> -#include <winddi.h> - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) - -#include <stdio.h> -#include <stdlib.h> -#include <windows.h> -#include <types.h> - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -#endif -#include <windows.h> -#include <stdio.h> - -#else - -#include <stdio.h> -#include <stdlib.h> - -#endif - -#include "pipe/p_compiler.h" +#include "pipe/p_compiler.h" +#include "os/os_stream.h" #include "util/u_debug.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_string.h" -#include "util/u_stream.h" #include "util/u_math.h" #include "util/u_tile.h" #include "util/u_prim.h" -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY -static INLINE void -_EngDebugPrint(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - EngDebugPrint("", (PCHAR)format, ap); - va_end(ap); -} -#endif - - void _debug_vprintf(const char *format, va_list ap) { -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - /* EngDebugPrint does not handle float point arguments, so we need to use - * our own vsnprintf implementation. It is also very slow, so buffer until - * we find a newline. */ - static char buf[512] = {'\0'}; - size_t len = strlen(buf); - int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); - if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { - _EngDebugPrint("%s", buf); - buf[0] = '\0'; - } -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) - /* OutputDebugStringA can be very slow, so buffer until we find a newline. */ + /* We buffer until we find a newline. */ static char buf[4096] = {'\0'}; size_t len = strlen(buf); int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { - OutputDebugStringA(buf); + os_log_message(buf); buf[0] = '\0'; } - - if(GetConsoleWindow() && !IsDebuggerPresent()) { - fflush(stdout); - vfprintf(stderr, format, ap); - fflush(stderr); - } - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) - wchar_t *wide_format; - long wide_str_len; - char buf[512]; - int ret; -#if (_WIN32_WCE < 600) - ret = vsprintf(buf, format, ap); - if(ret < 0){ - sprintf(buf, "Cant handle debug print!"); - ret = 25; - } -#else - ret = vsprintf_s(buf, 512, format, ap); - if(ret < 0){ - sprintf_s(buf, 512, "Cant handle debug print!"); - ret = 25; - } -#endif - buf[ret] = '\0'; - /* Format is ascii - needs to be converted to wchar_t for printing */ - wide_str_len = MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1, NULL, 0); - wide_format = (wchar_t *) malloc((wide_str_len+1) * sizeof(wchar_t)); - if (wide_format) { - MultiByteToWideChar(CP_ACP, 0, (const char *) buf, -1, - wide_format, wide_str_len); - NKDbgPrintfW(wide_format, wide_format); - free(wide_format); - } -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* TODO */ -#else /* !PIPE_SUBSYSTEM_WINDOWS */ - fflush(stdout); - vfprintf(stderr, format, ap); -#endif } @@ -169,108 +74,12 @@ void debug_print_blob( const char *name, #endif -#ifndef debug_break -void debug_break(void) -{ -#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) - DebugBreak(); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - EngDebugBreak(); -#else - abort(); -#endif -} -#endif - - -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY -static const char * -find(const char *start, const char *end, char c) -{ - const char *p; - for(p = start; !end || p != end; ++p) { - if(*p == c) - return p; - if(*p < 32) - break; - } - return NULL; -} - -static int -compare(const char *start, const char *end, const char *s) -{ - const char *p, *q; - for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { - if(*p != *q) - return 0; - } - return p == end && *q == '\0'; -} - -static void -copy(char *dst, const char *start, const char *end, size_t n) -{ - const char *p; - char *q; - for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) - *q = *p; - *q = '\0'; -} -#endif - - -static INLINE const char * -_debug_get_option(const char *name) -{ -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - /* EngMapFile creates the file if it does not exists, so it must either be - * disabled on release versions (or put in a less conspicuous place). */ -#ifdef DEBUG - const char *result = NULL; - ULONG_PTR iFile = 0; - const void *pMap = NULL; - const char *sol, *eol, *sep; - static char output[1024]; - - pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); - if(pMap) { - sol = (const char *)pMap; - while(1) { - /* TODO: handle LF line endings */ - eol = find(sol, NULL, '\r'); - if(!eol || eol == sol) - break; - sep = find(sol, eol, '='); - if(!sep) - break; - if(compare(sol, sep, name)) { - copy(output, sep + 1, eol, sizeof(output)); - result = output; - break; - } - sol = eol + 2; - } - EngUnmapFile(iFile); - } - return result; -#else - return NULL; -#endif -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* TODO: implement */ - return NULL; -#else - return getenv(name); -#endif -} - const char * debug_get_option(const char *name, const char *dfault) { const char *result; - result = _debug_get_option(name); + result = os_get_option(name); if(!result) result = dfault; @@ -282,7 +91,7 @@ debug_get_option(const char *name, const char *dfault) boolean debug_get_bool_option(const char *name, boolean dfault) { - const char *str = _debug_get_option(name); + const char *str = os_get_option(name); boolean result; if(str == NULL) @@ -312,7 +121,7 @@ debug_get_num_option(const char *name, long dfault) long result; const char *str; - str = _debug_get_option(name); + str = os_get_option(name); if(!str) result = dfault; else { @@ -348,7 +157,7 @@ debug_get_flags_option(const char *name, unsigned long result; const char *str; - str = _debug_get_option(name); + str = os_get_option(name); if(!str) result = dfault; else if (!util_strcmp(str, "help")) { @@ -389,7 +198,7 @@ void _debug_assert_fail(const char *expr, #else if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) #endif - debug_break(); + os_abort(); else _debug_printf("continuing...\n"); } @@ -631,6 +440,14 @@ const char *u_prim_name( unsigned prim ) #ifdef DEBUG +/** + * Dump an image to a .raw or .ppm file (depends on OS). + * \param format PIPE_FORMAT_x + * \param cpp bytes per pixel + * \param width width in pixels + * \param height height in pixels + * \param stride row stride in bytes + */ void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, @@ -672,6 +489,52 @@ void debug_dump_image(const char *prefix, } EngUnmapFile(iFile); +#elif defined(PIPE_OS_UNIX) + /* write a ppm file */ + char filename[256]; + FILE *f; + + util_snprintf(filename, sizeof(filename), "%s.ppm", prefix); + + f = fopen(filename, "w"); + if (f) { + int i, x, y; + int r, g, b; + const uint8_t *ptr = (uint8_t *) data; + + /* XXX this is a hack */ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + r = 2; + g = 1; + b = 0; + break; + default: + r = 0; + g = 1; + b = 1; + } + + fprintf(f, "P6\n"); + fprintf(f, "# ppm-file created by osdemo.c\n"); + fprintf(f, "%i %i\n", width, height); + fprintf(f, "255\n"); + fclose(f); + + f = fopen(filename, "ab"); /* reopen in binary append mode */ + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + i = y * stride + x * cpp; + fputc(ptr[i + r], f); /* write red */ + fputc(ptr[i + g], f); /* write green */ + fputc(ptr[i + b], f); /* write blue */ + } + } + fclose(f); + } + else { + fprintf(stderr, "Can't open %s for writing\n", filename); + } #endif } @@ -712,6 +575,27 @@ error: } +void debug_dump_texture(const char *prefix, + struct pipe_texture *texture) +{ + struct pipe_surface *surface; + struct pipe_screen *screen; + + if (!texture) + return; + + screen = texture->screen; + + /* XXX for now, just dump image for face=0, level=0 */ + surface = screen->get_tex_surface(screen, texture, 0, 0, 0, + PIPE_TEXTURE_USAGE_SAMPLER); + if (surface) { + debug_dump_surface(prefix, surface); + screen->tex_surface_destroy(surface); + } +} + + #pragma pack(push,2) struct bmp_file_header { uint16_t bfType; @@ -797,7 +681,7 @@ debug_dump_float_rgba_bmp(const char *filename, float *rgba, unsigned stride) { #ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT - struct util_stream *stream; + struct os_stream *stream; struct bmp_file_header bmfh; struct bmp_info_header bmih; unsigned x, y; @@ -823,12 +707,12 @@ debug_dump_float_rgba_bmp(const char *filename, bmih.biClrUsed = 0; bmih.biClrImportant = 0; - stream = util_stream_create(filename, bmfh.bfSize); + stream = os_stream_create(filename, bmfh.bfSize); if(!stream) goto error1; - util_stream_write(stream, &bmfh, 14); - util_stream_write(stream, &bmih, 40); + os_stream_write(stream, &bmfh, 14); + os_stream_write(stream, &bmih, 40); y = height; while(y--) { @@ -840,11 +724,11 @@ debug_dump_float_rgba_bmp(const char *filename, pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]); pixel.rgbBlue = float_to_ubyte(ptr[x*4 + 2]); pixel.rgbAlpha = 255; - util_stream_write(stream, &pixel, 4); + os_stream_write(stream, &pixel, 4); } } - util_stream_close(stream); + os_stream_close(stream); error1: ; #endif diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h index facc30a553..efcf065d27 100644 --- a/src/gallium/auxiliary/util/u_debug.h +++ b/src/gallium/auxiliary/util/u_debug.h @@ -39,9 +39,7 @@ #define U_DEBUG_H_ -#include <stdarg.h> - -#include "pipe/p_compiler.h" +#include "os/os_misc.h" #ifdef __cplusplus @@ -49,22 +47,6 @@ extern "C" { #endif -#if defined(DBG) || defined(DEBUG) -#ifndef DEBUG -#define DEBUG 1 -#endif -#else -#ifndef NDEBUG -#define NDEBUG 1 -#endif -#endif - - -/* MSVC bebore VC7 does not have the __FUNCTION__ macro */ -#if defined(_MSC_VER) && _MSC_VER < 1300 -#define __FUNCTION__ "???" -#endif - #if defined(__GNUC__) #define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list))) #else @@ -155,13 +137,7 @@ void debug_print_format(const char *msg, unsigned fmt ); * Hard-coded breakpoint. */ #ifdef DEBUG -#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) -#define debug_break() __asm("int3") -#elif defined(PIPE_CC_MSVC) -#define debug_break() __debugbreak() -#else -void debug_break(void); -#endif +#define debug_break() os_break() #else /* !DEBUG */ #define debug_break() ((void)0) #endif /* !DEBUG */ @@ -328,22 +304,6 @@ debug_get_flags_option(const char *name, unsigned long dfault); -void * -debug_malloc(const char *file, unsigned line, const char *function, - size_t size); - -void -debug_free(const char *file, unsigned line, const char *function, - void *ptr); - -void * -debug_calloc(const char *file, unsigned line, const char *function, - size_t count, size_t size ); - -void * -debug_realloc(const char *file, unsigned line, const char *function, - void *old_ptr, size_t old_size, size_t new_size ); - unsigned long debug_memory_begin(void); @@ -354,6 +314,8 @@ debug_memory_end(unsigned long beginning); #ifdef DEBUG struct pipe_surface; struct pipe_transfer; +struct pipe_texture; + void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, @@ -361,6 +323,8 @@ void debug_dump_image(const char *prefix, const void *data); void debug_dump_surface(const char *prefix, struct pipe_surface *surface); +void debug_dump_texture(const char *prefix, + struct pipe_texture *texture); void debug_dump_surface_bmp(const char *filename, struct pipe_surface *surface); void debug_dump_transfer_bmp(const char *filename, diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c index d6484f4ad5..f1baa62f89 100644 --- a/src/gallium/auxiliary/util/u_debug_memory.c +++ b/src/gallium/auxiliary/util/u_debug_memory.c @@ -34,15 +34,10 @@ #include "pipe/p_config.h" -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) -#include <windows.h> -#include <winddi.h> -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -#include <wdm.h> -#else -#include <stdio.h> -#include <stdlib.h> -#endif +#define DEBUG_MEMORY_IMPLEMENTATION + +#include "os/os_memory.h" +#include "os/os_memory_debug.h" #include "util/u_debug.h" #include "util/u_debug_stack.h" @@ -53,18 +48,6 @@ #define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) -#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') -#define real_free(_ptr) EngFreeMem(_ptr) -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -#define real_malloc(_size) ExAllocatePool(0, _size) -#define real_free(_ptr) ExFreePool(_ptr) -#else -#define real_malloc(_size) malloc(_size) -#define real_free(_ptr) free(_ptr) -#endif - - struct debug_memory_header { struct list_head head; @@ -127,7 +110,7 @@ debug_malloc(const char *file, unsigned line, const char *function, struct debug_memory_header *hdr; struct debug_memory_footer *ftr; - hdr = real_malloc(sizeof(*hdr) + size + sizeof(*ftr)); + hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr)); if(!hdr) { debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", file, line, function, @@ -185,7 +168,7 @@ debug_free(const char *file, unsigned line, const char *function, hdr->magic = 0; ftr->magic = 0; - real_free(hdr); + os_free(hdr); } void * @@ -232,7 +215,7 @@ debug_realloc(const char *file, unsigned line, const char *function, } /* alloc new */ - new_hdr = real_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); + new_hdr = os_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); if(!new_hdr) { debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", file, line, function, @@ -258,7 +241,7 @@ debug_realloc(const char *file, unsigned line, const char *function, /* free old */ old_hdr->magic = 0; old_ftr->magic = 0; - real_free(old_hdr); + os_free(old_hdr); return new_ptr; } diff --git a/src/gallium/auxiliary/util/u_dl.c b/src/gallium/auxiliary/util/u_dl.c index b42b429d4d..37ed789f95 100644 --- a/src/gallium/auxiliary/util/u_dl.c +++ b/src/gallium/auxiliary/util/u_dl.c @@ -28,6 +28,7 @@ #include "pipe/p_config.h" +#include "pipe/p_compiler.h" #if defined(PIPE_OS_UNIX) #include <dlfcn.h> diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index 4110485fb1..14506e8451 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -28,7 +28,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" @@ -61,6 +61,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe, /* tell pipe about the vertex attributes */ for (i = 0; i < num_attribs; i++) { velements[i].src_offset = i * 4 * sizeof(float); + velements[i].instance_divisor = 0; velements[i].vertex_buffer_index = 0; velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; velements[i].nr_components = 4; diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 9f16b42944..01f7931aed 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -62,10 +62,10 @@ PIPE_FORMAT_R16G16_SSCALED , array , 1, 1, s16 , s16 , , , xy01, PIPE_FORMAT_R16G16B16_SSCALED , array , 1, 1, s16 , s16 , s16 , , xyz1, rgb PIPE_FORMAT_R16G16B16A16_SSCALED , array , 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb PIPE_FORMAT_R8_UNORM , array , 1, 1, un8 , , , , x001, rgb -PIPE_FORMAT_R8G8_UNORM , array , 1, 1, un8 , un8 , , , xy01, rgb -PIPE_FORMAT_R8G8B8_UNORM , array , 1, 1, un8 , un8 , un8 , , xyz1, rgb -PIPE_FORMAT_R8G8B8A8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb -PIPE_FORMAT_R8G8B8X8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , xyz1, rgb +PIPE_FORMAT_R8G8_UNORM , array , 1, 1, un8 , un8 , , , yx01, rgb +PIPE_FORMAT_R8G8B8_UNORM , array , 1, 1, un8 , un8 , un8 , , zyx1, rgb +PIPE_FORMAT_R8G8B8A8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb +PIPE_FORMAT_R8G8B8X8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb PIPE_FORMAT_R8_USCALED , array , 1, 1, u8 , , , , x001, rgb PIPE_FORMAT_R8G8_USCALED , array , 1, 1, u8 , u8 , , , xy01, rgb PIPE_FORMAT_R8G8B8_USCALED , array , 1, 1, u8 , u8 , u8 , , xyz1, rgb diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index a558923b2e..4323bc881b 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -31,6 +31,7 @@ #include "pipe/p_format.h" +#include "util/u_debug.h" #ifdef __cplusplus extern "C" { diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 76023794dc..4e358d3938 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "util/u_debug.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" @@ -1287,7 +1287,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, /* disabled blending/masking */ memset(&ctx->blend, 0, sizeof(ctx->blend)); - ctx->blend.colormask = PIPE_MASK_RGBA; + ctx->blend.rt[0].colormask = PIPE_MASK_RGBA; /* no-op depth/stencil/alpha */ memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); @@ -1411,8 +1411,8 @@ set_vertex_data(struct gen_mipmap_state *ctx, offset = get_next_slot( ctx ); - pipe_buffer_write(ctx->pipe->screen, ctx->vbuf, - offset, sizeof(ctx->vertices), ctx->vertices); + pipe_buffer_write_nooverlap(ctx->pipe->screen, ctx->vbuf, + offset, sizeof(ctx->vertices), ctx->vertices); return offset; } diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 5fbd62a03d..e95d58ea86 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -25,12 +25,15 @@ * **************************************************************************/ -#ifndef P_INLINES_H -#define P_INLINES_H +#ifndef U_INLINES_H +#define U_INLINES_H -#include "p_context.h" -#include "p_defines.h" -#include "p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_screen.h" +#include "util/u_debug.h" +#include "util/u_atomic.h" #ifdef __cplusplus @@ -38,7 +41,84 @@ extern "C" { #endif +/* + * Reference counting helper functions. + */ + + +static INLINE void +pipe_reference_init(struct pipe_reference *reference, unsigned count) +{ + p_atomic_set(&reference->count, count); +} + +static INLINE boolean +pipe_is_referenced(struct pipe_reference *reference) +{ + return p_atomic_read(&reference->count) != 0; +} + /** + * Update reference counting. + * The old thing pointed to, if any, will be unreferenced. + * Both 'ptr' and 'reference' may be NULL. + * \return TRUE if the object's refcount hits zero and should be destroyed. + */ +static INLINE boolean +pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) +{ + boolean destroy = FALSE; + + if(ptr != reference) { + /* bump the reference.count first */ + if (reference) { + assert(pipe_is_referenced(reference)); + p_atomic_inc(&reference->count); + } + + if (ptr) { + assert(pipe_is_referenced(ptr)); + if (p_atomic_dec_zero(&ptr->count)) { + destroy = TRUE; + } + } + } + + return destroy; +} + +static INLINE void +pipe_buffer_reference(struct pipe_buffer **ptr, struct pipe_buffer *buf) +{ + struct pipe_buffer *old_buf = *ptr; + + if (pipe_reference(&(*ptr)->reference, &buf->reference)) + old_buf->screen->buffer_destroy(old_buf); + *ptr = buf; +} + +static INLINE void +pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) +{ + struct pipe_surface *old_surf = *ptr; + + if (pipe_reference(&(*ptr)->reference, &surf->reference)) + old_surf->texture->screen->tex_surface_destroy(old_surf); + *ptr = surf; +} + +static INLINE void +pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) +{ + struct pipe_texture *old_tex = *ptr; + + if (pipe_reference(&(*ptr)->reference, &tex->reference)) + old_tex->screen->texture_destroy(old_tex); + *ptr = tex; +} + + +/* * Convenience wrappers for screen buffer functions. */ @@ -63,13 +143,6 @@ pipe_buffer_map(struct pipe_screen *screen, if(screen->buffer_map_range) { unsigned offset = 0; unsigned length = buf->size; - - /* XXX: Actually we should be using/detecting DISCARD - * instead of assuming that WRITE implies discard */ - if((usage & PIPE_BUFFER_USAGE_CPU_WRITE) && - !(usage & PIPE_BUFFER_USAGE_DISCARD)) - usage |= PIPE_BUFFER_USAGE_CPU_READ; - return screen->buffer_map_range(screen, buf, offset, length, usage); } else @@ -126,7 +199,39 @@ pipe_buffer_write(struct pipe_screen *screen, map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD); + assert(map); + if(map) { + memcpy((uint8_t *)map + offset, data, size); + pipe_buffer_flush_mapped_range(screen, buf, offset, size); + pipe_buffer_unmap(screen, buf); + } +} + +/** + * Special case for writing non-overlapping ranges. + * + * We can avoid GPU/CPU synchronization when writing range that has never + * been written before. + */ +static INLINE void +pipe_buffer_write_nooverlap(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned offset, unsigned size, + const void *data) +{ + void *map; + + assert(offset < buf->size); + assert(offset + size <= buf->size); + assert(size); + + map = pipe_buffer_map_range(screen, buf, offset, size, + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD | + PIPE_BUFFER_USAGE_UNSYNCHRONIZED); assert(map); if(map) { memcpy((uint8_t *)map + offset, data, size); @@ -196,4 +301,4 @@ pipe_transfer_buffer_flags( struct pipe_transfer *transf ) } #endif -#endif /* P_INLINES_H */ +#endif /* U_INLINES_H */ diff --git a/src/gallium/auxiliary/util/u_keymap.c b/src/gallium/auxiliary/util/u_keymap.c index c4b9eb3d9b..e161ccd88e 100644 --- a/src/gallium/auxiliary/util/u_keymap.c +++ b/src/gallium/auxiliary/util/u_keymap.c @@ -36,7 +36,6 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_defines.h" #include "cso_cache/cso_hash.h" diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index c3f8c91833..a2fc597356 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -26,7 +26,7 @@ **************************************************************************/ -/** +/* * Memory functions */ @@ -37,6 +37,7 @@ #include "util/u_pointer.h" #include "util/u_debug.h" +#include "os/os_memory.h" #ifdef __cplusplus @@ -44,114 +45,13 @@ extern "C" { #endif -/* Define ENOMEM for WINCE */ -#if (_WIN32_WCE < 600) -#ifndef ENOMEM -#define ENOMEM 12 -#endif -#endif - - -#if defined(PIPE_OS_WINDOWS) && defined(DEBUG) - -/* memory debugging */ - -#include "util/u_debug.h" - -#define MALLOC( _size ) \ - debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) -#define CALLOC( _count, _size ) \ - debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) -#define FREE( _ptr ) \ - debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) -#define REALLOC( _ptr, _old_size, _size ) \ - debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -void * __stdcall -EngAllocMem( - unsigned long Flags, - unsigned long MemSize, - unsigned long Tag ); - -void __stdcall -EngFreeMem( - void *Mem ); - -#define MALLOC( _size ) EngAllocMem( 0, _size, 'D3AG' ) -#define _FREE( _ptr ) EngFreeMem( _ptr ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - -void * -ExAllocatePool( - unsigned long PoolType, - size_t NumberOfBytes); - -void -ExFreePool(void *P); - -#define MALLOC(_size) ExAllocatePool(0, _size) -#define _FREE(_ptr) ExFreePool(_ptr) - -#else - -#define MALLOC( SIZE ) malloc( SIZE ) -#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) -#define FREE( PTR ) free( PTR ) - -static INLINE void * -_REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) -{ - (void) old_size; - return realloc(old_ptr, new_size); -} -#define REALLOC( a, b, c ) _REALLOC( a, b, c ) -#endif - - -#ifndef CALLOC -static INLINE void * -CALLOC( unsigned count, unsigned size ) -{ - void *ptr = MALLOC( count * size ); - if( ptr ) { - memset( ptr, 0, count * size ); - } - return ptr; -} -#endif /* !CALLOC */ +#define MALLOC(_size) os_malloc(_size) -#ifndef FREE -static INLINE void -FREE( void *ptr ) -{ - if( ptr ) { - _FREE( ptr ); - } -} -#endif /* !FREE */ +#define CALLOC(_count, _size) os_calloc(_count, _size) -#ifndef REALLOC -static INLINE void * -REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) -{ - void *new_ptr = NULL; - - if (new_size != 0) { - unsigned copy_size = old_size < new_size ? old_size : new_size; - new_ptr = MALLOC( new_size ); - if (new_ptr && old_ptr && copy_size) { - memcpy( new_ptr, old_ptr, copy_size ); - } - } - - FREE( old_ptr ); - return new_ptr; -} -#endif /* !REALLOC */ +#define FREE(_ptr ) os_free(_ptr) +#define REALLOC(_ptr, _old_size, _size) os_realloc(_ptr, _old_size, _size) #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) @@ -160,50 +60,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define CALLOC_VARIANT_LENGTH_STRUCT(T,more_size) ((struct T *) CALLOC(1, sizeof(struct T) + more_size)) -/** - * Return memory on given byte alignment - */ -static INLINE void * -align_malloc(size_t bytes, uint alignment) -{ -#if defined(HAVE_POSIX_MEMALIGN) - void *mem; - alignment = (alignment + (uint)sizeof(void*) - 1) & ~((uint)sizeof(void*) - 1); - if(posix_memalign(& mem, alignment, bytes) != 0) - return NULL; - return mem; -#else - char *ptr, *buf; - - assert( alignment > 0 ); - - ptr = (char *) MALLOC(bytes + alignment + sizeof(void *)); - if (!ptr) - return NULL; - - buf = (char *) align_pointer( ptr + sizeof(void *), alignment ); - *(char **)(buf - sizeof(void *)) = ptr; - - return buf; -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} - -/** - * Free memory returned by align_malloc(). - */ -static INLINE void -align_free(void *ptr) -{ -#if defined(HAVE_POSIX_MEMALIGN) - FREE(ptr); -#else - if (ptr) { - void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); - void *realAddr = *cubbyHole; - FREE(realAddr); - } -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} +#define align_malloc(_size, _alignment) os_malloc_aligned(_size, _alignment) +#define align_free(_ptr) os_free_aligned(_ptr) /** diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 43eb0153ee..0ab53c75dd 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -425,6 +425,8 @@ util_pack_z(enum pipe_format format, double z) if (z == 1.0) return 0xffffffff; return (uint) (z * 0xffffffff); + case PIPE_FORMAT_Z32_FLOAT: + return (uint)z; case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: if (z == 1.0) diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index 10a874f341..64390e1385 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -30,12 +30,13 @@ #define U_BLIT_H +#include "pipe/p_defines.h" +#include "util/u_debug.h" + #ifdef __cplusplus extern "C" { #endif -#include "pipe/p_defines.h" - static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr ) { boolean ok = TRUE; diff --git a/src/gallium/auxiliary/util/u_ringbuffer.c b/src/gallium/auxiliary/util/u_ringbuffer.c new file mode 100644 index 0000000000..648b105b13 --- /dev/null +++ b/src/gallium/auxiliary/util/u_ringbuffer.c @@ -0,0 +1,160 @@ + +#include "os/os_thread.h" +#include "pipe/p_defines.h" +#include "util/u_ringbuffer.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +/* Generic ringbuffer: + */ +struct util_ringbuffer +{ + struct util_packet *buf; + unsigned mask; + + /* Can this be done with atomic variables?? + */ + unsigned head; + unsigned tail; + pipe_condvar change; + pipe_mutex mutex; +}; + + +struct util_ringbuffer *util_ringbuffer_create( unsigned dwords ) +{ + struct util_ringbuffer *ring = CALLOC_STRUCT(util_ringbuffer); + if (ring == NULL) + return NULL; + + assert(util_is_power_of_two(dwords)); + + ring->buf = MALLOC( dwords * sizeof(unsigned) ); + if (ring->buf == NULL) + goto fail; + + ring->mask = dwords - 1; + + pipe_condvar_init(ring->change); + pipe_mutex_init(ring->mutex); + return ring; + +fail: + FREE(ring->buf); + FREE(ring); + return NULL; +} + +void util_ringbuffer_destroy( struct util_ringbuffer *ring ) +{ + pipe_condvar_destroy(ring->change); + pipe_mutex_destroy(ring->mutex); + FREE(ring->buf); + FREE(ring); +} + +/** + * Return number of free entries in the ring + */ +static INLINE unsigned util_ringbuffer_space( const struct util_ringbuffer *ring ) +{ + return (ring->tail - (ring->head + 1)) & ring->mask; +} + +/** + * Is the ring buffer empty? + */ +static INLINE boolean util_ringbuffer_empty( const struct util_ringbuffer *ring ) +{ + return util_ringbuffer_space(ring) == ring->mask; +} + +void util_ringbuffer_enqueue( struct util_ringbuffer *ring, + const struct util_packet *packet ) +{ + unsigned i; + + /* XXX: over-reliance on mutexes, etc: + */ + pipe_mutex_lock(ring->mutex); + + /* make sure we don't request an impossible amount of space + */ + assert(packet->dwords <= ring->mask); + + /* Wait for free space: + */ + while (util_ringbuffer_space(ring) < packet->dwords) + pipe_condvar_wait(ring->change, ring->mutex); + + /* Copy data to ring: + */ + for (i = 0; i < packet->dwords; i++) { + + /* Copy all dwords of the packet. Note we're abusing the + * typesystem a little - we're being passed a pointer to + * something, but probably not an array of packet structs: + */ + ring->buf[ring->head] = packet[i]; + ring->head++; + ring->head &= ring->mask; + } + + /* Signal change: + */ + pipe_condvar_signal(ring->change); + pipe_mutex_unlock(ring->mutex); +} + +enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring, + struct util_packet *packet, + unsigned max_dwords, + boolean wait ) +{ + const struct util_packet *ring_packet; + unsigned i; + int ret = PIPE_OK; + + /* XXX: over-reliance on mutexes, etc: + */ + pipe_mutex_lock(ring->mutex); + + /* Get next ring entry: + */ + if (wait) { + while (util_ringbuffer_empty(ring)) + pipe_condvar_wait(ring->change, ring->mutex); + } + else { + if (util_ringbuffer_empty(ring)) { + ret = PIPE_ERROR_OUT_OF_MEMORY; + goto out; + } + } + + ring_packet = &ring->buf[ring->tail]; + + /* Both of these are considered bugs. Raise an assert on debug builds. + */ + if (ring_packet->dwords > ring->mask + 1 - util_ringbuffer_space(ring) || + ring_packet->dwords > max_dwords) { + assert(0); + ret = PIPE_ERROR_BAD_INPUT; + goto out; + } + + /* Copy data from ring: + */ + for (i = 0; i < ring_packet->dwords; i++) { + packet[i] = ring->buf[ring->tail]; + ring->tail++; + ring->tail &= ring->mask; + } + +out: + /* Signal change: + */ + pipe_condvar_signal(ring->change); + pipe_mutex_unlock(ring->mutex); + return ret; +} diff --git a/src/gallium/auxiliary/util/u_ringbuffer.h b/src/gallium/auxiliary/util/u_ringbuffer.h new file mode 100644 index 0000000000..85f0ad6c1f --- /dev/null +++ b/src/gallium/auxiliary/util/u_ringbuffer.h @@ -0,0 +1,29 @@ + +#ifndef UTIL_RINGBUFFER_H +#define UTIL_RINGBUFFER_H + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" /* only for pipe_error! */ + +/* Generic header + */ +struct util_packet { + unsigned dwords:8; + unsigned data24:24; +}; + +struct util_ringbuffer; + +struct util_ringbuffer *util_ringbuffer_create( unsigned dwords ); + +void util_ringbuffer_destroy( struct util_ringbuffer *ring ); + +void util_ringbuffer_enqueue( struct util_ringbuffer *ring, + const struct util_packet *packet ); + +enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring, + struct util_packet *packet, + unsigned max_dwords, + boolean wait ); + +#endif diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c index 5238299015..53f3c16dbc 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.c +++ b/src/gallium/auxiliary/util/u_simple_screen.c @@ -29,7 +29,7 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" static struct pipe_buffer * diff --git a/src/gallium/auxiliary/util/u_simple_screen.h b/src/gallium/auxiliary/util/u_simple_screen.h index 6612a8a7c0..bb3f5ba102 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.h +++ b/src/gallium/auxiliary/util/u_simple_screen.h @@ -28,8 +28,145 @@ #ifndef U_SIMPLE_SCREEN_H #define U_SIMPLE_SCREEN_H +#include "pipe/p_format.h" + struct pipe_screen; -struct pipe_winsys; +struct pipe_fence_handle; +struct pipe_surface; +struct pipe_buffer; + +/** + * Gallium3D drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ +struct pipe_winsys +{ + void (*destroy)( struct pipe_winsys *ws ); + + /** Returns name of this winsys interface */ + const char *(*get_name)( struct pipe_winsys *ws ); + + /** + * Do any special operations to ensure buffer size is correct + */ + void (*update_buffer)( struct pipe_winsys *ws, + void *context_private ); + /** + * Do any special operations to ensure frontbuffer contents are + * displayed, eg copy fake frontbuffer. + */ + void (*flush_frontbuffer)( struct pipe_winsys *ws, + struct pipe_surface *surf, + void *context_private ); + + + /** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + * + * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This + * usage argument is only an optimization hint, not a guarantee, therefore + * proper behavior must be observed in all circumstances. + * + * alignment indicates the client's alignment requirements, eg for + * SSE instructions. + */ + struct pipe_buffer *(*buffer_create)( struct pipe_winsys *ws, + unsigned alignment, + unsigned usage, + unsigned size ); + + /** + * Create a buffer that wraps user-space data. + * + * Effectively this schedules a delayed call to buffer_create + * followed by an upload of the data at *some point in the future*, + * or perhaps never. Basically the allocate/upload is delayed + * until the buffer is actually passed to hardware. + * + * The intention is to provide a quick way to turn regular data + * into a buffer, and secondly to avoid a copy operation if that + * data subsequently turns out to be only accessed by the CPU. + * + * Common example is OpenGL vertex buffers that are subsequently + * processed either by software TNL in the driver or by passing to + * hardware. + * + * XXX: What happens if the delayed call to buffer_create() fails? + * + * Note that ptr may be accessed at any time upto the time when the + * buffer is destroyed, so the data must not be freed before then. + */ + struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *ws, + void *ptr, + unsigned bytes); + + /** + * Allocate storage for a display target surface. + * + * Often surfaces which are meant to be blitted to the front screen (i.e., + * display targets) must be allocated with special characteristics, memory + * pools, or obtained directly from the windowing system. + * + * This callback is invoked by the pipe_screenwhen creating a texture marked + * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying + * buffer storage. + */ + struct pipe_buffer *(*surface_buffer_create)(struct pipe_winsys *ws, + unsigned width, unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride); + + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags. + */ + void *(*buffer_map)( struct pipe_winsys *ws, + struct pipe_buffer *buf, + unsigned usage ); + + void (*buffer_unmap)( struct pipe_winsys *ws, + struct pipe_buffer *buf ); + + void (*buffer_destroy)( struct pipe_buffer *buf ); + + + /** Set ptr = fence, with reference counting */ + void (*fence_reference)( struct pipe_winsys *ws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ); + + /** + * Checks whether the fence has been signalled. + * \param flags driver-specific meaning + * \return zero on success. + */ + int (*fence_signalled)( struct pipe_winsys *ws, + struct pipe_fence_handle *fence, + unsigned flag ); + + /** + * Wait for the fence to finish. + * \param flags driver-specific meaning + * \return zero on success. + */ + int (*fence_finish)( struct pipe_winsys *ws, + struct pipe_fence_handle *fence, + unsigned flag ); + +}; /** * The following function initializes a simple passthrough screen. diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index b751e29ab6..019dda767d 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -38,6 +38,7 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" #include "util/u_simple_shaders.h" +#include "util/u_debug.h" #include "tgsi/tgsi_ureg.h" diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 35c4978204..c9f1c9c210 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -35,8 +35,9 @@ #include "pipe/p_screen.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" +#include "util/u_inlines.h" -#include "util/u_format.h" +#include "util/u_memory.h" #include "util/u_surface.h" @@ -111,3 +112,73 @@ util_destroy_rgba_surface(struct pipe_texture *texture, pipe_texture_reference(&texture, NULL); } + + +/** + * Compare pipe_framebuffer_state objects. + * \return TRUE if same, FALSE if different + */ +boolean +util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, + const struct pipe_framebuffer_state *src) +{ + unsigned i; + + if (dst->width != src->width || + dst->height != src->height) + return FALSE; + + for (i = 0; i < Elements(src->cbufs); i++) { + if (dst->cbufs[i] != src->cbufs[i]) { + return FALSE; + } + } + + if (dst->nr_cbufs != src->nr_cbufs) { + return FALSE; + } + + if (dst->zsbuf != src->zsbuf) { + return FALSE; + } + + return TRUE; +} + + +/** + * Copy framebuffer state from src to dst, updating refcounts. + */ +void +util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, + const struct pipe_framebuffer_state *src) +{ + unsigned i; + + dst->width = src->width; + dst->height = src->height; + + for (i = 0; i < Elements(src->cbufs); i++) { + pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]); + } + + dst->nr_cbufs = src->nr_cbufs; + + pipe_surface_reference(&dst->zsbuf, src->zsbuf); +} + + +void +util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb) +{ + unsigned i; + + for (i = 0; i < fb->nr_cbufs; i++) { + pipe_surface_reference(&fb->cbufs[i], NULL); + } + + pipe_surface_reference(&fb->zsbuf, NULL); + + fb->width = fb->height = 0; + fb->nr_cbufs = 0; +} diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h index ce84ed7ad0..3c60df2c3e 100644 --- a/src/gallium/auxiliary/util/u_surface.h +++ b/src/gallium/auxiliary/util/u_surface.h @@ -30,11 +30,7 @@ #include "pipe/p_compiler.h" - - -struct pipe_screen; -struct pipe_texture; -struct pipe_surface; +#include "pipe/p_state.h" /** @@ -66,4 +62,17 @@ util_destroy_rgba_surface(struct pipe_texture *texture, struct pipe_surface *surface); +extern boolean +util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, + const struct pipe_framebuffer_state *src); + +extern void +util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, + const struct pipe_framebuffer_state *src); + + +extern void +util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb); + + #endif /* U_SURFACE_H */ diff --git a/src/gallium/auxiliary/util/u_texture.c b/src/gallium/auxiliary/util/u_texture.c index cd477ab640..d97e57a790 100644 --- a/src/gallium/auxiliary/util/u_texture.c +++ b/src/gallium/auxiliary/util/u_texture.c @@ -37,6 +37,7 @@ #include "pipe/p_defines.h" +#include "util/u_debug.h" #include "util/u_texture.h" void util_map_texcoords2d_onto_cubemap(unsigned face, diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index 1ba82bb21f..0051258e22 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -32,7 +32,7 @@ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" @@ -390,7 +390,7 @@ a4r4g4b4_put_tile_rgba(ushort *dst, g >>= 4; b >>= 4; a >>= 4; - *dst++ = (a << 12) | (r << 16) | (g << 4) | b; + *dst++ = (a << 12) | (r << 8) | (g << 4) | b; } p += src_stride; } @@ -1357,7 +1357,10 @@ pipe_put_tile_rgba(struct pipe_transfer *pt, /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ break; default: - debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format)); + util_format_write_4f(format, + p, src_stride * sizeof(float), + packed, util_format_get_stride(format, w), + 0, 0, w, h); } pipe_put_tile_raw(pt, x, y, w, h, packed, 0); diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c deleted file mode 100644 index b958a98635..0000000000 --- a/src/gallium/auxiliary/util/u_time.c +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - -/** - * @file - * OS independent time-manipulation functions. - * - * @author Jose Fonseca <jrfonseca@tungstengraphics.com> - */ - - -#include "pipe/p_config.h" - -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) -#include <sys/time.h> -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) -#include <windows.h> -#include <winddi.h> -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -#include <windows.h> -extern VOID KeQuerySystemTime(PLARGE_INTEGER); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) -#include <windows.h> -#else -#error Unsupported OS -#endif - -#include "util/u_time.h" - - -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - -static int64_t frequency = 0; - -static INLINE void -util_time_get_frequency(void) -{ - if(!frequency) { -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - LONGLONG temp; - EngQueryPerformanceFrequency(&temp); - frequency = temp; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - LARGE_INTEGER temp; - QueryPerformanceFrequency(&temp); - frequency = temp.QuadPart; -#endif - } -} -#endif - - -void -util_time_get(struct util_time *t) -{ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - gettimeofday(&t->tv, NULL); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - LONGLONG temp; - EngQueryPerformanceCounter(&temp); - t->counter = temp; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* Updated every 10 miliseconds, measured in units of 100 nanoseconds. - * http://msdn.microsoft.com/en-us/library/ms801642.aspx */ - LARGE_INTEGER temp; - KeQuerySystemTime(&temp); - t->counter = temp.QuadPart; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - LARGE_INTEGER temp; - QueryPerformanceCounter(&temp); - t->counter = temp.QuadPart; -#endif -} - - -void -util_time_add(const struct util_time *t1, - int64_t usecs, - struct util_time *t2) -{ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; - t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - util_time_get_frequency(); - t2->counter = t1->counter + (usecs * frequency + INT64_C(999999))/INT64_C(1000000); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - /* 1 tick = 100 nano seconds. */ - t2->counter = t1->counter + usecs * 10; -#else - LARGE_INTEGER temp; - LONGLONG freq; - freq = temp.QuadPart; - t2->counter = t1->counter + (usecs * freq)/1000000L; -#endif -} - - -int64_t -util_time_diff(const struct util_time *t1, - const struct util_time *t2) -{ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - return (t2->tv.tv_usec - t1->tv.tv_usec) + - (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - util_time_get_frequency(); - return (t2->counter - t1->counter)*INT64_C(1000000)/frequency; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - return (t2->counter - t1->counter)/10; -#endif -} - - - -uint64_t -util_time_micros( void ) -{ - struct util_time t1; - - util_time_get(&t1); - -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - util_time_get_frequency(); - return t1.counter*INT64_C(1000000)/frequency; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - return t1.counter/10; -#endif -} - - - -/** - * Compare two time values. - * - * Not publicly available because it does not take in account wrap-arounds. - * Use util_time_timeout instead. - */ -static INLINE int -util_time_compare(const struct util_time *t1, - const struct util_time *t2) -{ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - if (t1->tv.tv_sec < t2->tv.tv_sec) - return -1; - else if(t1->tv.tv_sec > t2->tv.tv_sec) - return 1; - else if (t1->tv.tv_usec < t2->tv.tv_usec) - return -1; - else if(t1->tv.tv_usec > t2->tv.tv_usec) - return 1; - else - return 0; -#elif defined(PIPE_OS_WINDOWS) - if (t1->counter < t2->counter) - return -1; - else if(t1->counter > t2->counter) - return 1; - else - return 0; -#endif -} - - -boolean -util_time_timeout(const struct util_time *start, - const struct util_time *end, - const struct util_time *curr) -{ - if(util_time_compare(start, end) <= 0) - return !(util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0); - else - return !(util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0); -} - - -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) -void util_time_sleep(unsigned usecs) -{ - LONGLONG start, curr, end; - - EngQueryPerformanceCounter(&start); - - if(!frequency) - EngQueryPerformanceFrequency(&frequency); - - end = start + (usecs * frequency + 999999LL)/1000000LL; - - do { - EngQueryPerformanceCounter(&curr); - } while(start <= curr && curr < end || - end < start && (curr < end || start <= curr)); -} -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) -void util_time_sleep(unsigned usecs) -{ - Sleep((usecs + 999)/ 1000); -} -#endif diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index a6189a247b..15899c2c88 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -38,15 +38,7 @@ #include "pipe/p_config.h" -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) -#include <time.h> /* timeval */ -#include <unistd.h> /* usleep */ -#endif - -#if defined(PIPE_OS_HAIKU) -#include <sys/time.h> /* timeval */ -#include <unistd.h> -#endif +#include "os/os_time.h" #include "pipe/p_compiler.h" @@ -63,43 +55,92 @@ extern "C" { */ struct util_time { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) - struct timeval tv; -#else int64_t counter; -#endif }; -void -util_time_get(struct util_time *t); +PIPE_DEPRECATED +static INLINE void +util_time_get(struct util_time *t) +{ + t->counter = os_time_get(); +} + -void +/** + * Return t2 = t1 + usecs + */ +PIPE_DEPRECATED +static INLINE void util_time_add(const struct util_time *t1, int64_t usecs, - struct util_time *t2); + struct util_time *t2) +{ + t2->counter = t1->counter + usecs; +} -uint64_t -util_time_micros( void ); -int64_t +/** + * Return difference between times, in microseconds + */ +PIPE_DEPRECATED +static INLINE int64_t util_time_diff(const struct util_time *t1, - const struct util_time *t2); + const struct util_time *t2) +{ + return t2->counter - t1->counter; +} + + +/** + * Compare two time values. + * + * Not publicly available because it does not take in account wrap-arounds. + * Use util_time_timeout instead. + */ +static INLINE int +_util_time_compare(const struct util_time *t1, + const struct util_time *t2) +{ + if (t1->counter < t2->counter) + return -1; + else if(t1->counter > t2->counter) + return 1; + else + return 0; +} + /** * Returns non-zero when the timeout expires. */ -boolean +PIPE_DEPRECATED +static INLINE boolean util_time_timeout(const struct util_time *start, const struct util_time *end, - const struct util_time *curr); + const struct util_time *curr) +{ + return os_time_timeout(start->counter, end->counter, curr->counter); +} -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) -#define util_time_sleep usleep -#else -void -util_time_sleep(unsigned usecs); -#endif + +/** + * Return current time in microseconds + */ +PIPE_DEPRECATED +static INLINE int64_t +util_time_micros(void) +{ + return os_time_get(); +} + + +PIPE_DEPRECATED +static INLINE void +util_time_sleep(int64_t usecs) +{ + os_time_sleep(usecs); +} #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c index 178acdca4d..59bdcd2c45 100644 --- a/src/gallium/auxiliary/util/u_timed_winsys.c +++ b/src/gallium/auxiliary/util/u_timed_winsys.c @@ -30,7 +30,7 @@ */ #include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "u_timed_winsys.h" #include "util/u_memory.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index 975ee89c45..012b2ae233 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -30,7 +30,7 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_math.h" @@ -85,7 +85,9 @@ my_buffer_write(struct pipe_screen *screen, map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD | + PIPE_BUFFER_USAGE_UNSYNCHRONIZED); if (map == NULL) return PIPE_ERROR_OUT_OF_MEMORY; diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index fc2a1c59a6..ba23435f69 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -28,7 +28,7 @@ #include "vl_compositor.h" #include <assert.h> #include <pipe/p_context.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <tgsi/tgsi_parse.h> #include <tgsi/tgsi_build.h> #include <util/u_memory.h> @@ -245,7 +245,6 @@ init_pipe_state(struct vl_compositor *c) sampler.compare_mode = PIPE_TEX_COMPARE_NONE; sampler.compare_func = PIPE_FUNC_ALWAYS; sampler.normalized_coords = 1; - /*sampler.prefilter = ;*/ /*sampler.lod_bias = ;*/ /*sampler.min_lod = ;*/ /*sampler.max_lod = ;*/ @@ -316,6 +315,7 @@ init_buffers(struct vl_compositor *c) pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer); c->vertex_elems[0].src_offset = 0; + c->vertex_elems[0].instance_divisor = 0; c->vertex_elems[0].vertex_buffer_index = 0; c->vertex_elems[0].nr_components = 2; c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; @@ -345,6 +345,7 @@ init_buffers(struct vl_compositor *c) pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer); c->vertex_elems[1].src_offset = 0; + c->vertex_elems[1].instance_divisor = 0; c->vertex_elems[1].vertex_buffer_index = 1; c->vertex_elems[1].nr_components = 2; c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; @@ -353,7 +354,7 @@ init_buffers(struct vl_compositor *c) * Create our vertex shader's constant buffer * Const buffer contains scaling and translation vectors */ - c->vs_const_buf.buffer = pipe_buffer_create + c->vs_const_buf = pipe_buffer_create ( c->pipe->screen, 1, @@ -365,7 +366,7 @@ init_buffers(struct vl_compositor *c) * Create our fragment shader's constant buffer * Const buffer contains the color conversion matrix and bias vectors */ - c->fs_const_buf.buffer = pipe_buffer_create + c->fs_const_buf = pipe_buffer_create ( c->pipe->screen, 1, @@ -390,8 +391,8 @@ cleanup_buffers(struct vl_compositor *c) for (i = 0; i < 2; ++i) pipe_buffer_reference(&c->vertex_bufs[i].buffer, NULL); - pipe_buffer_reference(&c->vs_const_buf.buffer, NULL); - pipe_buffer_reference(&c->fs_const_buf.buffer, NULL); + pipe_buffer_reference(&c->vs_const_buf, NULL); + pipe_buffer_reference(&c->fs_const_buf, NULL); } bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe) @@ -483,13 +484,13 @@ void vl_compositor_render(struct vl_compositor *compositor, compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs); compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems); - compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf); - compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf); + compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf); + compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf); vs_consts = pipe_buffer_map ( compositor->pipe->screen, - compositor->vs_const_buf.buffer, + compositor->vs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD ); @@ -511,7 +512,7 @@ void vl_compositor_render(struct vl_compositor *compositor, vs_consts->src_trans.z = 0; vs_consts->src_trans.w = 0; - pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer); + pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf); compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence); @@ -525,10 +526,10 @@ void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float memcpy ( - pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + pipe_buffer_map(compositor->pipe->screen, compositor->fs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE), mat, sizeof(struct fragment_shader_consts) ); - pipe_buffer_unmap(compositor->pipe->screen, compositor->fs_const_buf.buffer); + pipe_buffer_unmap(compositor->pipe->screen, compositor->fs_const_buf); } diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h index f441901a75..6a9a3fd7af 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.h +++ b/src/gallium/auxiliary/vl/vl_compositor.h @@ -47,7 +47,7 @@ struct vl_compositor struct pipe_scissor_state scissor; struct pipe_vertex_buffer vertex_bufs[2]; struct pipe_vertex_element vertex_elems[2]; - struct pipe_constant_buffer vs_const_buf, fs_const_buf; + struct pipe_buffer *vs_const_buf, *fs_const_buf; }; bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index caf581aca6..f323de0ea5 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -28,7 +28,7 @@ #include "vl_mpeg12_mc_renderer.h" #include <assert.h> #include <pipe/p_context.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_math.h> #include <util/u_memory.h> @@ -762,7 +762,6 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r) sampler.compare_mode = PIPE_TEX_COMPARE_NONE; sampler.compare_func = PIPE_FUNC_ALWAYS; sampler.normalized_coords = 1; - /*sampler.prefilter = ; */ /*sampler.shadow_ambient = ; */ /*sampler.lod_bias = ; */ sampler.min_lod = 0; @@ -891,53 +890,61 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) /* Position element */ r->vertex_elems[0].src_offset = 0; + r->vertex_elems[0].instance_divisor = 0; r->vertex_elems[0].vertex_buffer_index = 0; r->vertex_elems[0].nr_components = 2; r->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; /* Luma, texcoord element */ r->vertex_elems[1].src_offset = sizeof(struct vertex2f); + r->vertex_elems[1].instance_divisor = 0; r->vertex_elems[1].vertex_buffer_index = 0; r->vertex_elems[1].nr_components = 2; r->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; /* Chroma Cr texcoord element */ r->vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2; + r->vertex_elems[2].instance_divisor = 0; r->vertex_elems[2].vertex_buffer_index = 0; r->vertex_elems[2].nr_components = 2; r->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT; /* Chroma Cb texcoord element */ r->vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3; + r->vertex_elems[3].instance_divisor = 0; r->vertex_elems[3].vertex_buffer_index = 0; r->vertex_elems[3].nr_components = 2; r->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT; /* First ref surface top field texcoord element */ r->vertex_elems[4].src_offset = 0; + r->vertex_elems[4].instance_divisor = 0; r->vertex_elems[4].vertex_buffer_index = 1; r->vertex_elems[4].nr_components = 2; r->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT; /* First ref surface bottom field texcoord element */ r->vertex_elems[5].src_offset = sizeof(struct vertex2f); + r->vertex_elems[5].instance_divisor = 0; r->vertex_elems[5].vertex_buffer_index = 1; r->vertex_elems[5].nr_components = 2; r->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT; /* Second ref surface top field texcoord element */ r->vertex_elems[6].src_offset = 0; + r->vertex_elems[6].instance_divisor = 0; r->vertex_elems[6].vertex_buffer_index = 2; r->vertex_elems[6].nr_components = 2; r->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT; /* Second ref surface bottom field texcoord element */ r->vertex_elems[7].src_offset = sizeof(struct vertex2f); + r->vertex_elems[7].instance_divisor = 0; r->vertex_elems[7].vertex_buffer_index = 2; r->vertex_elems[7].nr_components = 2; r->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT; - r->vs_const_buf.buffer = pipe_buffer_create + r->vs_const_buf = pipe_buffer_create ( r->pipe->screen, DEFAULT_BUF_ALIGNMENT, @@ -945,7 +952,7 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) sizeof(struct vertex_shader_consts) ); - r->fs_const_buf.buffer = pipe_buffer_create + r->fs_const_buf = pipe_buffer_create ( r->pipe->screen, DEFAULT_BUF_ALIGNMENT, @@ -954,11 +961,11 @@ init_buffers(struct vl_mpeg12_mc_renderer *r) memcpy ( - pipe_buffer_map(r->pipe->screen, r->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE), + pipe_buffer_map(r->pipe->screen, r->fs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE), &fs_consts, sizeof(struct fragment_shader_consts) ); - pipe_buffer_unmap(r->pipe->screen, r->fs_const_buf.buffer); + pipe_buffer_unmap(r->pipe->screen, r->fs_const_buf); return true; } @@ -970,8 +977,8 @@ cleanup_buffers(struct vl_mpeg12_mc_renderer *r) assert(r); - pipe_buffer_reference(&r->vs_const_buf.buffer, NULL); - pipe_buffer_reference(&r->fs_const_buf.buffer, NULL); + pipe_buffer_reference(&r->vs_const_buf, NULL); + pipe_buffer_reference(&r->fs_const_buf, NULL); for (i = 0; i < 3; ++i) pipe_buffer_reference(&r->vertex_bufs.all[i].buffer, NULL); @@ -1284,19 +1291,19 @@ flush(struct vl_mpeg12_mc_renderer *r) vs_consts = pipe_buffer_map ( - r->pipe->screen, r->vs_const_buf.buffer, + r->pipe->screen, r->vs_const_buf, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD ); vs_consts->denorm.x = r->surface->width0; vs_consts->denorm.y = r->surface->height0; - pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf.buffer); + pipe_buffer_unmap(r->pipe->screen, r->vs_const_buf); r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_VERTEX, 0, - &r->vs_const_buf); + r->vs_const_buf); r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_FRAGMENT, 0, - &r->fs_const_buf); + r->fs_const_buf); if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) { r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all); diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h index 64184337a0..f00b8c7b8b 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@ -63,8 +63,8 @@ struct vl_mpeg12_mc_renderer struct pipe_viewport_state viewport; struct pipe_scissor_state scissor; - struct pipe_constant_buffer vs_const_buf; - struct pipe_constant_buffer fs_const_buf; + struct pipe_buffer *vs_const_buf; + struct pipe_buffer *fs_const_buf; struct pipe_framebuffer_state fb_state; struct pipe_vertex_element vertex_elems[8]; diff --git a/src/gallium/docs/source/conf.py b/src/gallium/docs/source/conf.py index 9b0c86babd..59c19ed98d 100644 --- a/src/gallium/docs/source/conf.py +++ b/src/gallium/docs/source/conf.py @@ -16,13 +16,13 @@ import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) +sys.path.append(os.path.abspath('exts')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.pngmath'] +extensions = ['sphinx.ext.pngmath', 'tgsi'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 21f5f9111a..a7669575b9 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -33,7 +33,11 @@ This state describes how resources in various flavours (textures, buffers, surfaces) are bound to the driver. -* ``set_constant_buffer`` +* ``set_constant_buffer`` sets a constant buffer to be used for a given shader + type. index is used to indicate which buffer to set (some apis may allow + multiple ones to be set, and binding a specific one later, though drivers + are mostly restricted to the first one right now). + * ``set_framebuffer_state`` * ``set_fragment_sampler_textures`` * ``set_vertex_sampler_textures`` @@ -47,11 +51,13 @@ These pieces of state are too small, variable, and/or trivial to have CSO objects. They all follow simple, one-method binding calls, e.g. ``set_edgeflags``. -* ``set_edgeflags`` * ``set_blend_color`` * ``set_clip_state`` * ``set_polygon_stipple`` -* ``set_scissor_state`` +* ``set_scissor_state`` sets the bounds for the scissor test, which culls + pixels before blending to render targets. If the :ref:`Rasterizer` does + not have the scissor test enabled, then the scissor bounds never need to + be set since they will not be used. * ``set_viewport_state`` * ``set_vertex_elements`` @@ -72,12 +78,67 @@ stencil-only clears of packed depth-stencil buffers. Drawing ^^^^^^^ -``draw_arrays`` +``draw_arrays`` draws a specified primitive. + +This command is equivalent to calling ``draw_arrays_instanced`` +with ``startInstance`` set to 0 and ``instanceCount`` set to 1. -``draw_elements`` +``draw_elements`` draws a specified primitive using an optional +index buffer. + +This command is equivalent to calling ``draw_elements_instanced`` +with ``startInstance`` set to 0 and ``instanceCount`` set to 1. ``draw_range_elements`` +XXX: this is (probably) a temporary entrypoint, as the range +information should be available from the vertex_buffer state. +Using this to quickly evaluate a specialized path in the draw +module. + +``draw_arrays_instanced`` draws multiple instances of the same primitive. + +This command is equivalent to calling ``draw_elements_instanced`` +with ``indexBuffer`` set to NULL and ``indexSize`` set to 0. + +``draw_elements_instanced`` draws multiple instances of the same primitive +using an optional index buffer. + +For instanceID in the range between ``startInstance`` +and ``startInstance``+``instanceCount``-1, inclusive, draw a primitive +specified by ``mode`` and sequential numbers in the range between ``start`` +and ``start``+``count``-1, inclusive. + +If ``indexBuffer`` is not NULL, it specifies an index buffer with index +byte size of ``indexSize``. The sequential numbers are used to lookup +the index buffer and the resulting indices in turn are used to fetch +vertex attributes. + +If ``indexBuffer`` is NULL, the sequential numbers are used directly +as indices to fetch vertex attributes. + +If a given vertex element has ``instance_divisor`` set to 0, it is said +it contains per-vertex data and effective vertex attribute address needs +to be recalculated for every index. + + attribAddr = ``stride`` * index + ``src_offset`` + +If a given vertex element has ``instance_divisor`` set to non-zero, +it is said it contains per-instance data and effective vertex attribute +address needs to recalculated for every ``instance_divisor``-th instance. + + attribAddr = ``stride`` * instanceID / ``instance_divisor`` + ``src_offset`` + +In the above formulas, ``src_offset`` is taken from the given vertex element +and ``stride`` is taken from a vertex buffer associated with the given +vertex element. + +The calculated attribAddr is used as an offset into the vertex buffer to +fetch the attribute data. + +The value of ``instanceID`` can be read in a vertex shader through a system +value register declared with INSTANCEID semantic name. + Queries ^^^^^^^ @@ -87,9 +148,51 @@ draws. Queries may be nested, though no state tracker currently exercises this. Queries can be created with ``create_query`` and deleted with -``destroy_query``. To enable a query, use ``begin_query``, and when finished, -use ``end_query`` to stop the query. Finally, ``get_query_result`` is used -to retrieve the results. +``destroy_query``. To start a query, use ``begin_query``, and when finished, +use ``end_query`` to end the query. + +``get_query_result`` is used to retrieve the results of a query. If +the ``wait`` parameter is TRUE, then the ``get_query_result`` call +will block until the results of the query are ready (and TRUE will be +returned). Otherwise, if the ``wait`` parameter is FALSE, the call +will not block and the return value will be TRUE if the query has +completed or FALSE otherwise. + +A common type of query is the occlusion query which counts the number of +fragments/pixels which are written to the framebuffer (and not culled by +Z/stencil/alpha testing or shader KILL instructions). + + +Conditional Rendering +^^^^^^^^^^^^^^^^^^^^^ + +A drawing command can be skipped depending on the outcome of a query +(typically an occlusion query). The ``render_condition`` function specifies +the query which should be checked prior to rendering anything. + +If ``render_condition`` is called with ``query`` = NULL, conditional +rendering is disabled and drawing takes place normally. + +If ``render_condition`` is called with a non-null ``query`` subsequent +drawing commands will be predicated on the outcome of the query. If +the query result is zero subsequent drawing commands will be skipped. + +If ``mode`` is PIPE_RENDER_COND_WAIT the driver will wait for the +query to complete before deciding whether to render. + +If ``mode`` is PIPE_RENDER_COND_NO_WAIT and the query has not yet +completed, the drawing command will be executed normally. If the query +has completed, drawing will be predicated on the outcome of the query. + +If ``mode`` is PIPE_RENDER_COND_BY_REGION_WAIT or +PIPE_RENDER_COND_BY_REGION_NO_WAIT rendering will be predicated as above +for the non-REGION modes but in the case that an occulusion query returns +a non-zero result, regions which were occluded may be ommitted by subsequent +drawing commands. This can result in better performance with some GPUs. +Normally, if the occlusion query returned a non-zero result subsequent +drawing happens normally so fragments may be generated, shaded and +processed even where they're known to be obscured. + Flushing ^^^^^^^^ diff --git a/src/gallium/docs/source/cso/blend.rst b/src/gallium/docs/source/cso/blend.rst index fd9e4a1e2d..55c0f32885 100644 --- a/src/gallium/docs/source/cso/blend.rst +++ b/src/gallium/docs/source/cso/blend.rst @@ -6,9 +6,50 @@ Blend This state controls blending of the final fragments into the target rendering buffers. -XXX it is unresolved what behavior should result if blend_enable is off. +Blend Factors +------------- + +The blend factors largely follow the same pattern as their counterparts +in other modern and legacy drawing APIs. + +XXX blurb about dual-source blends Members ------- -XXX undocumented members +independent_blend_enable + If enabled, blend state is different for each render target, and + for each render target set in the respective member of the rt array. + If disabled, blend state is the same for all render targets, and only + the first member of the rt array contains valid data. +logicop_enable + Enables logic ops. Cannot be enabled at the same time as blending, and + is always the same for all render targets. +logicop_func + The logic operation to use if logic ops are enabled. One of PIPE_LOGICOP. +dither + Whether dithering is enabled. +rt + Contains the per-rendertarget blend state. + +Per-rendertarget Members +------------------------ + +blend_enable + If blending is enabled, perform a blend calculation according to blend + functions and source/destination factors. Otherwise, the incoming fragment + color gets passed unmodified (but colormask still applies). +rgb_func + The blend function to use for rgb channels. One of PIPE_BLEND. +rgb_src_factor + The blend source factor to use for rgb channels. One of PIPE_BLENDFACTOR. +rgb_dst_factor + The blend destination factor to use for rgb channels. One of PIPE_BLENDFACTOR. +alpha_func + The blend function to use for the alpha channel. One of PIPE_BLEND. +alpha_src_factor + The blend source factor to use for the alpha channel. One of PIPE_BLENDFACTOR. +alpha_dst_factor + The blend destination factor to use for alpha channel. One of PIPE_BLENDFACTOR. +colormask + Bitmask of which channels to write. Combination of PIPE_MASK bits. diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index 00d65fc598..24cc78c68d 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -7,32 +7,69 @@ The rasterizer state controls the rendering of points, lines and triangles. Attributes include polygon culling state, line width, line stipple, multisample state, scissoring and flat/smooth shading. - Members ------- +bypass_vs_clip_and_viewport +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Whether the entire TCL pipeline should be bypassed. This implies that +vertices are pre-transformed for the viewport, and will not be run +through the vertex shader. + +.. note:: + + Implementations may still clip away vertices that are not in the viewport + when this is set. + flatshade - If set, the provoking vertex of each polygon is used to determine the - color of the entire polygon. If not set, fragment colors will be - interpolated between the vertex colors. - Note that this is separate from the fragment shader input attributes - CONSTANT, LINEAR and PERSPECTIVE. We need the flatshade state at +^^^^^^^^^ + +If set, the provoking vertex of each polygon is used to determine the color +of the entire polygon. If not set, fragment colors will be interpolated +between the vertex colors. + +The actual interpolated shading algorithm is obviously +implementation-dependent, but will usually be Gourard for most hardware. + +.. note:: + + This is separate from the fragment shader input attributes + CONSTANT, LINEAR and PERSPECTIVE. The flatshade state is needed at clipping time to determine how to set the color of new vertices. - Also note that the draw module can implement flat shading by copying - the provoking vertex color to all the other vertices in the primitive. + + :ref:`Draw` can implement flat shading by copying the provoking vertex + color to all the other vertices in the primitive. flatshade_first - Whether the first vertex should be the provoking vertex, for most - primitives. If not set, the last vertex is the provoking vertex. +^^^^^^^^^^^^^^^ + +Whether the first vertex should be the provoking vertex, for most primitives. +If not set, the last vertex is the provoking vertex. + +There are several important exceptions to the specification of this rule. + +* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first + vertex. If the caller wishes to change the provoking vertex, they merely + need to rotate the vertices themselves. +* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no + effect; the provoking vertex is always the last vertex. +* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the + second vertex, not the first. This permits each segment of the fan to have + a different color. + +Other Members +^^^^^^^^^^^^^ light_twoside - If set, there are per-vertex back-facing colors. The draw module + If set, there are per-vertex back-facing colors. :ref:`Draw` uses this state along with the front/back information to set the final vertex colors prior to rasterization. front_winding Indicates the window order of front-facing polygons, either PIPE_WINDING_CW or PIPE_WINDING_CCW + cull_mode Indicates which polygons to cull, either PIPE_WINDING_NONE (cull no polygons), PIPE_WINDING_CW (cull clockwise-winding polygons), @@ -68,7 +105,7 @@ line_stipple_enable line_stipple_pattern 16-bit bitfield of on/off flags, used to pattern the line stipple. line_stipple_factor - When drawinga stippled line, each bit in the stipple pattern is + When drawing a stippled line, each bit in the stipple pattern is repeated N times, where N = line_stipple_factor + 1. line_last_pixel Controls whether the last pixel in a line is drawn or not. OpenGL @@ -98,7 +135,7 @@ sprite_coord_mode coordinate (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have coordinate (0,0,0,1). - This state is needed by the 'draw' module because that's where each + This state is needed by :ref:`Draw` because that's where each point vertex is converted into four quad vertices. There's no other place to emit the new vertex texture coordinates which are required for sprite rendering. @@ -118,45 +155,9 @@ scissor Whether the scissor test is enabled. multisample - Whether :ref:`MSAA` is enabled. - -bypass_vs_clip_and_viewport - Whether the entire TCL pipeline should be bypassed. This implies that - vertices are pre-transformed for the viewport, and will not be run - through the vertex shader. Note that implementations may still clip away - vertices that are not in the viewport. + Whether :term:`MSAA` is enabled. gl_rasterization_rules Whether the rasterizer should use (0.5, 0.5) pixel centers. When not set, the rasterizer will use (0, 0) for pixel centers. - -Notes ------ - -flatshade -^^^^^^^^^ - -The actual interpolated shading algorithm is obviously -implementation-dependent, but will usually be Gourard for most hardware. - -bypass_vs_clip_and_viewport -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When set, this implies that vertices are pre-transformed for the viewport, and -will not be run through the vertex shader. Note that implementations may still -clip away vertices that are not visible. - -flatshade_first -^^^^^^^^^^^^^^^ - -There are several important exceptions to the specification of this rule. - -* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first - vertex. If the caller wishes to change the provoking vertex, they merely - need to rotate the vertices themselves. -* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no - effect; the provoking vertex is always the last vertex. -* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the - second vertex, not the first. This permits each segment of the fan to have - a different color. diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst index e3f1757f57..044ffffcb4 100644 --- a/src/gallium/docs/source/cso/sampler.rst +++ b/src/gallium/docs/source/cso/sampler.rst @@ -12,8 +12,6 @@ with the traditional (S, T, R, Q) notation. Members ------- -XXX undocumented compare_mode, compare_func - wrap_s How to wrap the S coordinate. One of PIPE_TEX_WRAP. wrap_t @@ -27,12 +25,16 @@ min_mip_filter PIPE_TEX_FILTER. mag_img_filter The filter to use when magnifying texels. One of PIPE_TEX_FILTER. +compare_mode + If set to PIPE_TEX_COMPARE_R_TO_TEXTURE, texture output is computed + according to compare_func, using r coord and the texture value as operands. + If set to PIPE_TEX_COMPARE_NONE, no comparison calculation is performed. +compare_func + How the comparison is computed. One of PIPE_FUNC. normalized_coords Whether the texture coordinates are normalized. If normalized, they will always be in [0, 1]. If not, they will be in the range of each dimension of the loaded texture. -prefilter - XXX From the Doxy, "weird sampling state exposed by some APIs." Refine. lod_bias The bias to apply to the level of detail. min_lod diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst index 33e846e33d..100afe3397 100644 --- a/src/gallium/docs/source/distro.rst +++ b/src/gallium/docs/source/distro.rst @@ -31,21 +31,6 @@ Wrapper driver. LLVM Softpipe ^^^^^^^^^^^^^ -nVidia nv04 -^^^^^^^^^^^ - -Deprecated. - -nVidia nv10 -^^^^^^^^^^^ - -Deprecated. - -nVidia nv20 -^^^^^^^^^^^ - -Deprecated. - nVidia nv30 ^^^^^^^^^^^ @@ -61,10 +46,7 @@ VMWare SVGA ATI r300 ^^^^^^^^ -AMD/ATI r600 -^^^^^^^^^^^^ - -Highly experimental. +Testing-quality. Softpipe ^^^^^^^^ @@ -106,20 +88,50 @@ Xorg XFree86 DDX Auxiliary --------- +OS +^^ + +The OS module contains the abstractions for basic operating system services: + +* memory allocation +* simple message logging +* obtaining run-time configuration option +* threading primitives + +This is the bare minimum required to port Gallium to a new platform. + +The OS module already provides the implementations of these abstractions for +the most common platforms. When targeting an embedded platform no +implementation will be provided -- these must be provided separately. + CSO Cache ^^^^^^^^^ +The CSO cache is used to accelerate preparation of state by saving +driver-specific state structures for later use. + +.. _draw: + Draw ^^^^ +Draw is a software :term:`TCL` pipeline for hardware that lacks vertex shaders +or other essential parts of pre-rasterization vertex preparation. + Gallivm ^^^^^^^ Indices ^^^^^^^ -Pipe Buffer Manager -^^^^^^^^^^^^^^^^^^^ +Indices provides tools for translating or generating element indices for +use with element-based rendering. + +Pipe Buffer Managers +^^^^^^^^^^^^^^^^^^^^ + +Each of these managers provides various services to drivers that are not +fully utilizing a memory manager. Remote Debugger ^^^^^^^^^^^^^^^ @@ -127,12 +139,12 @@ Remote Debugger Runtime Assembly Emission ^^^^^^^^^^^^^^^^^^^^^^^^^ -Surface Context Tracker -^^^^^^^^^^^^^^^^^^^^^^^ - TGSI ^^^^ +The TGSI auxiliary module provides basic utilities for manipulating TGSI +streams. + Translate ^^^^^^^^^ diff --git a/src/gallium/docs/source/exts/tgsi.py b/src/gallium/docs/source/exts/tgsi.py new file mode 100644 index 0000000000..e92cd5c4d1 --- /dev/null +++ b/src/gallium/docs/source/exts/tgsi.py @@ -0,0 +1,17 @@ +# tgsi.py +# Sphinx extension providing formatting for TGSI opcodes +# (c) Corbin Simpson 2010 + +import docutils.nodes +import sphinx.addnodes + +def parse_opcode(env, sig, signode): + opcode, desc = sig.split("-", 1) + opcode = opcode.strip().upper() + desc = " (%s)" % desc.strip() + signode += sphinx.addnodes.desc_name(opcode, opcode) + signode += sphinx.addnodes.desc_annotation(desc, desc) + return opcode + +def setup(app): + app.add_description_unit("opcode", "opcode", "%s (TGSI opcode)", parse_opcode) diff --git a/src/gallium/docs/source/glossary.rst b/src/gallium/docs/source/glossary.rst index 6a9110ce78..0696cb5d27 100644 --- a/src/gallium/docs/source/glossary.rst +++ b/src/gallium/docs/source/glossary.rst @@ -8,3 +8,16 @@ Glossary Multi-Sampled Anti-Aliasing. A basic anti-aliasing technique that takes multiple samples of the depth buffer, and uses this information to smooth the edges of polygons. + + TCL + Transform, Clipping, & Lighting. The three stages of preparation in a + rasterizing pipeline prior to the actual rasterization of vertices into + fragments. + + NPOT + Non-power-of-two. Usually applied to textures which have at least one + dimension which is not a power of two. + + LOD + Level of Detail. Also spelled "LoD." The value that determines when the + switches between mipmaps occur during texture sampling. diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 9631e6967e..27f65522b6 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -3,6 +3,160 @@ Screen A screen is an object representing the context-independent part of a device. +Useful Flags +------------ + +.. _pipe_cap: + +PIPE_CAP +^^^^^^^^ + +Pipe capabilities help expose hardware functionality not explicitly required +by Gallium. For floating-point values, use :ref:`get_paramf`, and for boolean +or integer values, use :ref:`get_param`. + +The integer capabilities: + +* ``MAX_TEXTURE_IMAGE_UNITS``: The maximum number of samplers available. +* ``NPOT_TEXTURES``: Whether :term:`NPOT` textures may have repeat modes, + normalized coordinates, and mipmaps. +* ``TWO_SIDED_STENCIL``: Whether the stencil test can also affect back-facing + polygons. +* ``GLSL``: Deprecated. +* ``DUAL_SOURCE_BLEND``: Whether dual-source blend factors are supported. See + :ref:`Blend` for more information. +* ``ANISOTROPIC_FILTER``: Whether textures can be filtered anisotropically. +* ``POINT_SPRITE``: Whether point sprites are available. +* ``MAX_RENDER_TARGETS``: The maximum number of render targets that may be + bound. +* ``OCCLUSION_QUERY``: Whether occlusion queries are available. +* ``TEXTURE_SHADOW_MAP``: XXX +* ``MAX_TEXTURE_2D_LEVELS``: The maximum number of mipmap levels available + for a 2D texture. +* ``MAX_TEXTURE_3D_LEVELS``: The maximum number of mipmap levels available + for a 3D texture. +* ``MAX_TEXTURE_CUBE_LEVELS``: The maximum number of mipmap levels available + for a cubemap. +* ``TEXTURE_MIRROR_CLAMP``: Whether mirrored texture coordinates with clamp + are supported. +* ``TEXTURE_MIRROR_REPEAT``: Whether mirrored repeating texture coordinates + are supported. +* ``MAX_VERTEX_TEXTURE_UNITS``: The maximum number of samplers addressable + inside the vertex shader. If this is 0, then the vertex shader cannot + sample textures. +* ``TGSI_CONT_SUPPORTED``: Whether the TGSI CONT opcode is supported. +* ``BLEND_EQUATION_SEPARATE``: Whether alpha blend equations may be different + from color blend equations, in :ref:`Blend` state. +* ``SM3``: Whether the vertex shader and fragment shader support equivalent + opcodes to the Shader Model 3 specification. XXX oh god this is horrible +* ``MAX_PREDICATE_REGISTERS``: XXX +* ``MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from + the vertex and fragment shader, inclusive. +* ``MAX_CONST_BUFFERS``: Maximum number of constant buffers that can be bound + to any shader stage using ``set_constant_buffer``. If 0 or 1, the pipe will + only permit binding one constant buffer per shader, and the shaders will + not permit two-dimensional access to constants. +* ``MAX_CONST_BUFFER_SIZE``: Maximum byte size of a single constant buffer. +* ``INDEP_BLEND_ENABLE``: Whether per-rendertarget blend enabling and channel + masks are supported. If 0, then the first rendertarget's blend mask is + replicated across all MRTs. +* ``INDEP_BLEND_FUNC``: Whether per-rendertarget blend functions are + available. If 0, then the first rendertarget's blend functions affect all + MRTs. +* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT``: Whether the TGSI property + FS_COORD_ORIGIN with value UPPER_LEFT is supported. +* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT``: Whether the TGSI property + FS_COORD_ORIGIN with value LOWER_LEFT is supported. +* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER``: Whether the TGSI + property FS_COORD_PIXEL_CENTER with value HALF_INTEGER is supported. +* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER``: Whether the TGSI + property FS_COORD_PIXEL_CENTER with value INTEGER is supported. + +The floating-point capabilities: + +* ``MAX_LINE_WIDTH``: The maximum width of a regular line. +* ``MAX_LINE_WIDTH_AA``: The maximum width of a smoothed line. +* ``MAX_POINT_WIDTH``: The maximum width and height of a point. +* ``MAX_POINT_WIDTH_AA``: The maximum width and height of a smoothed point. +* ``MAX_TEXTURE_ANISOTROPY``: The maximum level of anisotropy that can be + applied to anisotropically filtered textures. +* ``MAX_TEXTURE_LOD_BIAS``: The maximum :term:`LOD` bias that may be applied + to filtered textures. +* ``GUARD_BAND_LEFT``, ``GUARD_BAND_TOP``, ``GUARD_BAND_RIGHT``, + ``GUARD_BAND_BOTTOM``: XXX + +XXX Is there a better home for this? vvv + +If 0 is returned, the driver is not aware of multiple constant buffers, +supports binding of only one constant buffer, and does not support +two-dimensional CONST register file access in TGSI shaders. + +If a value greater than 0 is returned, the driver can have multiple +constant buffers bound to shader stages. The CONST register file can +be accessed with two-dimensional indices, like in the example below. + +DCL CONST[0][0..7] # declare first 8 vectors of constbuf 0 +DCL CONST[3][0] # declare first vector of constbuf 3 +MOV OUT[0], CONST[0][3] # copy vector 3 of constbuf 0 + +For backwards compatibility, one-dimensional access to CONST register +file is still supported. In that case, the constbuf index is assumed +to be 0. + +.. _pipe_buffer_usage: + +PIPE_BUFFER_USAGE +^^^^^^^^^^^^^^^^^ + +These flags control buffer creation. Buffers may only have one role, so +care should be taken to not allocate a buffer with the wrong usage. + +* ``PIXEL``: This is the flag to use for all textures. +* ``VERTEX``: A vertex buffer. +* ``INDEX``: An element buffer. +* ``CONSTANT``: A buffer of shader constants. + +Buffers are inevitably abstracting the pipe's underlying memory management, +so many of their usage flags can be used to direct the way the buffer is +handled. + +* ``CPU_READ``, ``CPU_WRITE``: Whether the user will map and, in the case of + the latter, write to, the buffer. The convenience flag ``CPU_READ_WRITE`` is + available to signify a read/write buffer. +* ``GPU_READ``, ``GPU_WRITE``: Whether the driver will internally need to + read from or write to the buffer. The latter will only happen if the buffer + is made into a render target. +* ``DISCARD``: When set on a map, the contents of the map will be discarded + beforehand. Cannot be used with ``CPU_READ``. +* ``DONTBLOCK``: When set on a map, the map will fail if the buffer cannot be + mapped immediately. +* ``UNSYNCHRONIZED``: When set on a map, any outstanding operations on the + buffer will be ignored. The interaction of any writes to the map and any + operations pending with the buffer are undefined. Cannot be used with + ``CPU_READ``. +* ``FLUSH_EXPLICIT``: When set on a map, written ranges of the map require + explicit flushes using :ref:`buffer_flush_mapped_range`. Requires + ``CPU_WRITE``. + +.. _pipe_texture_usage: + +PIPE_TEXTURE_USAGE +^^^^^^^^^^^^^^^^^^ + +These flags determine the possible roles a texture may be used for during its +lifetime. Texture usage flags are cumulative and may be combined to create a +texture that can be used as multiple things. + +* ``RENDER_TARGET``: A colorbuffer or pixelbuffer. +* ``DISPLAY_TARGET``: A sharable buffer that can be given to another process. +* ``PRIMARY``: A frontbuffer or scanout buffer. +* ``DEPTH_STENCIL``: A depthbuffer, stencilbuffer, or Z buffer. Gallium does + not explicitly provide for stencil-only buffers, so any stencilbuffer + validated here is implicitly also a depthbuffer. +* ``SAMPLER``: A texture that may be sampled from in a fragment or vertex + shader. +* ``DYNAMIC``: A texture that will be mapped frequently. + Methods ------- @@ -18,22 +172,96 @@ get_vendor Returns the screen vendor. +.. _get_param: + get_param ^^^^^^^^^ Get an integer/boolean screen parameter. +**param** is one of the :ref:`PIPE_CAP` names. + +.. _get_paramf: + get_paramf ^^^^^^^^^^ Get a floating-point screen parameter. +**param** is one of the :ref:`PIPE_CAP` names. + +context_create +^^^^^^^^^^^^^^ + +Create a pipe_context. + +**priv** is private data of the caller, which may be put to various +unspecified uses, typically to do with implementing swapbuffers +and/or front-buffer rendering. + is_format_supported ^^^^^^^^^^^^^^^^^^^ See if a format can be used in a specific manner. +**usage** is a bitmask of :ref:`PIPE_TEXTURE_USAGE` flags. + +Returns TRUE if all usages can be satisfied. + +.. note:: + + ``PIPE_TEXTURE_USAGE_DYNAMIC`` is not a valid usage. + +.. _texture_create: + texture_create ^^^^^^^^^^^^^^ -Given a template of texture setup, create a BO-backed texture. +Given a template of texture setup, create a buffer and texture. + +texture_blanket +^^^^^^^^^^^^^^^ + +Like :ref:`texture_create`, but use a supplied buffer instead of creating a +new one. + +texture_destroy +^^^^^^^^^^^^^^^ + +Destroy a texture. The buffer backing the texture is destroyed if it has no +more references. + +buffer_map +^^^^^^^^^^ + +Map a buffer into memory. + +**usage** is a bitmask of :ref:`PIPE_BUFFER_USAGE` flags. + +Returns a pointer to the map, or NULL if the mapping failed. + +buffer_map_range +^^^^^^^^^^^^^^^^ + +Map a range of a buffer into memory. + +The returned map is always relative to the beginning of the buffer, not the +beginning of the mapped range. + +.. _buffer_flush_mapped_range: + +buffer_flush_mapped_range +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Flush a range of mapped memory into a buffer. + +The buffer must have been mapped with ``PIPE_BUFFER_USAGE_FLUSH_EXPLICIT``. + +**usage** is a bitmask of :ref:`PIPE_BUFFER_USAGE` flags. + +buffer_unmap +^^^^^^^^^^^^ + +Unmap a buffer from memory. + +Any pointers into the map should be considered invalid and discarded. diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst index ef068448e8..c292cd37d5 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -6,6 +6,23 @@ for describing shaders. Since Gallium is inherently shaderful, shaders are an important part of the API. TGSI is the only intermediate representation used by all drivers. +Basics +------ + +All TGSI instructions, known as *opcodes*, operate on arbitrary-precision +floating-point four-component vectors. An opcode may have up to one +destination register, known as *dst*, and between zero and three source +registers, called *src0* through *src2*, or simply *src* if there is only +one. + +Some instructions, like :opcode:`I2F`, permit re-interpretation of vector +components as integers. Other instructions permit using registers as +two-component vectors with double precision; see :ref:`Double Opcodes`. + +When an instruction has a scalar result, the result is usually copied into +each of the components of *dst*. When this happens, the result is said to be +*replicated* to *dst*. :opcode:`RCP` is one such instruction. + Instruction Set --------------- @@ -13,7 +30,7 @@ From GL_NV_vertex_program ^^^^^^^^^^^^^^^^^^^^^^^^^ -ARL - Address Register Load +.. opcode:: ARL - Address Register Load .. math:: @@ -26,7 +43,7 @@ ARL - Address Register Load dst.w = \lfloor src.w\rfloor -MOV - Move +.. opcode:: MOV - Move .. math:: @@ -39,7 +56,7 @@ MOV - Move dst.w = src.w -LIT - Light Coefficients +.. opcode:: LIT - Light Coefficients .. math:: @@ -52,33 +69,25 @@ LIT - Light Coefficients dst.w = 1 -RCP - Reciprocal - -.. math:: +.. opcode:: RCP - Reciprocal - dst.x = \frac{1}{src.x} +This instruction replicates its result. - dst.y = \frac{1}{src.x} +.. math:: - dst.z = \frac{1}{src.x} + dst = \frac{1}{src.x} - dst.w = \frac{1}{src.x} +.. opcode:: RSQ - Reciprocal Square Root -RSQ - Reciprocal Square Root +This instruction replicates its result. .. math:: - dst.x = \frac{1}{\sqrt{|src.x|}} - - dst.y = \frac{1}{\sqrt{|src.x|}} - - dst.z = \frac{1}{\sqrt{|src.x|}} + dst = \frac{1}{\sqrt{|src.x|}} - dst.w = \frac{1}{\sqrt{|src.x|}} - -EXP - Approximate Exponential Base 2 +.. opcode:: EXP - Approximate Exponential Base 2 .. math:: @@ -91,7 +100,7 @@ EXP - Approximate Exponential Base 2 dst.w = 1 -LOG - Approximate Logarithm Base 2 +.. opcode:: LOG - Approximate Logarithm Base 2 .. math:: @@ -104,7 +113,7 @@ LOG - Approximate Logarithm Base 2 dst.w = 1 -MUL - Multiply +.. opcode:: MUL - Multiply .. math:: @@ -117,7 +126,7 @@ MUL - Multiply dst.w = src0.w \times src1.w -ADD - Add +.. opcode:: ADD - Add .. math:: @@ -130,33 +139,25 @@ ADD - Add dst.w = src0.w + src1.w -DP3 - 3-component Dot Product - -.. math:: +.. opcode:: DP3 - 3-component Dot Product - dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z +This instruction replicates its result. - dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z +.. math:: - dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z - dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z +.. opcode:: DP4 - 4-component Dot Product -DP4 - 4-component Dot Product +This instruction replicates its result. .. math:: - dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w - - dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w - - dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w + dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w - dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src0.w \times src1.w - -DST - Distance Vector +.. opcode:: DST - Distance Vector .. math:: @@ -169,7 +170,7 @@ DST - Distance Vector dst.w = src1.w -MIN - Minimum +.. opcode:: MIN - Minimum .. math:: @@ -182,7 +183,7 @@ MIN - Minimum dst.w = min(src0.w, src1.w) -MAX - Maximum +.. opcode:: MAX - Maximum .. math:: @@ -195,7 +196,7 @@ MAX - Maximum dst.w = max(src0.w, src1.w) -SLT - Set On Less Than +.. opcode:: SLT - Set On Less Than .. math:: @@ -208,7 +209,7 @@ SLT - Set On Less Than dst.w = (src0.w < src1.w) ? 1 : 0 -SGE - Set On Greater Equal Than +.. opcode:: SGE - Set On Greater Equal Than .. math:: @@ -221,7 +222,7 @@ SGE - Set On Greater Equal Than dst.w = (src0.w >= src1.w) ? 1 : 0 -MAD - Multiply And Add +.. opcode:: MAD - Multiply And Add .. math:: @@ -234,7 +235,7 @@ MAD - Multiply And Add dst.w = src0.w \times src1.w + src2.w -SUB - Subtract +.. opcode:: SUB - Subtract .. math:: @@ -247,7 +248,7 @@ SUB - Subtract dst.w = src0.w - src1.w -LRP - Linear Interpolate +.. opcode:: LRP - Linear Interpolate .. math:: @@ -260,7 +261,7 @@ LRP - Linear Interpolate dst.w = src0.w \times src1.w + (1 - src0.w) \times src2.w -CND - Condition +.. opcode:: CND - Condition .. math:: @@ -273,7 +274,7 @@ CND - Condition dst.w = (src2.w > 0.5) ? src0.w : src1.w -DP2A - 2-component Dot Product And Add +.. opcode:: DP2A - 2-component Dot Product And Add .. math:: @@ -286,7 +287,7 @@ DP2A - 2-component Dot Product And Add dst.w = src0.x \times src1.x + src0.y \times src1.y + src2.x -FRAC - Fraction +.. opcode:: FRAC - Fraction .. math:: @@ -299,7 +300,7 @@ FRAC - Fraction dst.w = src.w - \lfloor src.w\rfloor -CLAMP - Clamp +.. opcode:: CLAMP - Clamp .. math:: @@ -312,9 +313,9 @@ CLAMP - Clamp dst.w = clamp(src0.w, src1.w, src2.w) -FLR - Floor +.. opcode:: FLR - Floor -This is identical to ARL. +This is identical to :opcode:`ARL`. .. math:: @@ -327,7 +328,7 @@ This is identical to ARL. dst.w = \lfloor src.w\rfloor -ROUND - Round +.. opcode:: ROUND - Round .. math:: @@ -340,45 +341,33 @@ ROUND - Round dst.w = round(src.w) -EX2 - Exponential Base 2 - -.. math:: +.. opcode:: EX2 - Exponential Base 2 - dst.x = 2^{src.x} +This instruction replicates its result. - dst.y = 2^{src.x} +.. math:: - dst.z = 2^{src.x} + dst = 2^{src.x} - dst.w = 2^{src.x} +.. opcode:: LG2 - Logarithm Base 2 -LG2 - Logarithm Base 2 +This instruction replicates its result. .. math:: - dst.x = \log_2{src.x} - - dst.y = \log_2{src.x} + dst = \log_2{src.x} - dst.z = \log_2{src.x} - dst.w = \log_2{src.x} +.. opcode:: POW - Power - -POW - Power +This instruction replicates its result. .. math:: - dst.x = src0.x^{src1.x} - - dst.y = src0.x^{src1.x} - - dst.z = src0.x^{src1.x} + dst = src0.x^{src1.x} - dst.w = src0.x^{src1.x} - -XPD - Cross Product +.. opcode:: XPD - Cross Product .. math:: @@ -391,7 +380,7 @@ XPD - Cross Product dst.w = 1 -ABS - Absolute +.. opcode:: ABS - Absolute .. math:: @@ -404,48 +393,36 @@ ABS - Absolute dst.w = |src.w| -RCC - Reciprocal Clamped +.. opcode:: RCC - Reciprocal Clamped + +This instruction replicates its result. XXX cleanup on aisle three .. math:: - dst.x = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020) - - dst.y = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020) + dst = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020) - dst.z = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020) - dst.w = (1 / src.x) > 0 ? clamp(1 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1 / src.x, -1.884467e+019, -5.42101e-020) +.. opcode:: DPH - Homogeneous Dot Product - -DPH - Homogeneous Dot Product +This instruction replicates its result. .. math:: - dst.x = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w - - dst.y = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w - - dst.z = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w + dst = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w - dst.w = src0.x \times src1.x + src0.y \times src1.y + src0.z \times src1.z + src1.w +.. opcode:: COS - Cosine -COS - Cosine +This instruction replicates its result. .. math:: - dst.x = \cos{src.x} - - dst.y = \cos{src.x} - - dst.z = \cos{src.x} + dst = \cos{src.x} - dst.w = \cos{src.x} - -DDX - Derivative Relative To X +.. opcode:: DDX - Derivative Relative To X .. math:: @@ -458,7 +435,7 @@ DDX - Derivative Relative To X dst.w = partialx(src.w) -DDY - Derivative Relative To Y +.. opcode:: DDY - Derivative Relative To Y .. math:: @@ -471,32 +448,32 @@ DDY - Derivative Relative To Y dst.w = partialy(src.w) -KILP - Predicated Discard +.. opcode:: KILP - Predicated Discard discard -PK2H - Pack Two 16-bit Floats +.. opcode:: PK2H - Pack Two 16-bit Floats TBD -PK2US - Pack Two Unsigned 16-bit Scalars +.. opcode:: PK2US - Pack Two Unsigned 16-bit Scalars TBD -PK4B - Pack Four Signed 8-bit Scalars +.. opcode:: PK4B - Pack Four Signed 8-bit Scalars TBD -PK4UB - Pack Four Unsigned 8-bit Scalars +.. opcode:: PK4UB - Pack Four Unsigned 8-bit Scalars TBD -RFL - Reflection Vector +.. opcode:: RFL - Reflection Vector .. math:: @@ -508,145 +485,171 @@ RFL - Reflection Vector dst.w = 1 -Considered for removal. +.. note:: + + Considered for removal. -SEQ - Set On Equal +.. opcode:: SEQ - Set On Equal .. math:: dst.x = (src0.x == src1.x) ? 1 : 0 + dst.y = (src0.y == src1.y) ? 1 : 0 + dst.z = (src0.z == src1.z) ? 1 : 0 + dst.w = (src0.w == src1.w) ? 1 : 0 -SFL - Set On False +.. opcode:: SFL - Set On False + +This instruction replicates its result. .. math:: - dst.x = 0 - dst.y = 0 - dst.z = 0 - dst.w = 0 + dst = 0 + +.. note:: + + Considered for removal. -Considered for removal. -SGT - Set On Greater Than +.. opcode:: SGT - Set On Greater Than .. math:: dst.x = (src0.x > src1.x) ? 1 : 0 + dst.y = (src0.y > src1.y) ? 1 : 0 - dst.z = (src0.z > src1.z) ? 1 : 0 - dst.w = (src0.w > src1.w) ? 1 : 0 + dst.z = (src0.z > src1.z) ? 1 : 0 -SIN - Sine + dst.w = (src0.w > src1.w) ? 1 : 0 -.. math:: - dst.x = \sin{src.x} +.. opcode:: SIN - Sine - dst.y = \sin{src.x} +This instruction replicates its result. - dst.z = \sin{src.x} +.. math:: - dst.w = \sin{src.x} + dst = \sin{src.x} -SLE - Set On Less Equal Than +.. opcode:: SLE - Set On Less Equal Than .. math:: dst.x = (src0.x <= src1.x) ? 1 : 0 + dst.y = (src0.y <= src1.y) ? 1 : 0 + dst.z = (src0.z <= src1.z) ? 1 : 0 + dst.w = (src0.w <= src1.w) ? 1 : 0 -SNE - Set On Not Equal +.. opcode:: SNE - Set On Not Equal .. math:: dst.x = (src0.x != src1.x) ? 1 : 0 + dst.y = (src0.y != src1.y) ? 1 : 0 + dst.z = (src0.z != src1.z) ? 1 : 0 + dst.w = (src0.w != src1.w) ? 1 : 0 -STR - Set On True +.. opcode:: STR - Set On True + +This instruction replicates its result. .. math:: - dst.x = 1 - dst.y = 1 - dst.z = 1 - dst.w = 1 + dst = 1 -TEX - Texture Lookup +.. opcode:: TEX - Texture Lookup TBD -TXD - Texture Lookup with Derivatives +.. opcode:: TXD - Texture Lookup with Derivatives TBD -TXP - Projective Texture Lookup +.. opcode:: TXP - Projective Texture Lookup TBD -UP2H - Unpack Two 16-Bit Floats +.. opcode:: UP2H - Unpack Two 16-Bit Floats TBD - Considered for removal. +.. note:: + + Considered for removal. -UP2US - Unpack Two Unsigned 16-Bit Scalars +.. opcode:: UP2US - Unpack Two Unsigned 16-Bit Scalars TBD - Considered for removal. +.. note:: + + Considered for removal. -UP4B - Unpack Four Signed 8-Bit Values +.. opcode:: UP4B - Unpack Four Signed 8-Bit Values TBD - Considered for removal. +.. note:: -UP4UB - Unpack Four Unsigned 8-Bit Scalars + Considered for removal. + +.. opcode:: UP4UB - Unpack Four Unsigned 8-Bit Scalars TBD - Considered for removal. +.. note:: + + Considered for removal. -X2D - 2D Coordinate Transformation +.. opcode:: X2D - 2D Coordinate Transformation .. math:: dst.x = src0.x + src1.x \times src2.x + src1.y \times src2.y + dst.y = src0.y + src1.x \times src2.z + src1.y \times src2.w + dst.z = src0.x + src1.x \times src2.x + src1.y \times src2.y + dst.w = src0.y + src1.x \times src2.z + src1.y \times src2.w -Considered for removal. +.. note:: + + Considered for removal. From GL_NV_vertex_program2 ^^^^^^^^^^^^^^^^^^^^^^^^^^ -ARA - Address Register Add +.. opcode:: ARA - Address Register Add TBD - Considered for removal. +.. note:: -ARR - Address Register Load With Round + Considered for removal. + +.. opcode:: ARR - Address Register Load With Round .. math:: @@ -659,26 +662,28 @@ ARR - Address Register Load With Round dst.w = round(src.w) -BRA - Branch +.. opcode:: BRA - Branch pc = target - Considered for removal. +.. note:: + + Considered for removal. -CAL - Subroutine Call +.. opcode:: CAL - Subroutine Call push(pc) pc = target -RET - Subroutine Call Return +.. opcode:: RET - Subroutine Call Return pc = pop() Potential restrictions: * Only occurs at end of function. -SSG - Set Sign +.. opcode:: SSG - Set Sign .. math:: @@ -691,7 +696,7 @@ SSG - Set Sign dst.w = (src.w > 0) ? 1 : (src.w < 0) ? -1 : 0 -CMP - Compare +.. opcode:: CMP - Compare .. math:: @@ -704,7 +709,7 @@ CMP - Compare dst.w = (src0.w < 0) ? src1.w : src2.w -KIL - Conditional Discard +.. opcode:: KIL - Conditional Discard .. math:: @@ -713,7 +718,7 @@ KIL - Conditional Discard endif -SCS - Sine Cosine +.. opcode:: SCS - Sine Cosine .. math:: @@ -726,12 +731,12 @@ SCS - Sine Cosine dst.y = 1 -TXB - Texture Lookup With Bias +.. opcode:: TXB - Texture Lookup With Bias TBD -NRM - 3-component Vector Normalise +.. opcode:: NRM - 3-component Vector Normalise .. math:: @@ -744,7 +749,7 @@ NRM - 3-component Vector Normalise dst.w = 1 -DIV - Divide +.. opcode:: DIV - Divide .. math:: @@ -757,35 +762,31 @@ DIV - Divide dst.w = \frac{src0.w}{src1.w} -DP2 - 2-component Dot Product +.. opcode:: DP2 - 2-component Dot Product -.. math:: +This instruction replicates its result. - dst.x = src0.x \times src1.x + src0.y \times src1.y - - dst.y = src0.x \times src1.x + src0.y \times src1.y - - dst.z = src0.x \times src1.x + src0.y \times src1.y +.. math:: - dst.w = src0.x \times src1.x + src0.y \times src1.y + dst = src0.x \times src1.x + src0.y \times src1.y -TXL - Texture Lookup With LOD +.. opcode:: TXL - Texture Lookup With LOD TBD -BRK - Break +.. opcode:: BRK - Break TBD -IF - If +.. opcode:: IF - If TBD -BGNFOR - Begin a For-Loop +.. opcode:: BGNFOR - Begin a For-Loop dst.x = floor(src.x) dst.y = floor(src.y) @@ -798,25 +799,31 @@ BGNFOR - Begin a For-Loop Note: The destination must be a loop register. The source must be a constant register. - Considered for cleanup / removal. +.. note:: + + Considered for cleanup. + +.. note:: + + Considered for removal. -REP - Repeat +.. opcode:: REP - Repeat TBD -ELSE - Else +.. opcode:: ELSE - Else TBD -ENDIF - End If +.. opcode:: ENDIF - End If TBD -ENDFOR - End a For-Loop +.. opcode:: ENDFOR - End a For-Loop dst.x = dst.x + dst.z dst.y = dst.y - 1.0 @@ -827,30 +834,48 @@ ENDFOR - End a For-Loop Note: The destination must be a loop register. - Considered for cleanup / removal. +.. note:: -ENDREP - End Repeat + Considered for cleanup. + +.. note:: + + Considered for removal. + +.. opcode:: ENDREP - End Repeat TBD -PUSHA - Push Address Register On Stack +.. opcode:: PUSHA - Push Address Register On Stack push(src.x) push(src.y) push(src.z) push(src.w) - Considered for cleanup / removal. +.. note:: + + Considered for cleanup. + +.. note:: + + Considered for removal. -POPA - Pop Address Register From Stack +.. opcode:: POPA - Pop Address Register From Stack dst.w = pop() dst.z = pop() dst.y = pop() dst.x = pop() - Considered for cleanup / removal. +.. note:: + + Considered for cleanup. + +.. note:: + + Considered for removal. From GL_NV_gpu_program4 @@ -858,7 +883,7 @@ From GL_NV_gpu_program4 Support for these opcodes indicated by a special pipe capability bit (TBD). -CEIL - Ceiling +.. opcode:: CEIL - Ceiling .. math:: @@ -871,7 +896,7 @@ CEIL - Ceiling dst.w = \lceil src.w\rceil -I2F - Integer To Float +.. opcode:: I2F - Integer To Float .. math:: @@ -884,7 +909,7 @@ I2F - Integer To Float dst.w = (float) src.w -NOT - Bitwise Not +.. opcode:: NOT - Bitwise Not .. math:: @@ -897,7 +922,7 @@ NOT - Bitwise Not dst.w = ~src.w -TRUNC - Truncate +.. opcode:: TRUNC - Truncate .. math:: @@ -910,7 +935,7 @@ TRUNC - Truncate dst.w = trunc(src.w) -SHL - Shift Left +.. opcode:: SHL - Shift Left .. math:: @@ -923,7 +948,7 @@ SHL - Shift Left dst.w = src0.w << src1.x -SHR - Shift Right +.. opcode:: SHR - Shift Right .. math:: @@ -936,7 +961,7 @@ SHR - Shift Right dst.w = src0.w >> src1.x -AND - Bitwise And +.. opcode:: AND - Bitwise And .. math:: @@ -949,7 +974,7 @@ AND - Bitwise And dst.w = src0.w & src1.w -OR - Bitwise Or +.. opcode:: OR - Bitwise Or .. math:: @@ -962,7 +987,7 @@ OR - Bitwise Or dst.w = src0.w | src1.w -MOD - Modulus +.. opcode:: MOD - Modulus .. math:: @@ -975,20 +1000,20 @@ MOD - Modulus dst.w = src0.w \bmod src1.w -XOR - Bitwise Xor +.. opcode:: XOR - Bitwise Xor .. math:: - dst.x = src0.x ^ src1.x + dst.x = src0.x \oplus src1.x - dst.y = src0.y ^ src1.y + dst.y = src0.y \oplus src1.y - dst.z = src0.z ^ src1.z + dst.z = src0.z \oplus src1.z - dst.w = src0.w ^ src1.w + dst.w = src0.w \oplus src1.w -SAD - Sum Of Absolute Differences +.. opcode:: SAD - Sum Of Absolute Differences .. math:: @@ -1001,17 +1026,17 @@ SAD - Sum Of Absolute Differences dst.w = |src0.w - src1.w| + src2.w -TXF - Texel Fetch +.. opcode:: TXF - Texel Fetch TBD -TXQ - Texture Size Query +.. opcode:: TXQ - Texture Size Query TBD -CONT - Continue +.. opcode:: CONT - Continue TBD @@ -1020,12 +1045,12 @@ From GL_NV_geometry_program4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -EMIT - Emit +.. opcode:: EMIT - Emit TBD -ENDPRIM - End Primitive +.. opcode:: ENDPRIM - End Primitive TBD @@ -1034,62 +1059,171 @@ From GLSL ^^^^^^^^^^ -BGNLOOP - Begin a Loop +.. opcode:: BGNLOOP - Begin a Loop TBD -BGNSUB - Begin Subroutine +.. opcode:: BGNSUB - Begin Subroutine TBD -ENDLOOP - End a Loop +.. opcode:: ENDLOOP - End a Loop TBD -ENDSUB - End Subroutine +.. opcode:: ENDSUB - End Subroutine TBD -NOP - No Operation +.. opcode:: NOP - No Operation Do nothing. -NRM4 - 4-component Vector Normalise - -.. math:: - - dst.x = \frac{src.x}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w} +.. opcode:: NRM4 - 4-component Vector Normalise - dst.y = \frac{src.y}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w} +This instruction replicates its result. - dst.z = \frac{src.z}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w} +.. math:: - dst.w = \frac{src.w}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w} + dst = \frac{src.x}{src.x \times src.x + src.y \times src.y + src.z \times src.z + src.w \times src.w} ps_2_x ^^^^^^^^^^^^ -CALLNZ - Subroutine Call If Not Zero +.. opcode:: CALLNZ - Subroutine Call If Not Zero TBD -IFC - If +.. opcode:: IFC - If TBD -BREAKC - Break Conditional +.. opcode:: BREAKC - Break Conditional TBD +.. _doubleopcodes: + +Double Opcodes +^^^^^^^^^^^^^^^ + +.. opcode:: DADD - Add Double + +.. math:: + + dst.xy = src0.xy + src1.xy + + dst.zw = src0.zw + src1.zw + + +.. opcode:: DDIV - Divide Double + +.. math:: + + dst.xy = src0.xy / src1.xy + + dst.zw = src0.zw / src1.zw + +.. opcode:: DSEQ - Set Double on Equal + +.. math:: + + dst.xy = src0.xy == src1.xy ? 1.0F : 0.0F + + dst.zw = src0.zw == src1.zw ? 1.0F : 0.0F + +.. opcode:: DSLT - Set Double on Less than + +.. math:: + + dst.xy = src0.xy < src1.xy ? 1.0F : 0.0F + + dst.zw = src0.zw < src1.zw ? 1.0F : 0.0F + +.. opcode:: DFRAC - Double Fraction + +.. math:: + + dst.xy = src.xy - \lfloor src.xy\rfloor + + dst.zw = src.zw - \lfloor src.zw\rfloor + + +.. opcode:: DFRACEXP - Convert Double Number to Fractional and Integral Components + +.. math:: + + dst0.xy = frexp(src.xy, dst1.xy) + + dst0.zw = frexp(src.zw, dst1.zw) + +.. opcode:: DLDEXP - Multiple Double Number by Integral Power of 2 + +.. math:: + + dst.xy = ldexp(src0.xy, src1.xy) + + dst.zw = ldexp(src0.zw, src1.zw) + +.. opcode:: DMIN - Minimum Double + +.. math:: + + dst.xy = min(src0.xy, src1.xy) + + dst.zw = min(src0.zw, src1.zw) + +.. opcode:: DMAX - Maximum Double + +.. math:: + + dst.xy = max(src0.xy, src1.xy) + + dst.zw = max(src0.zw, src1.zw) + +.. opcode:: DMUL - Multiply Double + +.. math:: + + dst.xy = src0.xy \times src1.xy + + dst.zw = src0.zw \times src1.zw + + +.. opcode:: DMAD - Multiply And Add Doubles + +.. math:: + + dst.xy = src0.xy \times src1.xy + src2.xy + + dst.zw = src0.zw \times src1.zw + src2.zw + + +.. opcode:: DRCP - Reciprocal Double + +.. math:: + + dst.xy = \frac{1}{src.xy} + + dst.zw = \frac{1}{src.zw} + +.. opcode:: DSQRT - Square root double + +.. math:: + + dst.xy = \sqrt{src.xy} + + dst.zw = \sqrt{src.zw} + Explanation of symbols used ------------------------------ @@ -1137,25 +1271,41 @@ Keywords discard Discard fragment. - dst First destination register. + pc Program counter. - dst0 First destination register. + target Label of target instruction. - pc Program counter. - src First source register. +Other tokens +--------------- - src0 First source register. - src1 Second source register. +Declaration +^^^^^^^^^^^ - src2 Third source register. - target Label of target instruction. +Declares a register that is will be referenced as an operand in Instruction +tokens. +File field contains register file that is being declared and is one +of TGSI_FILE. -Other tokens ---------------- +UsageMask field specifies which of the register components can be accessed +and is one of TGSI_WRITEMASK. + +Interpolate field is only valid for fragment shader INPUT register files. +It specifes the way input is being interpolated by the rasteriser and is one +of TGSI_INTERPOLATE. + +If Dimension flag is set to 1, a Declaration Dimension token follows. + +If Semantic flag is set to 1, a Declaration Semantic token follows. + +CylindricalWrap bitfield is only valid for fragment shader INPUT register +files. It specifies which register components should be subject to cylindrical +wrapping when interpolating by the rasteriser. If TGSI_CYLINDRICAL_WRAP_X +is set to 1, the X component should be interpolated according to cylindrical +wrapping rules. Declaration Semantic @@ -1187,9 +1337,8 @@ are the Cartesian coordinates, and ``w`` is the homogenous coordinate and used for the perspective divide, if enabled. As a vertex shader output, position should be scaled to the viewport. When -used in fragment shaders, position will --- - -XXX --- wait a minute. Should position be in [0,1] for x and y? +used in fragment shaders, position will be in window coordinates. The convention +used depends on the FS_COORD_ORIGIN and FS_COORD_PIXEL_CENTER properties. XXX additionally, is there a way to configure the perspective divide? it's accelerated on most chipsets AFAIK... @@ -1266,3 +1415,85 @@ TGSI_SEMANTIC_EDGEFLAG """""""""""""""""""""" XXX no clue + + +Properties +^^^^^^^^^^^^^^^^^^^^^^^^ + + + Properties are general directives that apply to the whole TGSI program. + +FS_COORD_ORIGIN +""""""""""""""" + +Specifies the fragment shader TGSI_SEMANTIC_POSITION coordinate origin. +The default value is UPPER_LEFT. + +If UPPER_LEFT, the position will be (0,0) at the upper left corner and +increase downward and rightward. +If LOWER_LEFT, the position will be (0,0) at the lower left corner and +increase upward and rightward. + +OpenGL defaults to LOWER_LEFT, and is configurable with the +GL_ARB_fragment_coord_conventions extension. + +DirectX 9/10 use UPPER_LEFT. + +FS_COORD_PIXEL_CENTER +""""""""""""""""""""" + +Specifies the fragment shader TGSI_SEMANTIC_POSITION pixel center convention. +The default value is HALF_INTEGER. + +If HALF_INTEGER, the fractionary part of the position will be 0.5 +If INTEGER, the fractionary part of the position will be 0.0 + +Note that this does not affect the set of fragments generated by +rasterization, which is instead controlled by gl_rasterization_rules in the +rasterizer. + +OpenGL defaults to HALF_INTEGER, and is configurable with the +GL_ARB_fragment_coord_conventions extension. + +DirectX 9 uses INTEGER. +DirectX 10 uses HALF_INTEGER. + + + +Texture Sampling and Texture Formats +------------------------------------ + +This table shows how texture image components are returned as (x,y,z,w) tuples +by TGSI texture instructions, such as :opcode:`TEX`, :opcode:`TXD`, and +:opcode:`TXP`. For reference, OpenGL and Direct3D conventions are shown as +well. + ++--------------------+--------------+--------------------+--------------+ +| Texture Components | Gallium | OpenGL | Direct3D 9 | ++====================+==============+====================+==============+ +| R | XXX TBD | (r, 0, 0, 1) | (r, 1, 1, 1) | ++--------------------+--------------+--------------------+--------------+ +| RG | XXX TBD | (r, g, 0, 1) | (r, g, 1, 1) | ++--------------------+--------------+--------------------+--------------+ +| RGB | (r, g, b, 1) | (r, g, b, 1) | (r, g, b, 1) | ++--------------------+--------------+--------------------+--------------+ +| RGBA | (r, g, b, a) | (r, g, b, a) | (r, g, b, a) | ++--------------------+--------------+--------------------+--------------+ +| A | (0, 0, 0, a) | (0, 0, 0, a) | (0, 0, 0, a) | ++--------------------+--------------+--------------------+--------------+ +| L | (l, l, l, 1) | (l, l, l, 1) | (l, l, l, 1) | ++--------------------+--------------+--------------------+--------------+ +| LA | (l, l, l, a) | (l, l, l, a) | (l, l, l, a) | ++--------------------+--------------+--------------------+--------------+ +| I | (i, i, i, i) | (i, i, i, i) | N/A | ++--------------------+--------------+--------------------+--------------+ +| UV | XXX TBD | (0, 0, 0, 1) | (u, v, 1, 1) | +| | | [#envmap-bumpmap]_ | | ++--------------------+--------------+--------------------+--------------+ +| Z | XXX TBD | (z, z, z, 1) | (0, z, 0, 1) | +| | | [#depth-tex-mode]_ | | ++--------------------+--------------+--------------------+--------------+ + +.. [#envmap-bumpmap] http://www.opengl.org/registry/specs/ATI/envmap_bumpmap.txt +.. [#depth-tex-mode] the default is (z, z, z, 1) but may also be (0, 0, 0, z) + or (z, z, z, z) depending on the value of GL_DEPTH_TEXTURE_MODE. diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index d5f5c7bbba..7f2b33c2dc 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -36,7 +36,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" - +#include <stdio.h> /** The standard assert macro doesn't seem to work reliably */ #define ASSERT(x) \ @@ -49,7 +49,6 @@ } - #define JOIN(x, y) JOIN_AGAIN(x, y) #define JOIN_AGAIN(x, y) x ## y @@ -358,6 +357,7 @@ struct cell_spu_function_info /** This is the object passed to spe_create_thread() */ +PIPE_ALIGN_TYPE(16, struct cell_init_info { unsigned id; @@ -370,7 +370,7 @@ struct cell_init_info uint *buffer_status; /**< points at cell_context->buffer_status */ struct cell_spu_function_info *spu_functions; -} ALIGN16_ATTRIB; +}); #endif /* CELL_COMMON_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index 3a3f968a49..246fe21054 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -33,7 +33,7 @@ #include <stdio.h> #include <assert.h> #include <stdint.h> -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" #include "cell/common.h" diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index ebb7a7acc4..5bff9869fd 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -36,7 +36,7 @@ #include "pipe/p_defines.h" #include "pipe/p_format.h" #include "util/u_memory.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_screen.h" #include "draw/draw_context.h" @@ -124,7 +124,7 @@ cell_is_buffer_referenced( struct pipe_context *pipe, struct pipe_context * cell_create_context(struct pipe_screen *screen, - struct cell_winsys *cws) + void *priv ) { struct cell_context *cell; uint i; @@ -136,9 +136,10 @@ cell_create_context(struct pipe_screen *screen, memset(cell, 0, sizeof(*cell)); - cell->winsys = cws; + cell->winsys = NULL; /* XXX: fixme - get this from screen? */ cell->pipe.winsys = screen->winsys; cell->pipe.screen = screen; + cell->pipe.priv = priv; cell->pipe.destroy = cell_destroy_context; cell->pipe.clear = cell_clear; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 5c3188e7f9..905cd5db39 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -89,7 +89,7 @@ struct cell_buffer_node; */ struct cell_buffer_list { - struct cell_fence fence ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) struct cell_fence fence; struct cell_buffer_node *head; }; @@ -115,7 +115,7 @@ struct cell_context struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[2]; + struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -150,18 +150,18 @@ struct cell_context /** Mapped constant buffers */ void *mapped_constants[PIPE_SHADER_TYPES]; - struct cell_spu_function_info spu_functions ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) struct cell_spu_function_info spu_functions; uint num_cells, num_spus; /** Buffers for command batches, vertex/index data */ uint buffer_size[CELL_NUM_BUFFERS]; - ubyte buffer[CELL_NUM_BUFFERS][CELL_BUFFER_SIZE] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) ubyte buffer[CELL_NUM_BUFFERS][CELL_BUFFER_SIZE]; int cur_batch; /**< which buffer is being filled w/ commands */ /** [4] to ensure 16-byte alignment for each status word */ - uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BUFFERS][4] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BUFFERS][4]; /** Associated with each command/batch buffer is a list of pipe_buffers @@ -188,8 +188,9 @@ cell_context(struct pipe_context *pipe) } -extern struct pipe_context * -cell_create_context(struct pipe_screen *screen, struct cell_winsys *cws); +struct pipe_context * +cell_create_context(struct pipe_screen *screen, + void *priv ); extern void cell_vertex_shader_queue_flush(struct draw_context *draw); diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 3fa8b975d3..bffd0fac6f 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -33,8 +33,8 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" #include "cell_context.h" #include "cell_draw_arrays.h" @@ -51,17 +51,17 @@ cell_map_constant_buffers(struct cell_context *sp) struct pipe_winsys *ws = sp->pipe.winsys; uint i; for (i = 0; i < 2; i++) { - if (sp->constants[i].buffer && sp->constants[i].buffer->size) { - sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, + if (sp->constants[i] && sp->constants[i]->size) { + sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i], PIPE_BUFFER_USAGE_CPU_READ); cell_flush_buffer_range(sp, sp->mapped_constants[i], - sp->constants[i].buffer->size); + sp->constants[i]->size); } } - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0, sp->mapped_constants[PIPE_SHADER_VERTEX], - sp->constants[PIPE_SHADER_VERTEX].buffer->size); + sp->constants[PIPE_SHADER_VERTEX]->size); } static void @@ -70,8 +70,8 @@ cell_unmap_constant_buffers(struct cell_context *sp) struct pipe_winsys *ws = sp->pipe.winsys; uint i; for (i = 0; i < 2; i++) { - if (sp->constants[i].buffer && sp->constants[i].buffer->size) - ws->buffer_unmap(ws, sp->constants[i].buffer); + if (sp->constants[i] && sp->constants[i]->size) + ws->buffer_unmap(ws, sp->constants[i]); sp->mapped_constants[i] = NULL; } } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index 13125a9fa3..e10071529a 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -27,7 +27,7 @@ #include <unistd.h> #include "util/u_memory.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "cell_context.h" #include "cell_batch.h" #include "cell_fence.h" diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c index 66d4b3b6a3..0dab34075d 100644 --- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c @@ -408,7 +408,7 @@ gen_blend(const struct pipe_blend_state *blend, int one_reg = -1; int constR_reg = -1, constG_reg = -1, constB_reg = -1, constA_reg = -1; - ASSERT(blend->blend_enable); + ASSERT(blend->rt[0].blend_enable); /* packed RGBA -> float colors */ unpack_colors(f, color_format, fbRGBA_reg, @@ -420,7 +420,7 @@ gen_blend(const struct pipe_blend_state *blend, * because in some cases (like PIPE_BLENDFACTOR_ONE and * PIPE_BLENDFACTOR_ZERO) we can avoid doing unnecessary math. */ - switch (blend->rgb_src_factor) { + switch (blend->rt[0].rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: /* factors = (1,1,1), so term = (R,G,B) */ spe_move(f, term1R_reg, fragR_reg); @@ -574,7 +574,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term A*factor, not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->alpha_src_factor) { + switch (blend->rt[0].alpha_src_factor) { case PIPE_BLENDFACTOR_ZERO: /* factor = 0, so term = 0 */ spe_load_float(f, term1A_reg, 0.0f); @@ -648,7 +648,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term (Rfb,Gfb,Bfb)*(factor), not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->rgb_dst_factor) { + switch (blend->rt[0].rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* factors = (1,1,1), so term = (Rfb,Gfb,Bfb) */ spe_move(f, term2R_reg, fbR_reg); @@ -786,7 +786,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term Afb*factor, not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->alpha_dst_factor) { + switch (blend->rt[0].alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* factor = 1, so term = Afb */ spe_move(f, term2A_reg, fbA_reg); @@ -858,7 +858,7 @@ gen_blend(const struct pipe_blend_state *blend, /* * Combine Src/Dest RGB terms as per the blend equation. */ - switch (blend->rgb_func) { + switch (blend->rt[0].rgb_func) { case PIPE_BLEND_ADD: spe_fa(f, fragR_reg, term1R_reg, term2R_reg); spe_fa(f, fragG_reg, term1G_reg, term2G_reg); @@ -891,7 +891,7 @@ gen_blend(const struct pipe_blend_state *blend, /* * Combine Src/Dest A term */ - switch (blend->alpha_func) { + switch (blend->rt[0].alpha_func) { case PIPE_BLEND_ADD: spe_fa(f, fragA_reg, term1A_reg, term2A_reg); break; @@ -2118,7 +2118,7 @@ cell_gen_fragment_function(struct cell_context *cell, spe_comment(f, 0, "Fetch quad colors from tile"); spe_lqx(f, fbRGBA_reg, color_tile_reg, quad_offset_reg); - if (blend->blend_enable) { + if (blend->rt[0].blend_enable) { spe_comment(f, 0, "Perform blending"); gen_blend(blend, blend_color, f, color_format, fragR_reg, fragG_reg, fragB_reg, fragA_reg, fbRGBA_reg); @@ -2143,9 +2143,9 @@ cell_gen_fragment_function(struct cell_context *cell, gen_logicop(blend, f, rgba_reg, fbRGBA_reg); } - if (blend->colormask != PIPE_MASK_RGBA) { + if (blend->rt[0].colormask != PIPE_MASK_RGBA) { spe_comment(f, 0, "Compute color mask"); - gen_colormask(f, blend->colormask, color_format, rgba_reg, fbRGBA_reg); + gen_colormask(f, blend->rt[0].colormask, color_format, rgba_reg, fbRGBA_reg); } /* Mix fragment colors with framebuffer colors using the quad/pixel mask: diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index c18a5d0635..3259c58687 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -31,7 +31,7 @@ */ #include "util/u_memory.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" #include "cell_context.h" #include "cell_flush.h" diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index d185c6b849..7681e3411e 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -28,7 +28,7 @@ #include "util/u_memory.h" #include "util/u_simple_screen.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" @@ -86,6 +86,12 @@ cell_get_param(struct pipe_screen *screen, int param) return 0; /* XXX to do */ case PIPE_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } @@ -168,6 +174,7 @@ cell_create_screen(struct pipe_winsys *winsys) screen->get_param = cell_get_param; screen->get_paramf = cell_get_paramf; screen->is_format_supported = cell_is_format_supported; + screen->context_create = cell_create_context; cell_init_screen_texture_funcs(screen); u_simple_screen_init(screen); diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index b193170f9c..7adedcde57 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -50,7 +50,7 @@ extern void -cell_update_derived( struct cell_context *softpipe ); +cell_update_derived( struct cell_context *cell ); extern void diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 5b87286d4c..282f05ba08 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_math.h" #include "cell_context.h" @@ -240,12 +240,12 @@ cell_emit_state(struct cell_context *cell) if (cell->dirty & (CELL_NEW_FS_CONSTANTS)) { const uint shader = PIPE_SHADER_FRAGMENT; - const uint num_const = cell->constants[shader].buffer->size / sizeof(float); + const uint num_const = cell->constants[shader]->size / sizeof(float); uint i, j; float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float))); uint32_t *ibuf = (uint32_t *) buf; const float *constants = pipe_buffer_map(cell->pipe.screen, - cell->constants[shader].buffer, + cell->constants[shader], PIPE_BUFFER_USAGE_CPU_READ); ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS; ibuf[4] = num_const; @@ -253,7 +253,7 @@ cell_emit_state(struct cell_context *cell) for (i = 0; i < num_const; i++) { buf[j++] = constants[i]; } - pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader].buffer); + pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader]); } if (cell->dirty & (CELL_NEW_FRAMEBUFFER | diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index d97c22b2ef..21af7ed1c3 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -999,23 +999,23 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) /* Does the selected blend mode make use of the source / destination * color (RGB) blend factors? */ - boolean need_color_factor = b->blend_enable - && (b->rgb_func != PIPE_BLEND_MIN) - && (b->rgb_func != PIPE_BLEND_MAX); + boolean need_color_factor = b->rt[0].blend_enable + && (b->rt[0].rgb_func != PIPE_BLEND_MIN) + && (b->rt[0].rgb_func != PIPE_BLEND_MAX); /* Does the selected blend mode make use of the source / destination * alpha blend factors? */ - boolean need_alpha_factor = b->blend_enable - && (b->alpha_func != PIPE_BLEND_MIN) - && (b->alpha_func != PIPE_BLEND_MAX); + boolean need_alpha_factor = b->rt[0].blend_enable + && (b->rt[0].alpha_func != PIPE_BLEND_MIN) + && (b->rt[0].alpha_func != PIPE_BLEND_MAX); - if (b->blend_enable) { - sF[0] = b->rgb_src_factor; + if (b->rt[0].blend_enable) { + sF[0] = b->rt[0].rgb_src_factor; sF[1] = sF[0]; sF[2] = sF[0]; - switch (b->alpha_src_factor & 0x0f) { + switch (b->rt[0].alpha_src_factor & 0x0f) { case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: sF[3] = PIPE_BLENDFACTOR_ONE; break; @@ -1023,30 +1023,30 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_CONST_COLOR: case PIPE_BLENDFACTOR_SRC1_COLOR: - sF[3] = b->alpha_src_factor + 1; + sF[3] = b->rt[0].alpha_src_factor + 1; break; default: - sF[3] = b->alpha_src_factor; + sF[3] = b->rt[0].alpha_src_factor; } - dF[0] = b->rgb_dst_factor; + dF[0] = b->rt[0].rgb_dst_factor; dF[1] = dF[0]; dF[2] = dF[0]; - switch (b->alpha_dst_factor & 0x0f) { + switch (b->rt[0].alpha_dst_factor & 0x0f) { case PIPE_BLENDFACTOR_SRC_COLOR: case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_CONST_COLOR: case PIPE_BLENDFACTOR_SRC1_COLOR: - dF[3] = b->alpha_dst_factor + 1; + dF[3] = b->rt[0].alpha_dst_factor + 1; break; default: - dF[3] = b->alpha_dst_factor; + dF[3] = b->rt[0].alpha_dst_factor; } - func[0] = b->rgb_func; + func[0] = b->rt[0].rgb_func; func[1] = func[0]; func[2] = func[0]; - func[3] = b->alpha_func; + func[3] = b->rt[0].alpha_func; } else { sF[0] = PIPE_BLENDFACTOR_ONE; sF[1] = PIPE_BLENDFACTOR_ONE; @@ -1067,7 +1067,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) /* If alpha writing is enabled and the alpha blend mode requires use of * the alpha factor, calculate the alpha factor. */ - if (((b->colormask & 8) != 0) && need_alpha_factor) { + if (((b->rt[0].colormask & 8) != 0) && need_alpha_factor) { src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3], frag[3], pixel[3]); @@ -1091,8 +1091,8 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) src_factor[2] = dst_factor[3]; } else if (need_color_factor) { emit_color_factor_calculation(f, - b->rgb_src_factor, - b->colormask, + b->rt[0].rgb_src_factor, + b->rt[0].colormask, frag, pixel, const_color, src_factor); } @@ -1111,15 +1111,15 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) dst_factor[2] = src_factor[2]; } else if (need_color_factor) { emit_color_factor_calculation(f, - b->rgb_dst_factor, - b->colormask, + b->rt[0].rgb_dst_factor, + b->rt[0].colormask, frag, pixel, const_color, dst_factor); } for (i = 0; i < 4; ++i) { - if ((b->colormask & (1U << i)) != 0) { + if ((b->rt[0].colormask & (1U << i)) != 0) { emit_blend_calculation(f, func[i], sF[i], dF[i], frag[i], src_factor[i], @@ -1216,7 +1216,7 @@ cell_generate_logic_op(struct spe_function *f, /* Short-circuit the noop and invert cases. */ - if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) { + if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->rt[0].colormask == 0)) { spe_bi(f, 0, 0, 0); return; } else if (logic_op == PIPE_LOGICOP_INVERT) { diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 6568c784fe..9b2f86fdfb 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -27,8 +27,8 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_inlines.h" +#include "util/u_simple_screen.h" #include "draw/draw_context.h" #include "tgsi/tgsi_parse.h" @@ -183,7 +183,7 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs) static void cell_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct cell_context *cell = cell_context(pipe); @@ -193,7 +193,7 @@ cell_set_constant_buffer(struct pipe_context *pipe, draw_flush(cell->draw); /* note: reference counting */ - pipe_buffer_reference(&cell->constants[shader].buffer, buf->buffer); + pipe_buffer_reference(&cell->constants[shader], buf); if (shader == PIPE_SHADER_VERTEX) cell->dirty |= CELL_NEW_VS_CONSTANTS; diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 998944f77a..fad290dfa0 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -33,8 +33,8 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_inlines.h" +#include "util/u_simple_screen.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 403cf6d50f..cf8cd41159 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -31,7 +31,7 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "util/u_math.h" #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/drivers/cell/ppu/cell_winsys.h index ae2af5696b..e227e065ff 100644 --- a/src/gallium/drivers/cell/ppu/cell_winsys.h +++ b/src/gallium/drivers/cell/ppu/cell_winsys.h @@ -38,13 +38,10 @@ */ struct cell_winsys { - uint preferredFormat; + uint dummy; }; -extern struct cell_winsys * -cell_get_winsys(uint format); - #endif diff --git a/src/gallium/drivers/cell/spu/spu_command.c b/src/gallium/drivers/cell/spu/spu_command.c index 12b855a3db..55bd85bde2 100644 --- a/src/gallium/drivers/cell/spu/spu_command.c +++ b/src/gallium/drivers/cell/spu/spu_command.c @@ -53,8 +53,7 @@ struct spu_vs_context draw; /** * Buffers containing dynamically generated SPU code: */ -static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS] - ALIGN16_ATTRIB; +PIPE_ALIGN_VAR(16) static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS]; @@ -543,7 +542,7 @@ cmd_batch(uint opcode) { const uint buf = (opcode >> 8) & 0xff; uint size = (opcode >> 16); - qword buffer[CELL_BUFFER_SIZE / 16] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) qword buffer[CELL_BUFFER_SIZE / 16]; const unsigned usize = ROUNDUP16(size) / sizeof(buffer[0]); uint pos; diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index d86d8e09a5..d2166a4901 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -1839,10 +1839,11 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) /* execute declarations (interpolants) */ if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { for (i = 0; i < mach->NumDeclarations; i++) { + PIPE_ALIGN_VAR(16) union { struct tgsi_full_declaration decl; qword buffer[ROUNDUP16(sizeof(struct tgsi_full_declaration)) / 16]; - } d ALIGN16_ATTRIB; + } d; unsigned ea = (unsigned) (mach->Declarations + pc); spu_dcache_fetch_unaligned(d.buffer, ea, sizeof(d.decl)); @@ -1853,10 +1854,11 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) /* execute instructions, until pc is set to -1 */ while (pc != -1) { + PIPE_ALIGN_VAR(16) union { struct tgsi_full_instruction inst; qword buffer[ROUNDUP16(sizeof(struct tgsi_full_instruction)) / 16]; - } i ALIGN16_ATTRIB; + } i; unsigned ea = (unsigned) (mach->Instructions + pc); spu_dcache_fetch_unaligned(i.buffer, ea, sizeof(i.inst)); diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h index 8605679940..0ca92af248 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.h +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -98,9 +98,9 @@ struct spu_exec_machine * 4 internal temporaries * 1 address */ + PIPE_ALIGN_VAR(16) struct spu_exec_vector Temps[TGSI_EXEC_NUM_TEMPS - + TGSI_EXEC_NUM_TEMP_EXTRAS + 1] - ALIGN16_ATTRIB; + + TGSI_EXEC_NUM_TEMP_EXTRAS + 1]; struct spu_exec_vector *Addrs; diff --git a/src/gallium/drivers/cell/spu/spu_funcs.c b/src/gallium/drivers/cell/spu/spu_funcs.c index ff3d609d25..98919c43ff 100644 --- a/src/gallium/drivers/cell/spu/spu_funcs.c +++ b/src/gallium/drivers/cell/spu/spu_funcs.c @@ -144,7 +144,7 @@ export_func(struct cell_spu_function_info *spu_functions, void return_function_info(void) { - struct cell_spu_function_info funcs ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) struct cell_spu_function_info funcs; int tag = TAG_MISC; ASSERT(sizeof(funcs) == 256); /* must be multiple of 16 bytes */ diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 33767e7c51..a9d72f84d5 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -93,50 +93,64 @@ typedef vector unsigned int (*spu_fragment_program_func)(vector float *inputs, vector float *constants); +PIPE_ALIGN_TYPE(16, struct spu_framebuffer { void *color_start; /**< addr of color surface in main memory */ void *depth_start; /**< addr of depth surface in main memory */ enum pipe_format color_format; enum pipe_format depth_format; - uint width, height; /**< size in pixels */ - uint width_tiles, height_tiles; /**< width and height in tiles */ + uint width; /**< width in pixels */ + uint height; /**< height in pixels */ + uint width_tiles; /**< width in tiles */ + uint height_tiles; /**< width in tiles */ uint color_clear_value; uint depth_clear_value; uint zsize; /**< 0, 2 or 4 bytes per Z */ float zscale; /**< 65535.0, 2^24-1 or 2^32-1 */ -} ALIGN16_ATTRIB; +}); /** per-texture level info */ +PIPE_ALIGN_TYPE(16, struct spu_texture_level { void *start; - ushort width, height, depth; + ushort width; + ushort height; + ushort depth; ushort tiles_per_row; uint bytes_per_image; /** texcoord scale factors */ - vector float scale_s, scale_t, scale_r; + vector float scale_s; + vector float scale_t; + vector float scale_r; /** texcoord masks (if REPEAT then size-1, else ~0) */ - vector signed int mask_s, mask_t, mask_r; + vector signed int mask_s; + vector signed int mask_t; + vector signed int mask_r; /** texcoord clamp limits */ - vector signed int max_s, max_t, max_r; -} ALIGN16_ATTRIB; + vector signed int max_s; + vector signed int max_t; + vector signed int max_r; +}); +PIPE_ALIGN_TYPE(16, struct spu_texture { struct spu_texture_level level[CELL_MAX_TEXTURE_LEVELS]; uint max_level; uint target; /**< PIPE_TEXTURE_x */ -} ALIGN16_ATTRIB; +}); /** * All SPU global/context state will be in a singleton object of this type: */ +PIPE_ALIGN_TYPE(16, struct spu_global { /** One-time init/constant info */ @@ -155,18 +169,19 @@ struct spu_global struct vertex_info vertex_info; /** Current color and Z tiles */ - tile_t ctile ALIGN16_ATTRIB; - tile_t ztile ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) tile_t ctile; + PIPE_ALIGN_VAR(16) tile_t ztile; /** Read depth/stencil tiles? */ boolean read_depth_stencil; /** Current tiles' status */ - ubyte cur_ctile_status, cur_ztile_status; + ubyte cur_ctile_status; + ubyte cur_ztile_status; /** Status of all tiles in framebuffer */ - ubyte ctile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; - ubyte ztile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) ubyte ctile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE]; + PIPE_ALIGN_VAR(16) ubyte ztile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE]; /** Current fragment ops machine code, at 8-byte boundary */ uint *fragment_ops_code; @@ -175,7 +190,7 @@ struct spu_global spu_fragment_ops_func fragment_ops[2]; /** Current fragment program machine code, at 8-byte boundary */ - uint fragment_program_code[SPU_MAX_FRAGMENT_PROGRAM_INSTS] ALIGN8_ATTRIB; + PIPE_ALIGN_VAR(8) uint fragment_program_code[SPU_MAX_FRAGMENT_PROGRAM_INSTS]; /** Current fragment ops function */ spu_fragment_program_func fragment_program; @@ -187,7 +202,7 @@ struct spu_global /** Fragment program constants */ vector float constants[4 * CELL_MAX_CONSTANTS]; -} ALIGN16_ATTRIB; +}); extern struct spu_global spu; diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c index eba9f95cf1..5328374080 100644 --- a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c +++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c @@ -207,9 +207,9 @@ spu_fallback_fragment_ops(uint x, uint y, * If we'll need the current framebuffer/tile colors for blending * or logicop or colormask, fetch them now. */ - if (spu.blend.blend_enable || + if (spu.blend.rt[0].blend_enable || spu.blend.logicop_enable || - spu.blend.colormask != 0xf) { + spu.blend.rt[0].colormask != 0xf) { #if LINEAR_QUAD_LAYOUT /* See comments/diagram below */ fbc0 = colorTile->ui[y][x*2+0]; @@ -228,7 +228,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Do blending */ - if (spu.blend.blend_enable) { + if (spu.blend.rt[0].blend_enable) { /* blending terms, misc regs */ vector float term1r, term1g, term1b, term1a; vector float term2r, term2g, term2b, term2a; @@ -261,7 +261,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Compute Src RGB terms (fragment color * factor) */ - switch (spu.blend.rgb_src_factor) { + switch (spu.blend.rt[0].rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: term1r = fragR; term1g = fragG; @@ -310,7 +310,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Compute Src Alpha term (fragment alpha * factor) */ - switch (spu.blend.alpha_src_factor) { + switch (spu.blend.rt[0].alpha_src_factor) { case PIPE_BLENDFACTOR_ONE: term1a = fragA; break; @@ -338,7 +338,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Compute Dest RGB terms (framebuffer color * factor) */ - switch (spu.blend.rgb_dst_factor) { + switch (spu.blend.rt[0].rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: term2r = fbRGBA[0]; term2g = fbRGBA[1]; @@ -394,7 +394,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Compute Dest Alpha term (framebuffer alpha * factor) */ - switch (spu.blend.alpha_dst_factor) { + switch (spu.blend.rt[0].alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: term2a = fbRGBA[3]; break; @@ -427,7 +427,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Combine Src/Dest RGB terms */ - switch (spu.blend.rgb_func) { + switch (spu.blend.rt[0].rgb_func) { case PIPE_BLEND_ADD: fragR = spu_add(term1r, term2r); fragG = spu_add(term1g, term2g); @@ -460,7 +460,7 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Combine Src/Dest A term */ - switch (spu.blend.alpha_func) { + switch (spu.blend.rt[0].alpha_func) { case PIPE_BLEND_ADD: fragA = spu_add(term1a, term2a); break; @@ -527,29 +527,29 @@ spu_fallback_fragment_ops(uint x, uint y, /* * Do color masking */ - if (spu.blend.colormask != 0xf) { + if (spu.blend.rt[0].colormask != 0xf) { uint cmask = 0x0; /* each byte corresponds to a color channel */ /* Form bitmask depending on color buffer format and colormask bits */ switch (spu.fb.color_format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - if (spu.blend.colormask & PIPE_MASK_R) + if (spu.blend.rt[0].colormask & PIPE_MASK_R) cmask |= 0x00ff0000; /* red */ - if (spu.blend.colormask & PIPE_MASK_G) + if (spu.blend.rt[0].colormask & PIPE_MASK_G) cmask |= 0x0000ff00; /* green */ - if (spu.blend.colormask & PIPE_MASK_B) + if (spu.blend.rt[0].colormask & PIPE_MASK_B) cmask |= 0x000000ff; /* blue */ - if (spu.blend.colormask & PIPE_MASK_A) + if (spu.blend.rt[0].colormask & PIPE_MASK_A) cmask |= 0xff000000; /* alpha */ break; case PIPE_FORMAT_B8G8R8A8_UNORM: - if (spu.blend.colormask & PIPE_MASK_R) + if (spu.blend.rt[0].colormask & PIPE_MASK_R) cmask |= 0x0000ff00; /* red */ - if (spu.blend.colormask & PIPE_MASK_G) + if (spu.blend.rt[0].colormask & PIPE_MASK_G) cmask |= 0x00ff0000; /* green */ - if (spu.blend.colormask & PIPE_MASK_B) + if (spu.blend.rt[0].colormask & PIPE_MASK_B) cmask |= 0xff000000; /* blue */ - if (spu.blend.colormask & PIPE_MASK_A) + if (spu.blend.rt[0].colormask & PIPE_MASK_A) cmask |= 0x000000ff; /* alpha */ break; default: diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c index 5ffb7073ab..14987e3c3a 100644 --- a/src/gallium/drivers/cell/spu/spu_render.c +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -169,7 +169,7 @@ void cmd_render(const struct cell_command_render *render, uint *pos_incr) { /* we'll DMA into these buffers */ - ubyte vertex_data[CELL_BUFFER_SIZE] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) ubyte vertex_data[CELL_BUFFER_SIZE]; const uint vertex_size = render->vertex_size; /* in bytes */ /*const*/ uint total_vertex_bytes = render->num_verts * vertex_size; uint index_bytes; diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index 03375d84a5..087963960d 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -43,7 +43,8 @@ typedef void (*spu_fetch_func)(qword *out, const qword *in, const qword *shuffle_data); -static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = { +PIPE_ALIGN_VAR(16) static const qword +fetch_shuffle_data[5] = { /* Shuffle used by CVT_64_FLOAT */ { @@ -110,7 +111,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, unsigned idx; const unsigned bytes_per_entry = draw->vertex_fetch.size[attr]; const unsigned quads_per_entry = (bytes_per_entry + 15) / 16; - qword in[2 * 4] ALIGN16_ATTRIB; + PIPE_ALIGN_VAR(16) qword in[2 * 4]; /* Fetch four attributes for four vertices. diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index fbe5b34d39..3e9804bf8e 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -107,8 +107,8 @@ run_vertex_program(struct spu_vs_context *draw, struct spu_exec_machine *machine = &draw->machine; unsigned int j; - ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_MAX_ATTRIBS); + PIPE_ALIGN_VAR(16) struct spu_exec_vector inputs[PIPE_MAX_ATTRIBS]; + PIPE_ALIGN_VAR(16) struct spu_exec_vector outputs[PIPE_MAX_ATTRIBS]; const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; @@ -119,8 +119,8 @@ run_vertex_program(struct spu_vs_context *draw, ASSERT_ALIGN16(draw->constants); machine->Consts = (float (*)[4]) draw->constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); + machine->Inputs = inputs; + machine->Outputs = outputs; spu_vertex_fetch( draw, machine, elts, count ); @@ -132,8 +132,9 @@ run_vertex_program(struct spu_vs_context *draw, for (j = 0; j < count; j++) { unsigned slot; float x, y, z, w; + PIPE_ALIGN_VAR(16) unsigned char buffer[sizeof(struct vertex_header) - + MAX_VERTEX_SIZE] ALIGN16_ATTRIB; + + MAX_VERTEX_SIZE]; struct vertex_header *const tmpOut = (struct vertex_header *) buffer; const unsigned vert_size = ROUNDUP16(sizeof(struct vertex_header) @@ -186,8 +187,8 @@ run_vertex_program(struct spu_vs_context *draw, } -unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32] - ALIGN16_ATTRIB; +PIPE_ALIGN_VAR(16) unsigned char +immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]); void diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 46e4338d98..2ccc5d3e60 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -27,7 +27,7 @@ #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "util/u_memory.h" #include "pipe/p_context.h" diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 149393712a..191a44c3df 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -125,7 +125,7 @@ failover_context( struct pipe_context *pipe ) void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf); + struct pipe_buffer *buf); #endif /* FO_CONTEXT_H */ diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 3f5f556032..c189d1d82c 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -28,6 +28,8 @@ /* Authors: Keith Whitwell <keith@tungstengraphics.com> */ +#include "util/u_inlines.h" + #include "fo_context.h" @@ -495,7 +497,7 @@ failover_set_vertex_elements(struct pipe_context *pipe, void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct failover_context *failover = failover_context(pipe); diff --git a/src/gallium/drivers/i915/i915_buffer.c b/src/gallium/drivers/i915/i915_buffer.c index 669964770d..0f76a59e93 100644 --- a/src/gallium/drivers/i915/i915_buffer.c +++ b/src/gallium/drivers/i915/i915_buffer.c @@ -23,6 +23,7 @@ * **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "i915_screen.h" #include "i915_buffer.h" diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index 90530f2826..0d0859f8f3 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -32,7 +32,6 @@ #include "util/u_clear.h" #include "i915_context.h" -#include "i915_state.h" /** diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 89feeade75..3d45a22b7e 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -29,13 +29,10 @@ #include "i915_state.h" #include "i915_screen.h" #include "i915_batch.h" -#include "i915_texture.h" -#include "i915_reg.h" #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "pipe/p_screen.h" @@ -84,7 +81,7 @@ i915_draw_range_elements(struct pipe_context *pipe, } - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915->current.constants[PIPE_SHADER_VERTEX], (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * sizeof(float))); @@ -186,7 +183,7 @@ static void i915_destroy(struct pipe_context *pipe) } struct pipe_context * -i915_create_context(struct pipe_screen *screen) +i915_create_context(struct pipe_screen *screen, void *priv) { struct i915_context *i915; @@ -197,6 +194,7 @@ i915_create_context(struct pipe_screen *screen) i915->iws = i915_screen(screen)->iws; i915->base.winsys = NULL; i915->base.screen = screen; + i915->base.priv = priv; i915->base.destroy = i915_destroy; diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 234b441ce6..1479d2201a 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -167,7 +167,7 @@ struct i915_depth_stencil_state { }; struct i915_rasterizer_state { - int light_twoside : 1; + unsigned light_twoside : 1; unsigned st; enum interp_mode color_interp; @@ -233,7 +233,8 @@ struct i915_context struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + /* XXX unneded */ + struct pipe_buffer *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -333,6 +334,11 @@ void i915_init_flush_functions( struct i915_context *i915 ); void i915_init_string_functions( struct i915_context *i915 ); +/************************************************************************ + * i915_context.c + */ +struct pipe_context *i915_create_context(struct pipe_screen *screen, + void *priv); /*********************************************************************** diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c index c6e6d6fd31..237654d26b 100644 --- a/src/gallium/drivers/i915/i915_debug.c +++ b/src/gallium/drivers/i915/i915_debug.c @@ -29,7 +29,6 @@ #include "i915_context.h" #include "i915_debug.h" #include "i915_batch.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_debug.h" diff --git a/src/gallium/drivers/i915/i915_debug.h b/src/gallium/drivers/i915/i915_debug.h index dd9b86e17b..8f7484797d 100644 --- a/src/gallium/drivers/i915/i915_debug.h +++ b/src/gallium/drivers/i915/i915_debug.h @@ -72,7 +72,7 @@ void i915_print_ureg(const char *msg, unsigned ureg); #if defined(DEBUG) && defined(FILE_DEBUG_FLAG) -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" static INLINE void I915_DBG( diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c index 9c5b117b6d..066e7392d1 100644 --- a/src/gallium/drivers/i915/i915_debug_fp.c +++ b/src/gallium/drivers/i915/i915_debug_fp.c @@ -28,8 +28,8 @@ #include "i915_reg.h" #include "i915_debug.h" -#include "pipe/internal/p_winsys_screen.h" -#include "util/u_memory.h" +#include "util/u_simple_screen.h" +#include "util/u_debug.h" static void diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c index 6b832140a8..cad4109ee6 100644 --- a/src/gallium/drivers/i915/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915/i915_prim_vbuf.c @@ -41,7 +41,7 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "util/u_debug.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_fifo.h" diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index d4ee8f5339..c450854c98 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -117,6 +117,12 @@ i915_get_param(struct pipe_screen *screen, int param) return 8; /* max 128x128x128 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 11; /* max 1024x1024 */ + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } @@ -288,6 +294,8 @@ i915_create_screen(struct intel_winsys *iws, uint pci_id) is->base.get_paramf = i915_get_paramf; is->base.is_format_supported = i915_is_format_supported; + is->base.context_create = i915_create_context; + is->base.fence_reference = i915_fence_reference; is->base.fence_signalled = i915_fence_signalled; is->base.fence_finish = i915_fence_finish; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 5f5b6f8e18..beb26e996a 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -30,15 +30,13 @@ #include "draw/draw_context.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "i915_context.h" #include "i915_reg.h" -#include "i915_state.h" #include "i915_state_inlines.h" #include "i915_fpc.h" @@ -105,13 +103,13 @@ i915_create_blend_state(struct pipe_context *pipe, struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state ); { - unsigned eqRGB = blend->rgb_func; - unsigned srcRGB = blend->rgb_src_factor; - unsigned dstRGB = blend->rgb_dst_factor; + unsigned eqRGB = blend->rt[0].rgb_func; + unsigned srcRGB = blend->rt[0].rgb_src_factor; + unsigned dstRGB = blend->rt[0].rgb_dst_factor; - unsigned eqA = blend->alpha_func; - unsigned srcA = blend->alpha_src_factor; - unsigned dstA = blend->alpha_dst_factor; + unsigned eqA = blend->rt[0].alpha_func; + unsigned srcA = blend->rt[0].alpha_src_factor; + unsigned dstA = blend->rt[0].alpha_dst_factor; /* Special handling for MIN/MAX filter modes handled at * state_tracker level. @@ -148,22 +146,22 @@ i915_create_blend_state(struct pipe_context *pipe, if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; - if ((blend->colormask & PIPE_MASK_R) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; - if ((blend->colormask & PIPE_MASK_G) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_G) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; - if ((blend->colormask & PIPE_MASK_B) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_B) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; - if ((blend->colormask & PIPE_MASK_A) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_A) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; - if (blend->blend_enable) { - unsigned funcRGB = blend->rgb_func; - unsigned srcRGB = blend->rgb_src_factor; - unsigned dstRGB = blend->rgb_dst_factor; + if (blend->rt[0].blend_enable) { + unsigned funcRGB = blend->rt[0].rgb_func; + unsigned srcRGB = blend->rt[0].rgb_src_factor; + unsigned dstRGB = blend->rt[0].rgb_dst_factor; cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE | SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | @@ -518,7 +516,7 @@ static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) static void i915_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct i915_context *i915 = i915_context(pipe); struct pipe_screen *screen = pipe->screen; @@ -538,13 +536,13 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, */ if (buf) { void *mapped; - if (buf->buffer && buf->buffer->size && - (mapped = pipe_buffer_map(screen, buf->buffer, + if (buf->size && + (mapped = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_READ))) { - memcpy(i915->current.constants[shader], mapped, buf->buffer->size); - pipe_buffer_unmap(screen, buf->buffer); + memcpy(i915->current.constants[shader], mapped, buf->size); + pipe_buffer_unmap(screen, buf); i915->current.num_user_constants[shader] - = buf->buffer->size / (4 * sizeof(float)); + = buf->size / (4 * sizeof(float)); } else { i915->current.num_user_constants[shader] = 0; diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index 03dd5091a6..f5b0e9f011 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -33,7 +33,6 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "i915_fpc.h" diff --git a/src/gallium/drivers/i915/i915_state_inlines.h b/src/gallium/drivers/i915/i915_state_inlines.h index 378de8f9c4..b589117fbf 100644 --- a/src/gallium/drivers/i915/i915_state_inlines.h +++ b/src/gallium/drivers/i915/i915_state_inlines.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" +#include "util/u_debug.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index cbac4175c8..e5c6d87215 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -27,7 +27,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "i915_state_inlines.h" #include "i915_context.h" diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index c693eb30e8..1ff6b9f4c6 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -27,14 +27,8 @@ #include "i915_context.h" #include "i915_blit.h" -#include "i915_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_format.h" -#include "util/u_tile.h" -#include "util/u_rect.h" /* Assumes all values are within bounds -- no checking at this level - diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 50a9e19094..e101c8683e 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_texture.c @@ -33,15 +33,13 @@ #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "i915_context.h" #include "i915_texture.h" -#include "i915_debug.h" #include "i915_screen.h" #include "intel_winsys.h" diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/intel_winsys.h index c6bf6e6f7f..b3a802b0e2 100644 --- a/src/gallium/drivers/i915/intel_winsys.h +++ b/src/gallium/drivers/i915/intel_winsys.h @@ -203,10 +203,6 @@ struct intel_winsys { */ struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id); -/** - * Create a i915 pipe_context. - */ -struct pipe_context *i915_create_context(struct pipe_screen *screen); /** * Get the intel_winsys buffer backing the texture. diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 22607dc608..003b1fd5bf 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -155,7 +155,7 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, struct brw_winsys_buffer *buffer, - uint32_t usage, + enum brw_buffer_usage usage, uint32_t delta) { int ret; diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 7473f5bea4..6ca9f617f5 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -64,12 +64,12 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch); * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ -int brw_batchbuffer_data(struct brw_batchbuffer *batch, +enum pipe_error brw_batchbuffer_data(struct brw_batchbuffer *batch, const void *data, GLuint bytes, enum cliprect_mode cliprect_mode); -int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, +enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, struct brw_winsys_buffer *buffer, enum brw_buffer_usage usage, uint32_t offset); diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 3e070f5591..4a543276f5 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -32,7 +32,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" static enum pipe_error prepare_cc_vp( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index d67a1a6263..ccba205e8c 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -38,7 +38,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_state.h" #include "brw_pipe_rast.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_line.c b/src/gallium/drivers/i965/brw_clip_line.c index 54282d975e..66caadc4d5 100644 --- a/src/gallium/drivers/i965/brw_clip_line.c +++ b/src/gallium/drivers/i965/brw_clip_line.c @@ -33,7 +33,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_point.c b/src/gallium/drivers/i965/brw_clip_point.c index e0a5330556..124156c1b5 100644 --- a/src/gallium/drivers/i965/brw_clip_point.c +++ b/src/gallium/drivers/i965/brw_clip_point.c @@ -31,7 +31,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_tri.c b/src/gallium/drivers/i965/brw_clip_tri.c index 4cde7294ea..069524bc14 100644 --- a/src/gallium/drivers/i965/brw_clip_tri.c +++ b/src/gallium/drivers/i965/brw_clip_tri.c @@ -31,7 +31,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" static void release_tmps( struct brw_clip_compile *c ) diff --git a/src/gallium/drivers/i965/brw_clip_util.c b/src/gallium/drivers/i965/brw_clip_util.c index 97a5710310..23e51ee9bc 100644 --- a/src/gallium/drivers/i965/brw_clip_util.c +++ b/src/gallium/drivers/i965/brw_clip_util.c @@ -32,7 +32,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index e67551882d..3dbe2b9130 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -31,10 +31,10 @@ #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "util/u_simple_list.h" #include "brw_context.h" -#include "brw_defines.h" #include "brw_draw.h" #include "brw_state.h" #include "brw_batchbuffer.h" @@ -102,7 +102,8 @@ static void brw_destroy_context( struct pipe_context *pipe ) } -struct pipe_context *brw_create_context(struct pipe_screen *screen) +struct pipe_context *brw_create_context(struct pipe_screen *screen, + void *priv) { struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context); @@ -112,6 +113,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen) } brw->base.screen = screen; + brw->base.priv = priv; brw->base.destroy = brw_destroy_context; brw->sws = brw_screen(screen)->sws; brw->chipset = brw_screen(screen)->chipset; diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 8c006bb95b..19fda423de 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -837,6 +837,10 @@ int brw_upload_urb_fence(struct brw_context *brw); */ int brw_upload_cs_urb_state(struct brw_context *brw); +/* brw_context.c + */ +struct pipe_context *brw_create_context(struct pipe_screen *screen, + void *priv); /*====================================================================== * Inline conversion functions. These are better-typed than the diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index 3f031577d5..4b215a001c 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -36,9 +36,7 @@ #include "brw_context.h" #include "brw_defines.h" #include "brw_state.h" -#include "brw_util.h" #include "brw_debug.h" -#include "brw_screen.h" /** diff --git a/src/gallium/drivers/i965/brw_disasm.c b/src/gallium/drivers/i965/brw_disasm.c index 65db27248b..9c2ccfff65 100644 --- a/src/gallium/drivers/i965/brw_disasm.c +++ b/src/gallium/drivers/i965/brw_disasm.c @@ -366,6 +366,7 @@ static int format (FILE *f, char *format, ...) va_start (args, format); vsnprintf (buf, sizeof (buf) - 1, format, args); + va_end (args); string (f, buf); return 0; } diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index ea8d39adaf..9bad61ef72 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -26,6 +26,7 @@ **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_prim.h" #include "util/u_upload_mgr.h" @@ -34,7 +35,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_debug.h" -#include "brw_screen.h" #include "brw_batchbuffer.h" diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index a27da5f1c1..d59261557b 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c index 921b201bae..06826635a8 100644 --- a/src/gallium/drivers/i965/brw_gs.c +++ b/src/gallium/drivers/i965/brw_gs.c @@ -34,7 +34,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_state.h" #include "brw_gs.h" diff --git a/src/gallium/drivers/i965/brw_gs_emit.c b/src/gallium/drivers/i965/brw_gs_emit.c index fd8e2acced..9b58773b3b 100644 --- a/src/gallium/drivers/i965/brw_gs_emit.c +++ b/src/gallium/drivers/i965/brw_gs_emit.c @@ -35,7 +35,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_gs.h" static void brw_gs_alloc_regs( struct brw_gs_compile *c, diff --git a/src/gallium/drivers/i965/brw_pipe_blend.c b/src/gallium/drivers/i965/brw_pipe_blend.c index b759a910b6..21f786f871 100644 --- a/src/gallium/drivers/i965/brw_pipe_blend.c +++ b/src/gallium/drivers/i965/brw_pipe_blend.c @@ -118,14 +118,14 @@ static void *brw_create_blend_state( struct pipe_context *pipe, blend->cc2.logicop_enable = 1; blend->cc5.logicop_func = translate_logicop(templ->logicop_func); } - else if (templ->blend_enable) { - blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor); - blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor); - blend->cc6.blend_function = translate_blend_equation(templ->rgb_func); + else if (templ->rt[0].blend_enable) { + blend->cc6.dest_blend_factor = translate_blend_factor(templ->rt[0].rgb_dst_factor); + blend->cc6.src_blend_factor = translate_blend_factor(templ->rt[0].rgb_src_factor); + blend->cc6.blend_function = translate_blend_equation(templ->rt[0].rgb_func); - blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor); - blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor); - blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func); + blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->rt[0].alpha_dst_factor); + blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->rt[0].alpha_src_factor); + blend->cc5.ia_blend_function = translate_blend_equation(templ->rt[0].alpha_func); blend->cc3.blend_enable = 1; blend->cc3.ia_blend_enable = @@ -146,10 +146,10 @@ static void *brw_create_blend_state( struct pipe_context *pipe, /* Per-surface color mask -- just follow global state: */ - blend->ss0.writedisable_red = (templ->colormask & PIPE_MASK_R) ? 0 : 1; - blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 0 : 1; - blend->ss0.writedisable_blue = (templ->colormask & PIPE_MASK_B) ? 0 : 1; - blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 0 : 1; + blend->ss0.writedisable_red = (templ->rt[0].colormask & PIPE_MASK_R) ? 0 : 1; + blend->ss0.writedisable_green = (templ->rt[0].colormask & PIPE_MASK_G) ? 0 : 1; + blend->ss0.writedisable_blue = (templ->rt[0].colormask & PIPE_MASK_B) ? 0 : 1; + blend->ss0.writedisable_alpha = (templ->rt[0].colormask & PIPE_MASK_A) ? 0 : 1; return (void *)blend; } diff --git a/src/gallium/drivers/i965/brw_pipe_fb.c b/src/gallium/drivers/i965/brw_pipe_fb.c index 5d4e5025f9..a90b7c73f6 100644 --- a/src/gallium/drivers/i965/brw_pipe_fb.c +++ b/src/gallium/drivers/i965/brw_pipe_fb.c @@ -1,9 +1,9 @@ #include "util/u_math.h" #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "brw_context.h" -#include "brw_debug.h" /** * called from intelDrawBuffer() diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index 81712798a5..6aab561004 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -4,10 +4,10 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "brw_context.h" #include "brw_defines.h" -#include "brw_debug.h" diff --git a/src/gallium/drivers/i965/brw_pipe_shader.c b/src/gallium/drivers/i965/brw_pipe_shader.c index bb32d90e33..fe445b9982 100644 --- a/src/gallium/drivers/i965/brw_pipe_shader.c +++ b/src/gallium/drivers/i965/brw_pipe_shader.c @@ -29,13 +29,13 @@ * Keith Whitwell <keith@tungstengraphics.com> */ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" @@ -262,7 +262,7 @@ static void brw_delete_vs_state( struct pipe_context *pipe, void *prog ) static void brw_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct brw_context *brw = brw_context(pipe); @@ -270,13 +270,13 @@ static void brw_set_constant_buffer(struct pipe_context *pipe, if (shader == PIPE_SHADER_FRAGMENT) { pipe_buffer_reference( &brw->curr.fragment_constants, - buf->buffer ); + buf ); brw->state.dirty.mesa |= PIPE_NEW_FRAGMENT_CONSTANTS; } else { pipe_buffer_reference( &brw->curr.vertex_constants, - buf->buffer ); + buf ); brw->state.dirty.mesa |= PIPE_NEW_VERTEX_CONSTANTS; } diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 0ecacac9a3..184cd490e5 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -138,6 +138,9 @@ brw_get_name(struct pipe_screen *screen) case PCI_CHIP_ILM_G: chipset = "ILM_G"; break; + default: + chipset = "unknown"; + break; } util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset); @@ -172,6 +175,12 @@ brw_get_param(struct pipe_screen *screen, int param) return 8; /* max 128x128x128 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 11; /* max 1024x1024 */ + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } @@ -388,6 +397,7 @@ brw_create_screen(struct brw_winsys_screen *sws, uint pci_id) bscreen->base.get_param = brw_get_param; bscreen->base.get_paramf = brw_get_paramf; bscreen->base.is_format_supported = brw_is_format_supported; + bscreen->base.context_create = brw_create_context; bscreen->base.fence_reference = brw_fence_reference; bscreen->base.fence_signalled = brw_fence_signalled; bscreen->base.fence_finish = brw_fence_finish; diff --git a/src/gallium/drivers/i965/brw_screen_buffers.c b/src/gallium/drivers/i965/brw_screen_buffers.c index d8141a3f5b..0b38885f40 100644 --- a/src/gallium/drivers/i965/brw_screen_buffers.c +++ b/src/gallium/drivers/i965/brw_screen_buffers.c @@ -4,7 +4,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "brw_screen.h" #include "brw_winsys.h" diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index fc3102b531..9cceb4dbe5 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -36,7 +36,6 @@ #include "brw_context.h" #include "brw_pipe_rast.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_sf.h" #include "brw_state.h" diff --git a/src/gallium/drivers/i965/brw_sf_emit.c b/src/gallium/drivers/i965/brw_sf_emit.c index 3b85725e36..497634ec9e 100644 --- a/src/gallium/drivers/i965/brw_sf_emit.c +++ b/src/gallium/drivers/i965/brw_sf_emit.c @@ -35,7 +35,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_sf.h" diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c index 16b643ceb2..85c20076fb 100644 --- a/src/gallium/drivers/i965/brw_state_cache.c +++ b/src/gallium/drivers/i965/brw_state_cache.c @@ -59,7 +59,6 @@ #include "brw_debug.h" #include "brw_state.h" -#include "brw_batchbuffer.h" /* XXX: Fixme - have to include these to get the sizes of the prog_key * structs: diff --git a/src/gallium/drivers/i965/brw_util.c b/src/gallium/drivers/i965/brw_util.c index 458058d668..1fd2e29713 100644 --- a/src/gallium/drivers/i965/brw_util.c +++ b/src/gallium/drivers/i965/brw_util.c @@ -30,8 +30,6 @@ */ -#include "brw_util.h" -#include "brw_defines.h" diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c index e3ea5a3a13..ca8ee79550 100644 --- a/src/gallium/drivers/i965/brw_vs.c +++ b/src/gallium/drivers/i965/brw_vs.c @@ -33,9 +33,7 @@ #include "brw_context.h" #include "brw_vs.h" -#include "brw_util.h" #include "brw_state.h" -#include "brw_pipe_rast.h" diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 177a5170d2..004e3cb4e6 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -31,7 +31,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" #include "brw_winsys.h" /* XXX: disabled true constant buffer functionality diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h index a242e31218..c82d00f4a4 100644 --- a/src/gallium/drivers/i965/brw_winsys.h +++ b/src/gallium/drivers/i965/brw_winsys.h @@ -28,7 +28,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" -#include "pipe/p_refcnt.h" +#include "util/u_inlines.h" struct brw_winsys; struct pipe_fence_handle; @@ -256,10 +256,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf) */ struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id); -/** - * Create a brw pipe_context. - */ -struct pipe_context *brw_create_context(struct pipe_screen *screen); /** * Get the brw_winsys buffer backing the texture. diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index fdf820a9aa..5164c90ed6 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -32,7 +32,6 @@ #include "brw_context.h" #include "brw_screen.h" -#include "brw_util.h" #include "brw_wm.h" #include "brw_state.h" #include "brw_debug.h" diff --git a/src/gallium/drivers/i965/brw_wm_fp.c b/src/gallium/drivers/i965/brw_wm_fp.c index 9c5b527f89..9c67759ad0 100644 --- a/src/gallium/drivers/i965/brw_wm_fp.c +++ b/src/gallium/drivers/i965/brw_wm_fp.c @@ -41,7 +41,6 @@ #include "tgsi/tgsi_util.h" #include "brw_wm.h" -#include "brw_util.h" #include "brw_debug.h" diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index f92b8198ed..b01a7f194b 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -34,7 +34,6 @@ #include "brw_batchbuffer.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" #include "brw_screen.h" diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 9f5b4e6323..9955380e1f 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -29,7 +29,6 @@ #include "pipe/p_context.h" #include "util/u_memory.h" -#include "id_public.h" #include "id_context.h" #include "id_objects.h" @@ -404,17 +403,17 @@ static void identity_set_constant_buffer(struct pipe_context *_pipe, uint shader, uint index, - const struct pipe_constant_buffer *_buffer) + struct pipe_buffer *_buffer) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_constant_buffer unwrapped_buffer; - struct pipe_constant_buffer *buffer = NULL; + struct pipe_buffer *unwrapped_buffer; + struct pipe_buffer *buffer = NULL; - /* unwrap the input state */ + /* XXX hmm? unwrap the input state */ if (_buffer) { - unwrapped_buffer.buffer = identity_buffer_unwrap(_buffer->buffer); - buffer = &unwrapped_buffer; + unwrapped_buffer = identity_buffer_unwrap(_buffer); + buffer = unwrapped_buffer; } pipe->set_constant_buffer(pipe, @@ -692,7 +691,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.winsys = NULL; id_pipe->base.screen = _screen; - id_pipe->base.priv = pipe->priv; + id_pipe->base.priv = pipe->priv; /* expose wrapped data */ id_pipe->base.draw = NULL; id_pipe->base.destroy = identity_destroy; diff --git a/src/gallium/drivers/identity/id_context.h b/src/gallium/drivers/identity/id_context.h index 75b73fc7df..6d3c1899d5 100644 --- a/src/gallium/drivers/identity/id_context.h +++ b/src/gallium/drivers/identity/id_context.h @@ -39,6 +39,10 @@ struct identity_context { }; +struct pipe_context * +identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + + static INLINE struct identity_context * identity_context(struct pipe_context *pipe) { diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c index 14f68ac0d0..12b516b445 100644 --- a/src/gallium/drivers/identity/id_drm.c +++ b/src/gallium/drivers/identity/id_drm.c @@ -63,22 +63,6 @@ identity_drm_create_screen(struct drm_api *_api, int fd, return identity_screen_create(screen); } -static struct pipe_context * -identity_drm_create_context(struct drm_api *_api, - struct pipe_screen *_screen) -{ - struct identity_screen *id_screen = identity_screen(_screen); - struct identity_drm_api *id_api = identity_drm_api(_api); - struct pipe_screen *screen = id_screen->screen; - struct drm_api *api = id_api->api; - struct pipe_context *pipe; - - pipe = api->create_context(api, screen); - - pipe = identity_context_create(_screen, pipe); - - return pipe; -} static struct pipe_texture * identity_drm_texture_from_shared_handle(struct drm_api *_api, @@ -159,7 +143,6 @@ identity_drm_create(struct drm_api *api) goto error; id_api->base.create_screen = identity_drm_create_screen; - id_api->base.create_context = identity_drm_create_context; id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle; id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture; id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture; diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c index bc9bc7121d..2b1a60c1bf 100644 --- a/src/gallium/drivers/identity/id_objects.c +++ b/src/gallium/drivers/identity/id_objects.c @@ -25,9 +25,9 @@ * **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_memory.h" -#include "id_public.h" #include "id_screen.h" #include "id_objects.h" diff --git a/src/gallium/drivers/identity/id_public.h b/src/gallium/drivers/identity/id_public.h index 3d2862eaa0..d0d5847c61 100644 --- a/src/gallium/drivers/identity/id_public.h +++ b/src/gallium/drivers/identity/id_public.h @@ -34,7 +34,4 @@ struct pipe_context; struct pipe_screen * identity_screen_create(struct pipe_screen *screen); -struct pipe_context * -identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe); - #endif /* ID_PUBLIC_H */ diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 53eae3ef54..b85492114a 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -32,6 +32,7 @@ #include "id_public.h" #include "id_screen.h" +#include "id_context.h" #include "id_objects.h" @@ -103,6 +104,20 @@ identity_screen_is_format_supported(struct pipe_screen *_screen, geom_flags); } +static struct pipe_context * +identity_screen_context_create(struct pipe_screen *_screen, + void *priv) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_context *result; + + result = screen->context_create(screen, priv); + if (result) + return identity_context_create(_screen, result); + return NULL; +} + static struct pipe_texture * identity_screen_texture_create(struct pipe_screen *_screen, const struct pipe_texture *templat) @@ -478,6 +493,7 @@ identity_screen_create(struct pipe_screen *screen) id_screen->base.get_param = identity_screen_get_param; id_screen->base.get_paramf = identity_screen_get_paramf; id_screen->base.is_format_supported = identity_screen_is_format_supported; + id_screen->base.context_create = identity_screen_context_create; id_screen->base.texture_create = identity_screen_texture_create; id_screen->base.texture_blanket = identity_screen_texture_blanket; id_screen->base.texture_destroy = identity_screen_texture_destroy; diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 7c6e46006b..e880042b71 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -3,42 +3,28 @@ include $(TOP)/configs/current LIBNAME = llvmpipe -CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS +DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS C_SOURCES = \ - lp_bld_alpha.c \ - lp_bld_arit.c \ - lp_bld_blend_aos.c \ - lp_bld_blend_logicop.c \ - lp_bld_blend_soa.c \ - lp_bld_const.c \ - lp_bld_conv.c \ - lp_bld_debug.c \ - lp_bld_depth.c \ - lp_bld_flow.c \ - lp_bld_format_aos.c \ - lp_bld_format_query.c \ - lp_bld_format_soa.c \ - lp_bld_interp.c \ - lp_bld_intr.c \ - lp_bld_logic.c \ - lp_bld_pack.c \ - lp_bld_sample.c \ - lp_bld_sample_soa.c \ - lp_bld_swizzle.c \ - lp_bld_struct.c \ - lp_bld_tgsi_soa.c \ - lp_bld_type.c \ lp_buffer.c \ lp_clear.c \ lp_context.c \ lp_draw_arrays.c \ + lp_fence.c \ lp_flush.c \ lp_jit.c \ - lp_prim_vbuf.c \ - lp_setup.c \ + lp_perf.c \ lp_query.c \ + lp_rast.c \ + lp_rast_tri.c \ + lp_scene.c \ + lp_scene_queue.c \ lp_screen.c \ + lp_setup.c \ + lp_setup_line.c \ + lp_setup_point.c \ + lp_setup_tri.c \ + lp_setup_vbuf.c \ lp_state_blend.c \ lp_state_clip.c \ lp_state_derived.c \ @@ -49,16 +35,32 @@ C_SOURCES = \ lp_state_vertex.c \ lp_state_vs.c \ lp_surface.c \ - lp_tex_cache.c \ lp_tex_sample_llvm.c \ lp_texture.c \ - lp_tile_cache.c \ + lp_tile_surface.c \ lp_tile_soa.c CPP_SOURCES = \ - lp_bld_misc.cpp + include ../../Makefile.template lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxiliary/util/u_format_access.py ../../auxiliary/util/u_format.csv python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@ + + +# to make a .s file to inspect assembly code +.c.s: + $(CC) -S $(INCLUDES) $(DEFINES) $(CFLAGS) $(LIBRARY_DEFINES) $< + + +testprogs := lp_test_format \ + lp_test_blend \ + lp_test_conv + +LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium + +$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a + $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group + +default: $(testprogs) diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 6bb545a501..a39283e5e8 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -21,40 +21,25 @@ env.CodeGenerate( llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ - 'lp_bld_alpha.c', - 'lp_bld_arit.c', - 'lp_bld_blend_aos.c', - 'lp_bld_blend_logicop.c', - 'lp_bld_blend_soa.c', - 'lp_bld_const.c', - 'lp_bld_conv.c', - 'lp_bld_debug.c', - 'lp_bld_depth.c', - 'lp_bld_flow.c', - 'lp_bld_format_aos.c', - 'lp_bld_format_query.c', - 'lp_bld_format_soa.c', - 'lp_bld_interp.c', - 'lp_bld_intr.c', - 'lp_bld_misc.cpp', - 'lp_bld_pack.c', - 'lp_bld_sample.c', - 'lp_bld_sample_soa.c', - 'lp_bld_struct.c', - 'lp_bld_logic.c', - 'lp_bld_swizzle.c', - 'lp_bld_tgsi_soa.c', - 'lp_bld_type.c', 'lp_buffer.c', 'lp_clear.c', 'lp_context.c', 'lp_draw_arrays.c', + 'lp_fence.c', 'lp_flush.c', 'lp_jit.c', - 'lp_prim_vbuf.c', - 'lp_setup.c', + 'lp_perf.c', 'lp_query.c', + 'lp_rast.c', + 'lp_rast_tri.c', + 'lp_scene.c', + 'lp_scene_queue.c', 'lp_screen.c', + 'lp_setup.c', + 'lp_setup_line.c', + 'lp_setup_point.c', + 'lp_setup_tri.c', + 'lp_setup_vbuf.c', 'lp_state_blend.c', 'lp_state_clip.c', 'lp_state_derived.c', @@ -65,29 +50,28 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_vertex.c', 'lp_state_vs.c', 'lp_surface.c', - 'lp_tex_cache.c', 'lp_tex_sample_llvm.c', 'lp_texture.c', - 'lp_tile_cache.c', 'lp_tile_soa.c', ]) -env = env.Clone() +if env['platform'] != 'embedded': + env = env.Clone() -env.Prepend(LIBS = [llvmpipe] + gallium) + env.Prepend(LIBS = [llvmpipe] + gallium) -tests = [ - 'format', - 'blend', - 'conv', -] + tests = [ + 'format', + 'blend', + 'conv', + ] -for test in tests: - target = env.Program( - target = 'lp_test_' + test, - source = ['lp_test_' + test + '.c', 'lp_test_main.c'], - ) - env.InstallProgram(target) + for test in tests: + target = env.Program( + target = 'lp_test_' + test, + source = ['lp_test_' + test + '.c', 'lp_test_main.c'], + ) + env.InstallProgram(target) -Export('llvmpipe') + Export('llvmpipe') diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c index 66f1f8e138..9eda972081 100644 --- a/src/gallium/drivers/llvmpipe/lp_buffer.c +++ b/src/gallium/drivers/llvmpipe/lp_buffer.c @@ -26,12 +26,12 @@ **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_math.h" #include "lp_winsys.h" #include "lp_screen.h" -#include "lp_texture.h" #include "lp_buffer.h" @@ -108,32 +108,6 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen, } -static void -llvmpipe_fence_reference(struct pipe_screen *screen, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -llvmpipe_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -llvmpipe_fence_finish(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - void llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen) { @@ -142,9 +116,4 @@ llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen) screen->buffer_map = llvmpipe_buffer_map; screen->buffer_unmap = llvmpipe_buffer_unmap; screen->buffer_destroy = llvmpipe_buffer_destroy; - - screen->fence_reference = llvmpipe_fence_reference; - screen->fence_signalled = llvmpipe_fence_signalled; - screen->fence_finish = llvmpipe_fence_finish; - } diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c index 08d9f2e273..3e8c410925 100644 --- a/src/gallium/drivers/llvmpipe/lp_clear.c +++ b/src/gallium/drivers/llvmpipe/lp_clear.c @@ -33,12 +33,9 @@ #include "pipe/p_defines.h" -#include "util/u_pack_color.h" #include "lp_clear.h" #include "lp_context.h" -#include "lp_surface.h" -#include "lp_state.h" -#include "lp_tile_cache.h" +#include "lp_setup.h" /** @@ -46,37 +43,16 @@ * No masking, no scissor (clear entire buffer). */ void -llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, - double depth, unsigned stencil) +llvmpipe_clear(struct pipe_context *pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - union util_color uc; - unsigned cv; - uint i; if (llvmpipe->no_rast) return; -#if 0 - llvmpipe_update_derived(llvmpipe); /* not needed?? */ -#endif - - if (buffers & PIPE_CLEAR_COLOR) { - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { - struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i]; - - util_pack_color(rgba, ps->format, &uc); - lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, uc.ui); - } - llvmpipe->dirty_render_cache = TRUE; - } - - if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { - struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf; - - cv = util_pack_z_stencil(ps->format, depth, stencil); - - /* non-cached surface */ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); - } + lp_setup_clear( llvmpipe->setup, rgba, depth, stencil, buffers ); } diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 1cc3c9227c..43d610631d 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -33,70 +33,22 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "pipe/p_defines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "lp_clear.h" #include "lp_context.h" #include "lp_flush.h" -#include "lp_prim_vbuf.h" +#include "lp_perf.h" #include "lp_state.h" #include "lp_surface.h" -#include "lp_tile_cache.h" -#include "lp_tex_cache.h" #include "lp_texture.h" #include "lp_winsys.h" #include "lp_query.h" +#include "lp_setup.h" -/** - * Map any drawing surfaces which aren't already mapped - */ -void -llvmpipe_map_transfers(struct llvmpipe_context *lp) -{ - struct pipe_screen *screen = lp->pipe.screen; - struct pipe_surface *zsbuf = lp->framebuffer.zsbuf; - unsigned i; - - for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { - lp_tile_cache_map_transfers(lp->cbuf_cache[i]); - } - - if(zsbuf) { - if(!lp->zsbuf_transfer) - lp->zsbuf_transfer = screen->get_tex_transfer(screen, zsbuf->texture, - zsbuf->face, zsbuf->level, zsbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, zsbuf->width, zsbuf->height); - if(lp->zsbuf_transfer && !lp->zsbuf_map) - lp->zsbuf_map = screen->transfer_map(screen, lp->zsbuf_transfer); - - } -} - - -/** - * Unmap any mapped drawing surfaces - */ -void -llvmpipe_unmap_transfers(struct llvmpipe_context *lp) -{ - uint i; - - for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { - lp_tile_cache_unmap_transfers(lp->cbuf_cache[i]); - } - - if(lp->zsbuf_transfer) { - struct pipe_screen *screen = lp->pipe.screen; - - if(lp->zsbuf_map) { - screen->transfer_unmap(screen, lp->zsbuf_transfer); - lp->zsbuf_map = NULL; - } - } -} static void llvmpipe_destroy( struct pipe_context *pipe ) @@ -104,28 +56,30 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); uint i; + lp_print_counters(); + + /* This will also destroy llvmpipe->setup: + */ if (llvmpipe->draw) draw_destroy( llvmpipe->draw ); for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]); pipe_surface_reference(&llvmpipe->framebuffer.cbufs[i], NULL); } + pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - lp_destroy_tex_tile_cache(llvmpipe->tex_cache[i]); pipe_texture_reference(&llvmpipe->texture[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - lp_destroy_tex_tile_cache(llvmpipe->vertex_tex_cache[i]); pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL); } for (i = 0; i < Elements(llvmpipe->constants); i++) { - if (llvmpipe->constants[i].buffer) { - pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL); + if (llvmpipe->constants[i]) { + pipe_buffer_reference(&llvmpipe->constants[i], NULL); } } @@ -138,33 +92,8 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe, unsigned face, unsigned level) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - unsigned i; - - /* check if any of the bound drawing surfaces are this texture */ - if(llvmpipe->dirty_render_cache) { - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { - if(llvmpipe->framebuffer.cbufs[i] && - llvmpipe->framebuffer.cbufs[i]->texture == texture) - return PIPE_REFERENCED_FOR_WRITE; - } - if(llvmpipe->framebuffer.zsbuf && - llvmpipe->framebuffer.zsbuf->texture == texture) - return PIPE_REFERENCED_FOR_WRITE; - } - /* check if any of the tex_cache textures are this texture */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (llvmpipe->tex_cache[i] && - llvmpipe->tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; - } - for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - if (llvmpipe->vertex_tex_cache[i] && - llvmpipe->vertex_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; - } - - return PIPE_UNREFERENCED; + return lp_setup_is_texture_referenced(llvmpipe->setup, texture); } static unsigned int @@ -175,10 +104,9 @@ llvmpipe_is_buffer_referenced( struct pipe_context *pipe, } struct pipe_context * -llvmpipe_create( struct pipe_screen *screen ) +llvmpipe_create_context( struct pipe_screen *screen, void *priv ) { struct llvmpipe_context *llvmpipe; - uint i; llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16); if (!llvmpipe) @@ -190,6 +118,7 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe->pipe.winsys = screen->winsys; llvmpipe->pipe.screen = screen; + llvmpipe->pipe.priv = priv; llvmpipe->pipe.destroy = llvmpipe_destroy; /* state setters */ @@ -242,19 +171,6 @@ llvmpipe_create( struct pipe_screen *screen ) llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced; llvmpipe_init_query_funcs( llvmpipe ); - llvmpipe_init_texture_funcs( llvmpipe ); - - /* - * Alloc caches for accessing drawing surfaces and textures. - */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - llvmpipe->cbuf_cache[i] = lp_create_tile_cache( screen ); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen ); - for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) - llvmpipe->vertex_tex_cache[i] = lp_create_tex_tile_cache(screen); - /* * Create drawing context and plug our rendering stage into it. @@ -268,19 +184,11 @@ llvmpipe_create( struct pipe_screen *screen ) if (debug_get_bool_option( "LP_NO_RAST", FALSE )) llvmpipe->no_rast = TRUE; - llvmpipe->vbuf_backend = lp_create_vbuf_backend(llvmpipe); - if (!llvmpipe->vbuf_backend) - goto fail; - - llvmpipe->vbuf = draw_vbuf_stage(llvmpipe->draw, llvmpipe->vbuf_backend); - if (!llvmpipe->vbuf) + llvmpipe->setup = lp_setup_create( screen, + llvmpipe->draw ); + if (!llvmpipe->setup) goto fail; - draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->vbuf); - draw_set_render(llvmpipe->draw, llvmpipe->vbuf_backend); - - - /* plug in AA line/point stages */ draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe); draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe); @@ -292,6 +200,8 @@ llvmpipe_create( struct pipe_screen *screen ) lp_init_surface_functions(llvmpipe); + lp_reset_counters(); + return &llvmpipe->pipe; fail: diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 6411797cf5..3bde485ac0 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -42,12 +42,10 @@ struct llvmpipe_vbuf_render; struct draw_context; struct draw_stage; -struct llvmpipe_tile_cache; -struct llvmpipe_tex_tile_cache; struct lp_fragment_shader; struct lp_vertex_shader; struct lp_blend_state; - +struct setup_context; struct llvmpipe_context { struct pipe_context pipe; /**< base class */ @@ -62,9 +60,9 @@ struct llvmpipe_context { const struct lp_vertex_shader *vs; /** Other rendering state */ - struct pipe_blend_color blend_color[4][16]; + struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_buffer *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -94,52 +92,26 @@ struct llvmpipe_context { /** Vertex format */ struct vertex_info vertex_info; - struct vertex_info vertex_info_vbuf; /** Which vertex shader output slot contains point size */ int psize_slot; - /* The reduced version of the primitive supplied by the state - * tracker. - */ - unsigned reduced_api_prim; - - /* The reduced primitive after unfilled triangles, wide-line - * decomposition, etc, are taken into account. This is the - * primitive actually rasterized. - */ - unsigned reduced_prim; - - /** Derived from scissor and surface bounds: */ - struct pipe_scissor_state cliprect; - - unsigned line_stipple_counter; + /** The tiling engine */ + struct setup_context *setup; /** The primitive drawing context */ struct draw_context *draw; - /** Draw module backend */ - struct vbuf_render *vbuf_backend; - struct draw_stage *vbuf; - - boolean dirty_render_cache; - - struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; - - /* TODO: we shouldn't be using external interfaces internally like this */ - struct pipe_transfer *zsbuf_transfer; - uint8_t *zsbuf_map; - unsigned tex_timestamp; - struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; - struct llvmpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS]; + boolean no_rast; - unsigned no_rast : 1; - - struct lp_jit_context jit_context; }; +struct pipe_context * +llvmpipe_create_context( struct pipe_screen *screen, void *priv ); + + static INLINE struct llvmpipe_context * llvmpipe_context( struct pipe_context *pipe ) { diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h index 74b2757494..ee81814361 100644 --- a/src/gallium/drivers/llvmpipe/lp_debug.h +++ b/src/gallium/drivers/llvmpipe/lp_debug.h @@ -45,6 +45,11 @@ st_print_current(void); #define DEBUG_QUERY 0x40 #define DEBUG_SCREEN 0x80 #define DEBUG_JIT 0x100 +#define DEBUG_SHOW_TILES 0x200 +#define DEBUG_SHOW_SUBTILES 0x400 +#define DEBUG_COUNTERS 0x800 +#define DEBUG_NO_LLVM_OPT 0x1000 + #ifdef DEBUG extern int LP_DEBUG; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index c152b4413f..3dd68d5794 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -33,8 +33,6 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" #include "util/u_prim.h" #include "lp_buffer.h" @@ -70,13 +68,9 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, struct draw_context *draw = lp->draw; unsigned i; - lp->reduced_api_prim = u_reduced_prim(mode); - if (lp->dirty) llvmpipe_update_derived( lp ); - llvmpipe_map_transfers(lp); - /* * Map vertex buffers */ @@ -118,10 +112,6 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, * internally when this condition is seen?) */ draw_flush(draw); - - /* Note: leave drawing surfaces mapped */ - - lp->dirty_render_cache = TRUE; } diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c new file mode 100644 index 0000000000..525c117f31 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fence.c @@ -0,0 +1,110 @@ +/************************************************************************** + * + * 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 VMWARE 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 "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "lp_fence.h" + + +struct lp_fence * +lp_fence_create(unsigned rank) +{ + struct lp_fence *fence = CALLOC_STRUCT(lp_fence); + + pipe_reference_init(&fence->reference, 1); + + pipe_mutex_init(fence->mutex); + pipe_condvar_init(fence->signalled); + + fence->rank = rank; + + return fence; +} + + +static void +lp_fence_destroy(struct lp_fence *fence) +{ + pipe_mutex_destroy(fence->mutex); + pipe_condvar_destroy(fence->signalled); + FREE(fence); +} + + +static void +llvmpipe_fence_reference(struct pipe_screen *screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct lp_fence *old = (struct lp_fence *) *ptr; + struct lp_fence *f = (struct lp_fence *) fence; + + if (pipe_reference(&old->reference, &f->reference)) { + lp_fence_destroy(old); + } +} + + +static int +llvmpipe_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct lp_fence *f = (struct lp_fence *) fence; + + return f->count == f->rank; +} + + +static int +llvmpipe_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence_handle, + unsigned flag) +{ + struct lp_fence *fence = (struct lp_fence *) fence_handle; + + pipe_mutex_lock(fence->mutex); + while (fence->count < fence->rank) { + pipe_condvar_wait(fence->signalled, fence->mutex); + } + pipe_mutex_unlock(fence->mutex); + + return 0; +} + + + + +void +llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen) +{ + screen->fence_reference = llvmpipe_fence_reference; + screen->fence_signalled = llvmpipe_fence_signalled; + screen->fence_finish = llvmpipe_fence_finish; +} diff --git a/src/gallium/drivers/llvmpipe/lp_fence.h b/src/gallium/drivers/llvmpipe/lp_fence.h new file mode 100644 index 0000000000..c90e6de423 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fence.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + + +#ifndef LP_FENCE_H +#define LP_FENCE_H + + +#include "os/os_thread.h" +#include "pipe/p_state.h" + + +struct pipe_screen; + + +struct lp_fence +{ + struct pipe_reference reference; + + pipe_mutex mutex; + pipe_condvar signalled; + + unsigned rank; + unsigned count; +}; + + +struct lp_fence * +lp_fence_create(unsigned rank); + + +void +llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen); + + +#endif /* LP_FENCE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index cd8381fe30..bf832433be 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -34,11 +34,7 @@ #include "draw/draw_context.h" #include "lp_flush.h" #include "lp_context.h" -#include "lp_surface.h" -#include "lp_state.h" -#include "lp_tile_cache.h" -#include "lp_tex_cache.h" -#include "lp_winsys.h" +#include "lp_setup.h" void @@ -47,56 +43,52 @@ llvmpipe_flush( struct pipe_context *pipe, struct pipe_fence_handle **fence ) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - uint i; draw_flush(llvmpipe->draw); - if (flags & PIPE_FLUSH_SWAPBUFFERS) { - /* If this is a swapbuffers, just flush color buffers. - * - * The zbuffer changes are not discarded, but held in the cache - * in the hope that a later clear will wipe them out. - */ - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) - if (llvmpipe->cbuf_cache[i]) { - lp_tile_cache_map_transfers(llvmpipe->cbuf_cache[i]); - lp_flush_tile_cache(llvmpipe->cbuf_cache[i]); - } + if (fence) { + if ((flags & (PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_RENDER_CACHE))) { + /* if we're going to flush the setup/rasterization modules, emit + * a fence. + * XXX this (and the code below) may need fine tuning... + */ + *fence = lp_setup_fence( llvmpipe->setup ); + } + else { + *fence = NULL; + } + } - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * to unmap surfaces when flushing. - */ - llvmpipe_unmap_transfers(llvmpipe); + /* XXX the lp_setup_flush(flags) param is not a bool, and it's ignored + * at this time! + */ + if (flags & PIPE_FLUSH_SWAPBUFFERS) { + lp_setup_flush( llvmpipe->setup, FALSE ); } else if (flags & PIPE_FLUSH_RENDER_CACHE) { - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) - if (llvmpipe->cbuf_cache[i]) { - lp_tile_cache_map_transfers(llvmpipe->cbuf_cache[i]); - lp_flush_tile_cache(llvmpipe->cbuf_cache[i]); - } - - /* FIXME: untile zsbuf! */ - - llvmpipe->dirty_render_cache = FALSE; + lp_setup_flush( llvmpipe->setup, TRUE ); } /* Enable to dump BMPs of the color/depth buffers each frame */ #if 0 - if(flags & PIPE_FLUSH_FRAME) { + if (flags & PIPE_FLUSH_FRAME) { static unsigned frame_no = 1; - static char filename[256]; - util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no); - debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[0]); - util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no); - debug_dump_surface_bmp(filename, llvmpipe->framebuffer.zsbuf); + char filename[256]; + unsigned i; + + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); + debug_dump_surface(filename, llvmpipe->framebuffer.cbufs[i]); + } + + if (0) { + util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); + debug_dump_surface(filename, llvmpipe->framebuffer.zsbuf); + } + ++frame_no; } #endif - - if (fence) - *fence = NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 4ef0783f3e..27b54c5959 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -37,9 +37,10 @@ #include "util/u_memory.h" #include "util/u_cpu_detect.h" +#include "lp_debug.h" #include "lp_screen.h" -#include "lp_bld_intr.h" -#include "lp_bld_misc.h" +#include "gallivm/lp_bld_intr.h" +#include "gallivm/lp_bld_misc.h" #include "lp_jit.h" @@ -79,13 +80,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) /* struct lp_jit_context */ { - LLVMTypeRef elem_types[4]; + LLVMTypeRef elem_types[8]; LLVMTypeRef context_type; elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */ - elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ - elem_types[2] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */ - elem_types[3] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ + elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ elem_types[2] = LLVMFloatType(); /* scissor_xmin */ + elem_types[3] = LLVMFloatType(); /* scissor_ymin */ + elem_types[4] = LLVMFloatType(); /* scissor_xmax */ + elem_types[5] = LLVMFloatType(); /* scissor_ymax */ + elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */ + elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ context_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -93,8 +97,16 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) screen->target, context_type, 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, screen->target, context_type, 1); - LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin, screen->target, context_type, 2); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin, + screen->target, context_type, 3); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax, + screen->target, context_type, 4); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax, + screen->target, context_type, 5); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color, + screen->target, context_type, 6); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures, screen->target, context_type, LP_JIT_CONTEXT_TEXTURES_INDEX); @@ -154,20 +166,23 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) screen->pass = LLVMCreateFunctionPassManager(screen->provider); LLVMAddTargetData(screen->target, screen->pass); - /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, - * but there are more on SVN. */ - /* TODO: Add more passes */ - LLVMAddConstantPropagationPass(screen->pass); - if(util_cpu_caps.has_sse4_1) { - /* FIXME: There is a bug in this pass, whereby the combination of fptosi - * and sitofp (necessary for trunc/floor/ceil/round implementation) - * somehow becomes invalid code. - */ - LLVMAddInstructionCombiningPass(screen->pass); + + if ((LP_DEBUG & DEBUG_NO_LLVM_OPT) == 0) { + /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, + * but there are more on SVN. */ + /* TODO: Add more passes */ + LLVMAddConstantPropagationPass(screen->pass); + if(util_cpu_caps.has_sse4_1) { + /* FIXME: There is a bug in this pass, whereby the combination of fptosi + * and sitofp (necessary for trunc/floor/ceil/round implementation) + * somehow becomes invalid code. + */ + LLVMAddInstructionCombiningPass(screen->pass); + } + LLVMAddPromoteMemoryToRegisterPass(screen->pass); + LLVMAddGVNPass(screen->pass); + LLVMAddCFGSimplificationPass(screen->pass); } - LLVMAddPromoteMemoryToRegisterPass(screen->pass); - LLVMAddGVNPass(screen->pass); - LLVMAddCFGSimplificationPass(screen->pass); lp_jit_init_globals(screen); } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 277b690c02..8df3015d4b 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -36,7 +36,7 @@ #define LP_JIT_H -#include "lp_bld_struct.h" +#include "gallivm/lp_bld_struct.h" #include "pipe/p_state.h" @@ -79,6 +79,9 @@ struct lp_jit_context float alpha_ref_value; + /** floats, not ints */ + float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax; + /* FIXME: store (also?) in floats */ uint8_t *blend_color; @@ -92,25 +95,43 @@ struct lp_jit_context #define lp_jit_context_alpha_ref_value(_builder, _ptr) \ lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value") +#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin") + +#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin") + +#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax") + +#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax") + #define lp_jit_context_blend_color(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 2, "blend_color") + lp_build_struct_get(_builder, _ptr, 6, "blend_color") -#define LP_JIT_CONTEXT_TEXTURES_INDEX 3 +#define LP_JIT_CONTEXT_TEXTURES_INDEX 7 #define lp_jit_context_textures(_builder, _ptr) \ lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures") typedef void -(*lp_jit_frag_func)(struct lp_jit_context *context, +(*lp_jit_frag_func)(const struct lp_jit_context *context, uint32_t x, uint32_t y, const void *a0, const void *dadx, const void *dady, - uint32_t *mask, - void *color, - void *depth); + uint8_t **color, + void *depth, + const int32_t c1, + const int32_t c2, + const int32_t c3, + const int32_t *step1, + const int32_t *step2, + const int32_t *step3); + void lp_jit_screen_cleanup(struct llvmpipe_screen *screen); diff --git a/src/gallium/drivers/llvmpipe/lp_perf.c b/src/gallium/drivers/llvmpipe/lp_perf.c new file mode 100644 index 0000000000..a316597675 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.c @@ -0,0 +1,95 @@ +/************************************************************************** + * + * 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 VMWARE 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 "util/u_debug.h" +#include "lp_debug.h" +#include "lp_perf.h" + + + +struct lp_counters lp_count; + + +void +lp_reset_counters(void) +{ + memset(&lp_count, 0, sizeof(lp_count)); +} + + +void +lp_print_counters(void) +{ + if (LP_DEBUG & DEBUG_COUNTERS) { + unsigned total_64, total_16, total_4; + float p1, p2, p3; + + debug_printf("llvmpipe: nr_triangles: %9u\n", lp_count.nr_tris); + debug_printf("llvmpipe: nr_culled_triangles: %9u\n", lp_count.nr_culled_tris); + + total_64 = (lp_count.nr_empty_64 + + lp_count.nr_fully_covered_64 + + lp_count.nr_partially_covered_64); + + p1 = 100.0 * (float) lp_count.nr_empty_64 / (float) total_64; + p2 = 100.0 * (float) lp_count.nr_fully_covered_64 / (float) total_64; + p3 = 100.0 * (float) lp_count.nr_partially_covered_64 / (float) total_64; + + debug_printf("llvmpipe: nr_empty_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_64, p1, total_64); + debug_printf("llvmpipe: nr_fully_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_64, p2, total_64); + debug_printf("llvmpipe: nr_partially_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_64, p3, total_64); + + total_16 = (lp_count.nr_empty_16 + + lp_count.nr_fully_covered_16 + + lp_count.nr_partially_covered_16); + + p1 = 100.0 * (float) lp_count.nr_empty_16 / (float) total_16; + p2 = 100.0 * (float) lp_count.nr_fully_covered_16 / (float) total_16; + p3 = 100.0 * (float) lp_count.nr_partially_covered_16 / (float) total_16; + + debug_printf("llvmpipe: nr_empty_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_16, p1, total_16); + debug_printf("llvmpipe: nr_fully_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_16, p2, total_16); + debug_printf("llvmpipe: nr_partially_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_16, p3, total_16); + + total_4 = (lp_count.nr_empty_4 + lp_count.nr_non_empty_4); + + p1 = 100.0 * (float) lp_count.nr_empty_4 / (float) total_4; + p2 = 100.0 * (float) lp_count.nr_non_empty_4 / (float) total_4; + + debug_printf("llvmpipe: nr_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_empty_4, p1, total_4); + debug_printf("llvmpipe: nr_non_empty_4x4: %9u (%2.0f%% of %u)\n", lp_count.nr_non_empty_4, p2, total_4); + + debug_printf("llvmpipe: nr_color_tile_clear: %9u\n", lp_count.nr_color_tile_clear); + debug_printf("llvmpipe: nr_color_tile_load: %9u\n", lp_count.nr_color_tile_load); + debug_printf("llvmpipe: nr_color_tile_store: %9u\n", lp_count.nr_color_tile_store); + + debug_printf("llvmpipe: nr_llvm_compiles: %u\n", lp_count.nr_llvm_compiles); + debug_printf("llvmpipe: total LLVM compile time: %.2f sec\n", lp_count.llvm_compile_time / 1000000.0); + debug_printf("llvmpipe: average LLVM compile time: %.2f sec\n", lp_count.llvm_compile_time / 1000000.0 / lp_count.nr_llvm_compiles); + + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_perf.h b/src/gallium/drivers/llvmpipe/lp_perf.h new file mode 100644 index 0000000000..a9629dae3c --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_perf.h @@ -0,0 +1,82 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + +/** + * Performance / statistic counters, etc. + */ + + +#ifndef LP_PERF_H +#define LP_PERF_H + + +/** + * Various counters + */ +struct lp_counters +{ + unsigned nr_tris; + unsigned nr_culled_tris; + unsigned nr_empty_64; + unsigned nr_fully_covered_64; + unsigned nr_partially_covered_64; + unsigned nr_empty_16; + unsigned nr_fully_covered_16; + unsigned nr_partially_covered_16; + unsigned nr_empty_4; + unsigned nr_non_empty_4; + unsigned nr_llvm_compiles; + int64_t llvm_compile_time; /**< total, in microseconds */ + + unsigned nr_color_tile_clear; + unsigned nr_color_tile_load; + unsigned nr_color_tile_store; +}; + + +extern struct lp_counters lp_count; + + +/** Increment the named counter (only for debug builds) */ +#ifdef DEBUG +#define LP_COUNT(counter) lp_count.counter++ +#define LP_COUNT_ADD(counter, incr) lp_count.counter += (incr) +#else +#define LP_COUNT(counter) +#define LP_COUNT_ADD(counter, incr) (void) incr +#endif + + +extern void +lp_reset_counters(void); + + +extern void +lp_print_counters(void); + + +#endif /* LP_PERF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c deleted file mode 100644 index e8e2e2524a..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ /dev/null @@ -1,563 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * Interface between 'draw' module's output and the llvmpipe rasterizer/setup - * code. When the 'draw' module has finished filling a vertex buffer, the - * draw_arrays() functions below will be called. Loop over the vertices and - * call the point/line/tri setup functions. - * - * Authors - * Brian Paul - */ - - -#include "lp_context.h" -#include "lp_setup.h" -#include "lp_state.h" -#include "lp_prim_vbuf.h" -#include "draw/draw_context.h" -#include "draw/draw_vbuf.h" -#include "util/u_memory.h" -#include "util/u_prim.h" - - -#define LP_MAX_VBUF_INDEXES 1024 -#define LP_MAX_VBUF_SIZE 4096 - -typedef const float (*cptrf4)[4]; - -/** - * Subclass of vbuf_render. - */ -struct llvmpipe_vbuf_render -{ - struct vbuf_render base; - struct llvmpipe_context *llvmpipe; - struct setup_context *setup; - - uint prim; - uint vertex_size; - uint nr_vertices; - uint vertex_buffer_size; - void *vertex_buffer; -}; - - -/** cast wrapper */ -static struct llvmpipe_vbuf_render * -llvmpipe_vbuf_render(struct vbuf_render *vbr) -{ - return (struct llvmpipe_vbuf_render *) vbr; -} - - - - - - - -static const struct vertex_info * -lp_vbuf_get_vertex_info(struct vbuf_render *vbr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe); -} - - -static boolean -lp_vbuf_allocate_vertices(struct vbuf_render *vbr, - ushort vertex_size, ushort nr_vertices) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - unsigned size = vertex_size * nr_vertices; - - if (cvbr->vertex_buffer_size < size) { - align_free(cvbr->vertex_buffer); - cvbr->vertex_buffer = align_malloc(size, 16); - cvbr->vertex_buffer_size = size; - } - - cvbr->vertex_size = vertex_size; - cvbr->nr_vertices = nr_vertices; - - return cvbr->vertex_buffer != NULL; -} - -static void -lp_vbuf_release_vertices(struct vbuf_render *vbr) -{ - /* keep the old allocation for next time */ -} - -static void * -lp_vbuf_map_vertices(struct vbuf_render *vbr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - return cvbr->vertex_buffer; -} - -static void -lp_vbuf_unmap_vertices(struct vbuf_render *vbr, - ushort min_index, - ushort max_index ) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size ); - (void) cvbr; - /* do nothing */ -} - - -static boolean -lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - struct setup_context *setup_ctx = cvbr->setup; - - llvmpipe_setup_prepare( setup_ctx ); - - cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim); - cvbr->prim = prim; - return TRUE; - -} - - -static INLINE cptrf4 get_vert( const void *vertex_buffer, - int index, - int stride ) -{ - return (cptrf4)((char *)vertex_buffer + index * stride); -} - - -/** - * draw elements / indexed primitives - */ -static void -lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; - const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); - const void *vertex_buffer = cvbr->vertex_buffer; - struct setup_context *setup_ctx = cvbr->setup; - unsigned i; - - switch (cvbr->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < nr; i++) { - llvmpipe_setup_point( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 1; i < nr; i += 2) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - if (nr) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, indices[nr-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i+(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-(i&1)], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i+(i&1)-2], stride), - get_vert(vertex_buffer, indices[i-(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_QUADS: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride)); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. - */ - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); - } - break; - - default: - assert(0); - } -} - - -/** - * This function is hit when the draw module is working in pass-through mode. - * It's up to us to convert the vertex array into point/line/tri prims. - */ -static void -lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; - struct setup_context *setup_ctx = cvbr->setup; - const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); - const void *vertex_buffer = - (void *) get_vert(cvbr->vertex_buffer, start, stride); - unsigned i; - - switch (cvbr->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < nr; i++) { - llvmpipe_setup_point( setup_ctx, - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 1; i < nr; i += 2) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - for (i = 1; i < nr; i ++) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - if (nr) { - llvmpipe_setup_line( setup_ctx, - get_vert(vertex_buffer, nr-1, stride), - get_vert(vertex_buffer, 0, stride) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i++) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i+(i&1)-1, stride), - get_vert(vertex_buffer, i-(i&1), stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i++) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i+(i&1)-2, stride), - get_vert(vertex_buffer, i-(i&1)-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride) ); - } - } - else { - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_QUADS: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (llvmpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. - */ - for (i = 2; i < nr; i += 1) { - llvmpipe_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride) ); - } - break; - - default: - assert(0); - } -} - - - -static void -lp_vbuf_destroy(struct vbuf_render *vbr) -{ - struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); - llvmpipe_setup_destroy_context(cvbr->setup); - FREE(cvbr); -} - - -/** - * Create the post-transform vertex handler for the given context. - */ -struct vbuf_render * -lp_create_vbuf_backend(struct llvmpipe_context *lp) -{ - struct llvmpipe_vbuf_render *cvbr = CALLOC_STRUCT(llvmpipe_vbuf_render); - - assert(lp->draw); - - - cvbr->base.max_indices = LP_MAX_VBUF_INDEXES; - cvbr->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE; - - cvbr->base.get_vertex_info = lp_vbuf_get_vertex_info; - cvbr->base.allocate_vertices = lp_vbuf_allocate_vertices; - cvbr->base.map_vertices = lp_vbuf_map_vertices; - cvbr->base.unmap_vertices = lp_vbuf_unmap_vertices; - cvbr->base.set_primitive = lp_vbuf_set_primitive; - cvbr->base.draw = lp_vbuf_draw; - cvbr->base.draw_arrays = lp_vbuf_draw_arrays; - cvbr->base.release_vertices = lp_vbuf_release_vertices; - cvbr->base.destroy = lp_vbuf_destroy; - - cvbr->llvmpipe = lp; - - cvbr->setup = llvmpipe_setup_create_context(cvbr->llvmpipe); - - return &cvbr->base; -} diff --git a/src/gallium/drivers/llvmpipe/lp_quad.h b/src/gallium/drivers/llvmpipe/lp_quad.h deleted file mode 100644 index 7eb05de77a..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_quad.h +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/* Authors: Keith Whitwell <keith@tungstengraphics.com> - */ - -#ifndef LP_QUAD_H -#define LP_QUAD_H - -#include "pipe/p_state.h" -#include "tgsi/tgsi_exec.h" - - -#define QUAD_PRIM_POINT 1 -#define QUAD_PRIM_LINE 2 -#define QUAD_PRIM_TRI 3 - - -/* The rasterizer generates 2x2 quads of fragment and feeds them to - * the current fp_machine (see below). - * Remember that Y=0=top with Y increasing down the window. - */ -#define QUAD_TOP_LEFT 0 -#define QUAD_TOP_RIGHT 1 -#define QUAD_BOTTOM_LEFT 2 -#define QUAD_BOTTOM_RIGHT 3 - -#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT) -#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT) -#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT) -#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT) -#define MASK_ALL 0xf - - -/** - * Quad stage inputs (pos, coverage, front/back face, etc) - */ -struct quad_header_input -{ - int x0, y0; /**< quad window pos, always even */ - float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */ - unsigned facing:1; /**< Front (0) or back (1) facing? */ - unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */ -}; - - -/** - * Quad stage inputs/outputs. - */ -struct quad_header_inout -{ - unsigned mask:4; -}; - - -/** - * Quad stage outputs (color & depth). - */ -struct quad_header_output -{ - /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */ - float ALIGN16_ATTRIB color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE]; -}; - - -/** - * Input interpolation coefficients - */ -struct quad_interp_coef -{ - float ALIGN16_ATTRIB a0[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - float ALIGN16_ATTRIB dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; - float ALIGN16_ATTRIB dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; -}; - - -/** - * Encodes everything we need to know about a 2x2 pixel block. Uses - * "Channel-Serial" or "SoA" layout. - */ -struct quad_header { - struct quad_header_input input; - struct quad_header_inout inout; - - /* Redundant/duplicated: - */ - const struct quad_interp_coef *coef; -}; - -#endif /* LP_QUAD_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c new file mode 100644 index 0000000000..5ae323fd96 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -0,0 +1,1036 @@ +/************************************************************************** + * + * 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 VMWARE 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 <limits.h> +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_cpu_detect.h" +#include "util/u_surface.h" + +#include "lp_scene_queue.h" +#include "lp_debug.h" +#include "lp_fence.h" +#include "lp_perf.h" +#include "lp_rast.h" +#include "lp_rast_priv.h" +#include "lp_tile_soa.h" +#include "gallivm/lp_bld_debug.h" +#include "lp_scene.h" + + +/** + * Begin the rasterization phase. + * Map the framebuffer surfaces. Initialize the 'rast' state. + */ +static boolean +lp_rast_begin( struct lp_rasterizer *rast, + const struct pipe_framebuffer_state *fb, + boolean write_color, + boolean write_zstencil ) +{ + struct pipe_screen *screen = rast->screen; + struct pipe_surface *cbuf, *zsbuf; + int i; + + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + + util_copy_framebuffer_state(&rast->state.fb, fb); + + rast->state.write_zstencil = write_zstencil; + rast->state.write_color = write_color; + + rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 || + fb->height % TILE_SIZE != 0); + + + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + cbuf = rast->state.fb.cbufs[i]; + if (cbuf) { + rast->cbuf_transfer[i] = screen->get_tex_transfer(rast->screen, + cbuf->texture, + cbuf->face, + cbuf->level, + cbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, + cbuf->width, + cbuf->height); + if (!rast->cbuf_transfer[i]) + goto fail; + + rast->cbuf_map[i] = screen->transfer_map(rast->screen, + rast->cbuf_transfer[i]); + if (!rast->cbuf_map[i]) + goto fail; + } + } + + zsbuf = rast->state.fb.zsbuf; + if (zsbuf) { + rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen, + zsbuf->texture, + zsbuf->face, + zsbuf->level, + zsbuf->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, + zsbuf->width, + zsbuf->height); + if (!rast->zsbuf_transfer) + goto fail; + + rast->zsbuf_map = screen->transfer_map(rast->screen, + rast->zsbuf_transfer); + if (!rast->zsbuf_map) + goto fail; + } + + return TRUE; + +fail: + /* Unmap and release transfers? + */ + return FALSE; +} + + +/** + * Finish the rasterization phase. + * Unmap framebuffer surfaces. + */ +static void +lp_rast_end( struct lp_rasterizer *rast ) +{ + struct pipe_screen *screen = rast->screen; + unsigned i; + + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + if (rast->cbuf_map[i]) + screen->transfer_unmap(screen, rast->cbuf_transfer[i]); + + if (rast->cbuf_transfer[i]) + screen->tex_transfer_destroy(rast->cbuf_transfer[i]); + + rast->cbuf_transfer[i] = NULL; + rast->cbuf_map[i] = NULL; + } + + if (rast->zsbuf_map) + screen->transfer_unmap(screen, rast->zsbuf_transfer); + + if (rast->zsbuf_transfer) + screen->tex_transfer_destroy(rast->zsbuf_transfer); + + rast->zsbuf_transfer = NULL; + rast->zsbuf_map = NULL; +} + + +/** + * Begining rasterization of a tile. + * \param x window X position of the tile, in pixels + * \param y window Y position of the tile, in pixels + */ +static void +lp_rast_start_tile( struct lp_rasterizer *rast, + unsigned thread_index, + unsigned x, unsigned y ) +{ + LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); + + rast->tasks[thread_index].x = x; + rast->tasks[thread_index].y = y; +} + + +/** + * Clear the rasterizer's current color tile. + * This is a bin command called during bin processing. + */ +void lp_rast_clear_color( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + const uint8_t *clear_color = arg.clear_color; + uint8_t **color_tile = rast->tasks[thread_index].tile.color; + unsigned i; + + LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, + clear_color[0], + clear_color[1], + clear_color[2], + clear_color[3]); + + if (clear_color[0] == clear_color[1] && + clear_color[1] == clear_color[2] && + clear_color[2] == clear_color[3]) { + /* clear to grayscale value {x, x, x, x} */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4); + } + } + else { + /* Non-gray color. + * Note: if the swizzled tile layout changes (see TILE_PIXEL) this code + * will need to change. It'll be pretty obvious when clearing no longer + * works. + */ + const unsigned chunk = TILE_SIZE / 4; + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + uint8_t *c = color_tile[i]; + unsigned j; + for (j = 0; j < 4 * TILE_SIZE; j++) { + memset(c, clear_color[0], chunk); + c += chunk; + memset(c, clear_color[1], chunk); + c += chunk; + memset(c, clear_color[2], chunk); + c += chunk; + memset(c, clear_color[3], chunk); + c += chunk; + } + assert(c - color_tile[i] == TILE_SIZE * TILE_SIZE * 4); + } + } + + LP_COUNT(nr_color_tile_clear); +} + + +/** + * Clear the rasterizer's current z/stencil tile. + * This is a bin command called during bin processing. + */ +void lp_rast_clear_zstencil( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg) +{ + unsigned i; + uint32_t *depth_tile = rast->tasks[thread_index].tile.depth; + + LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); + + for (i = 0; i < TILE_SIZE * TILE_SIZE; i++) + depth_tile[i] = arg.clear_zstencil; +} + + +/** + * Load tile color from the framebuffer surface. + * This is a bin command called during bin processing. + */ +void lp_rast_load_color( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; + unsigned i; + + LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y); + + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + struct pipe_transfer *transfer = rast->cbuf_transfer[i]; + int w = TILE_SIZE; + int h = TILE_SIZE; + + if (x >= transfer->width) + continue; + + if (y >= transfer->height) + continue; + + assert(w >= 0); + assert(h >= 0); + assert(w <= TILE_SIZE); + assert(h <= TILE_SIZE); + + lp_tile_read_4ub(transfer->texture->format, + task->tile.color[i], + rast->cbuf_map[i], + transfer->stride, + x, y, + w, h); + + LP_COUNT(nr_color_tile_load); + } +} + + +static void +lp_tile_read_z32(uint32_t *tile, + const uint8_t *map, + unsigned map_stride, + unsigned x0, unsigned y0, unsigned w, unsigned h) +{ + unsigned x, y; + const uint8_t *map_row = map + y0*map_stride; + for (y = 0; y < h; ++y) { + const uint32_t *map_pixel = (uint32_t *)(map_row + x0*4); + for (x = 0; x < w; ++x) { + *tile++ = *map_pixel++; + } + map_row += map_stride; + } +} + +/** + * Load tile z/stencil from the framebuffer surface. + * This is a bin command called during bin processing. + */ +void lp_rast_load_zstencil( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; + unsigned w = TILE_SIZE; + unsigned h = TILE_SIZE; + + if (x + w > rast->state.fb.width) + w -= x + w - rast->state.fb.width; + + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; + + LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); + lp_tile_read_z32(task->tile.depth, + rast->zsbuf_map, + rast->zsbuf_transfer->stride, + x, y, w, h); +} + + +void lp_rast_set_state( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + const struct lp_rast_state *state = arg.set_state; + + LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state); + + /* just set the current state pointer for this rasterizer */ + rast->tasks[thread_index].current_state = state; +} + + + +/** + * Run the shader on all blocks in a tile. This is used when a tile is + * completely contained inside a triangle. + * This is a bin command called during bin processing. + */ +void lp_rast_shade_tile( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const struct lp_rast_state *state = task->current_state; + struct lp_rast_tile *tile = &task->tile; + const struct lp_rast_shader_inputs *inputs = arg.shade_tile; + const unsigned tile_x = task->x; + const unsigned tile_y = task->y; + unsigned x, y; + + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + + /* render the whole 64x64 tile in 4x4 chunks */ + for (y = 0; y < TILE_SIZE; y += 4){ + for (x = 0; x < TILE_SIZE; x += 4) { + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + uint32_t *depth; + unsigned block_offset, i; + + /* offset of the 16x16 pixel block within the tile */ + block_offset = ((y / 4) * (16 * 16) + (x / 4) * 16); + + /* color buffer */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; + + /* depth buffer */ + depth = tile->depth + block_offset; + + /* run shader */ + state->jit_function[0]( &state->jit_context, + tile_x + x, tile_y + y, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); + } + } +} + + +/** + * Compute shading for a 4x4 block of pixels. + * This is a bin command called during bin processing. + */ +void lp_rast_shade_quads( struct lp_rasterizer *rast, + unsigned thread_index, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y, + int32_t c1, int32_t c2, int32_t c3) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const struct lp_rast_state *state = task->current_state; + struct lp_rast_tile *tile = &task->tile; + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + void *depth; + unsigned i; + unsigned ix, iy; + int block_offset; + +#ifdef DEBUG + assert(state); + + /* Sanity checks */ + assert(x % TILE_VECTOR_WIDTH == 0); + assert(y % TILE_VECTOR_HEIGHT == 0); + + assert((x % 4) == 0); + assert((y % 4) == 0); +#endif + + ix = x % TILE_SIZE; + iy = y % TILE_SIZE; + + /* offset of the 16x16 pixel block within the tile */ + block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16); + + /* color buffer */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; + + /* depth buffer */ + depth = tile->depth + block_offset; + + + +#ifdef DEBUG + assert(lp_check_alignment(tile->depth, 16)); + assert(lp_check_alignment(tile->color[0], 16)); + assert(lp_check_alignment(state->jit_context.blend_color, 16)); + + assert(lp_check_alignment(inputs->step[0], 16)); + assert(lp_check_alignment(inputs->step[1], 16)); + assert(lp_check_alignment(inputs->step[2], 16)); +#endif + + /* run shader */ + state->jit_function[1]( &state->jit_context, + x, y, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + c1, c2, c3, + inputs->step[0], inputs->step[1], inputs->step[2]); +} + + +/** + * Set top row and left column of the tile's pixels to white. For debugging. + */ +static void +outline_tile(uint8_t *tile) +{ + const uint8_t val = 0xff; + unsigned i; + + for (i = 0; i < TILE_SIZE; i++) { + TILE_PIXEL(tile, i, 0, 0) = val; + TILE_PIXEL(tile, i, 0, 1) = val; + TILE_PIXEL(tile, i, 0, 2) = val; + TILE_PIXEL(tile, i, 0, 3) = val; + + TILE_PIXEL(tile, 0, i, 0) = val; + TILE_PIXEL(tile, 0, i, 1) = val; + TILE_PIXEL(tile, 0, i, 2) = val; + TILE_PIXEL(tile, 0, i, 3) = val; + } +} + + +/** + * Draw grid of gray lines at 16-pixel intervals across the tile to + * show the sub-tile boundaries. For debugging. + */ +static void +outline_subtiles(uint8_t *tile) +{ + const uint8_t val = 0x80; + const unsigned step = 16; + unsigned i, j; + + for (i = 0; i < TILE_SIZE; i += step) { + for (j = 0; j < TILE_SIZE; j++) { + TILE_PIXEL(tile, i, j, 0) = val; + TILE_PIXEL(tile, i, j, 1) = val; + TILE_PIXEL(tile, i, j, 2) = val; + TILE_PIXEL(tile, i, j, 3) = val; + + TILE_PIXEL(tile, j, i, 0) = val; + TILE_PIXEL(tile, j, i, 1) = val; + TILE_PIXEL(tile, j, i, 2) = val; + TILE_PIXEL(tile, j, i, 3) = val; + } + } + + outline_tile(tile); +} + + + +/** + * Write the rasterizer's color tile to the framebuffer. + */ +static void lp_rast_store_color( struct lp_rasterizer *rast, + unsigned thread_index) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; + unsigned i; + + for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + struct pipe_transfer *transfer = rast->cbuf_transfer[i]; + int w = TILE_SIZE; + int h = TILE_SIZE; + + if (x >= transfer->width) + continue; + + if (y >= transfer->height) + continue; + + LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, + thread_index, x, y, w, h); + + if (LP_DEBUG & DEBUG_SHOW_SUBTILES) + outline_subtiles(task->tile.color[i]); + else if (LP_DEBUG & DEBUG_SHOW_TILES) + outline_tile(task->tile.color[i]); + + lp_tile_write_4ub(transfer->texture->format, + task->tile.color[i], + rast->cbuf_map[i], + transfer->stride, + x, y, + w, h); + + LP_COUNT(nr_color_tile_store); + } +} + + +static void +lp_tile_write_z32(const uint32_t *src, uint8_t *dst, unsigned dst_stride, + unsigned x0, unsigned y0, unsigned w, unsigned h) +{ + unsigned x, y; + uint8_t *dst_row = dst + y0*dst_stride; + for (y = 0; y < h; ++y) { + uint32_t *dst_pixel = (uint32_t *)(dst_row + x0*4); + for (x = 0; x < w; ++x) { + *dst_pixel++ = *src++; + } + dst_row += dst_stride; + } +} + +/** + * Write the rasterizer's z/stencil tile to the framebuffer. + */ +static void lp_rast_store_zstencil( struct lp_rasterizer *rast, + unsigned thread_index ) +{ + struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + const unsigned x = task->x; + const unsigned y = task->y; + unsigned w = TILE_SIZE; + unsigned h = TILE_SIZE; + + if (x + w > rast->state.fb.width) + w -= x + w - rast->state.fb.width; + + if (y + h > rast->state.fb.height) + h -= y + h - rast->state.fb.height; + + LP_DBG(DEBUG_RAST, "%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + assert(rast->zsbuf_transfer->texture->format == PIPE_FORMAT_Z32_UNORM); + lp_tile_write_z32(task->tile.depth, + rast->zsbuf_map, + rast->zsbuf_transfer->stride, + x, y, w, h); +} + + +/** + * Write the rasterizer's tiles to the framebuffer. + */ +static void +lp_rast_end_tile( struct lp_rasterizer *rast, + unsigned thread_index ) +{ + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + + if (rast->state.write_color) + lp_rast_store_color(rast, thread_index); + + if (rast->state.write_zstencil) + lp_rast_store_zstencil(rast, thread_index); +} + + +/** + * Signal on a fence. This is called during bin execution/rasterization. + * Called per thread. + */ +void lp_rast_fence( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + struct lp_fence *fence = arg.fence; + + pipe_mutex_lock( fence->mutex ); + + fence->count++; + assert(fence->count <= fence->rank); + + LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__, + fence->count, fence->rank); + + pipe_condvar_signal( fence->signalled ); + + pipe_mutex_unlock( fence->mutex ); +} + + +/** + * When all the threads are done rasterizing a scene, one thread will + * call this function to reset the scene and put it onto the empty queue. + */ +static void +release_scene( struct lp_rasterizer *rast, + struct lp_scene *scene ) +{ + util_unreference_framebuffer_state( &scene->fb ); + + lp_scene_reset( scene ); + lp_scene_enqueue( rast->empty_scenes, scene ); + rast->curr_scene = NULL; +} + + +/** + * Rasterize commands for a single bin. + * \param x, y position of the bin's tile in the framebuffer + * Must be called between lp_rast_begin() and lp_rast_end(). + * Called per thread. + */ +static void +rasterize_bin( struct lp_rasterizer *rast, + unsigned thread_index, + const struct cmd_bin *bin, + int x, int y) +{ + const struct cmd_block_list *commands = &bin->commands; + struct cmd_block *block; + unsigned k; + + lp_rast_start_tile( rast, thread_index, x, y ); + + /* simply execute each of the commands in the block list */ + for (block = commands->head; block; block = block->next) { + for (k = 0; k < block->count; k++) { + block->cmd[k]( rast, thread_index, block->arg[k] ); + } + } + + lp_rast_end_tile( rast, thread_index ); +} + + +#define RAST(x) { lp_rast_##x, #x } + +static struct { + lp_rast_cmd cmd; + const char *name; +} cmd_names[] = +{ + RAST(load_color), + RAST(load_zstencil), + RAST(clear_color), + RAST(clear_zstencil), + RAST(triangle), + RAST(shade_tile), + RAST(set_state), + RAST(fence), +}; + +static void +debug_bin( const struct cmd_bin *bin ) +{ + const struct cmd_block *head = bin->commands.head; + int i, j; + + for (i = 0; i < head->count; i++) { + debug_printf("%d: ", i); + for (j = 0; j < Elements(cmd_names); j++) { + if (head->cmd[i] == cmd_names[j].cmd) { + debug_printf("%s\n", cmd_names[j].name); + break; + } + } + if (j == Elements(cmd_names)) + debug_printf("...other\n"); + } + +} + +/* An empty bin is one that just loads the contents of the tile and + * stores them again unchanged. This typically happens when bins have + * been flushed for some reason in the middle of a frame, or when + * incremental updates are being made to a render target. + * + * Try to avoid doing pointless work in this case. + */ +static boolean +is_empty_bin( const struct cmd_bin *bin ) +{ + const struct cmd_block *head = bin->commands.head; + int i; + + if (0) + debug_bin(bin); + + /* We emit at most two load-tile commands at the start of the first + * command block. In addition we seem to emit a couple of + * set-state commands even in empty bins. + * + * As a heuristic, if a bin has more than 4 commands, consider it + * non-empty. + */ + if (head->next != NULL || + head->count > 4) { + return FALSE; + } + + for (i = 0; i < head->count; i++) + if (head->cmd[i] != lp_rast_load_color && + head->cmd[i] != lp_rast_load_zstencil && + head->cmd[i] != lp_rast_set_state) { + return FALSE; + } + + return TRUE; +} + + + +/** + * Rasterize/execute all bins within a scene. + * Called per thread. + */ +static void +rasterize_scene( struct lp_rasterizer *rast, + unsigned thread_index, + struct lp_scene *scene, + bool write_depth ) +{ + /* loop over scene bins, rasterize each */ +#if 0 + { + unsigned i, j; + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(scene, i, j); + rasterize_bin( rast, thread_index, + bin, i * TILE_SIZE, j * TILE_SIZE ); + } + } + } +#else + { + struct cmd_bin *bin; + int x, y; + + assert(scene); + while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { + if (!is_empty_bin( bin )) + rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); + } + } +#endif +} + + +/** + * Called by setup module when it has something for us to render. + */ +void +lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, + const struct pipe_framebuffer_state *fb, + bool write_depth ) +{ + boolean debug = false; + + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + + if (debug) { + unsigned x, y; + debug_printf("rasterize scene:\n"); + debug_printf(" data size: %u\n", lp_scene_data_size(scene)); + for (y = 0; y < scene->tiles_y; y++) { + for (x = 0; x < scene->tiles_x; x++) { + debug_printf(" bin %u, %u size: %u\n", x, y, + lp_scene_bin_size(scene, x, y)); + } + } + } + + /* save framebuffer state in the bin */ + util_copy_framebuffer_state(&scene->fb, fb); + scene->write_depth = write_depth; + + if (rast->num_threads == 0) { + /* no threading */ + + lp_rast_begin( rast, fb, + fb->nr_cbufs != 0, /* always write color if cbufs present */ + fb->zsbuf != NULL && write_depth ); + + lp_scene_bin_iter_begin( scene ); + rasterize_scene( rast, 0, scene, write_depth ); + + release_scene( rast, scene ); + + lp_rast_end( rast ); + } + else { + /* threaded rendering! */ + unsigned i; + + lp_scene_enqueue( rast->full_scenes, scene ); + + /* signal the threads that there's work to do */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_signal(&rast->tasks[i].work_ready); + } + + /* wait for work to complete */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_wait(&rast->tasks[i].work_done); + } + } + + LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); +} + + +/** + * This is the thread's main entrypoint. + * It's a simple loop: + * 1. wait for work + * 2. do work + * 3. signal that we're done + */ +static PIPE_THREAD_ROUTINE( thread_func, init_data ) +{ + struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; + struct lp_rasterizer *rast = task->rast; + boolean debug = false; + + while (1) { + /* wait for work */ + if (debug) + debug_printf("thread %d waiting for work\n", task->thread_index); + pipe_semaphore_wait(&task->work_ready); + + if (task->thread_index == 0) { + /* thread[0]: + * - get next scene to rasterize + * - map the framebuffer surfaces + */ + const struct pipe_framebuffer_state *fb; + boolean write_depth; + + rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE ); + + lp_scene_bin_iter_begin( rast->curr_scene ); + + fb = &rast->curr_scene->fb; + write_depth = rast->curr_scene->write_depth; + + lp_rast_begin( rast, fb, + fb->nr_cbufs != 0, + fb->zsbuf != NULL && write_depth ); + } + + /* Wait for all threads to get here so that threads[1+] don't + * get a null rast->curr_scene pointer. + */ + pipe_barrier_wait( &rast->barrier ); + + /* do work */ + if (debug) + debug_printf("thread %d doing work\n", task->thread_index); + rasterize_scene(rast, + task->thread_index, + rast->curr_scene, + rast->curr_scene->write_depth); + + /* wait for all threads to finish with this scene */ + pipe_barrier_wait( &rast->barrier ); + + if (task->thread_index == 0) { + /* thread[0]: + * - release the scene object + * - unmap the framebuffer surfaces + */ + release_scene( rast, rast->curr_scene ); + lp_rast_end( rast ); + } + + /* signal done with work */ + if (debug) + debug_printf("thread %d done working\n", task->thread_index); + pipe_semaphore_signal(&task->work_done); + } + + return NULL; +} + + +/** + * Initialize semaphores and spawn the threads. + */ +static void +create_rast_threads(struct lp_rasterizer *rast) +{ + unsigned i; + +#ifdef PIPE_OS_WINDOWS + /* Multithreading not supported on windows until conditions and barriers are + * properly implemented. */ + rast->num_threads = 0; +#else + rast->num_threads = util_cpu_caps.nr_cpus; + rast->num_threads = debug_get_num_option("LP_NUM_THREADS", rast->num_threads); + rast->num_threads = MIN2(rast->num_threads, MAX_THREADS); +#endif + + /* NOTE: if num_threads is zero, we won't use any threads */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_init(&rast->tasks[i].work_ready, 0); + pipe_semaphore_init(&rast->tasks[i].work_done, 0); + rast->threads[i] = pipe_thread_create(thread_func, + (void *) &rast->tasks[i]); + } +} + + + +/** + * Create new lp_rasterizer. + * \param empty the queue to put empty scenes on after we've finished + * processing them. + */ +struct lp_rasterizer * +lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) +{ + struct lp_rasterizer *rast; + unsigned i, cbuf; + + rast = CALLOC_STRUCT(lp_rasterizer); + if(!rast) + return NULL; + + rast->screen = screen; + + rast->empty_scenes = empty; + rast->full_scenes = lp_scene_queue_create(); + + for (i = 0; i < Elements(rast->tasks); i++) { + struct lp_rasterizer_task *task = &rast->tasks[i]; + + for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) + task->tile.color[cbuf] = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); + + task->tile.depth = align_malloc(TILE_SIZE * TILE_SIZE * 4, 16); + task->rast = rast; + task->thread_index = i; + } + + create_rast_threads(rast); + + /* for synchronizing rasterization threads */ + pipe_barrier_init( &rast->barrier, rast->num_threads ); + + return rast; +} + + +/* Shutdown: + */ +void lp_rast_destroy( struct lp_rasterizer *rast ) +{ + unsigned i, cbuf; + + util_unreference_framebuffer_state(&rast->state.fb); + + for (i = 0; i < Elements(rast->tasks); i++) { + align_free(rast->tasks[i].tile.depth); + for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) + align_free(rast->tasks[i].tile.color[cbuf]); + } + + /* for synchronizing rasterization threads */ + pipe_barrier_destroy( &rast->barrier ); + + FREE(rast); +} + + +/** Return number of rasterization threads */ +unsigned +lp_rast_get_num_threads( struct lp_rasterizer *rast ) +{ + return rast->num_threads; +} diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h new file mode 100644 index 0000000000..34da73eb50 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -0,0 +1,236 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + +/** + * The rast code is concerned with rasterization of command bins. + * Each screen tile has a bin associated with it. To render the + * scene we iterate over the tile bins and execute the commands + * in each bin. + * We'll do that with multiple threads... + */ + + +#ifndef LP_RAST_H +#define LP_RAST_H + +#include "pipe/p_compiler.h" +#include "lp_jit.h" + + +struct lp_rasterizer; +struct lp_scene; +struct lp_scene_queue; +struct lp_fence; +struct cmd_bin; +struct pipe_screen; + +/** For sub-pixel positioning */ +#define FIXED_ORDER 4 +#define FIXED_ONE (1<<FIXED_ORDER) + + +/** + * Rasterization state. + * Objects of this type are put into the shared data bin and pointed + * to by commands in the per-tile bins. + */ +struct lp_rast_state { + /* State for the shader. This also contains state which feeds into + * the fragment shader, such as blend color and alpha ref value. + */ + struct lp_jit_context jit_context; + + /* The shader itself. Probably we also need to pass a pointer to + * the tile color/z/stencil data somehow: + * jit_function[0] skips the triangle in/out test code + * jit_function[1] does triangle in/out testing + */ + lp_jit_frag_func jit_function[2]; + + boolean opaque; +}; + + +/** + * Coefficients necessary to run the shader at a given location. + * First coefficient is position. + * These pointers point into the bin data buffer. + */ +struct lp_rast_shader_inputs { + float (*a0)[4]; + float (*dadx)[4]; + float (*dady)[4]; + + /* edge/step info for 3 edges and 4x4 block of pixels */ + PIPE_ALIGN_VAR(16) int step[3][16]; +}; + + +/** + * Rasterization information for a triangle known to be in this bin, + * plus inputs to run the shader: + * These fields are tile- and bin-independent. + * Objects of this type are put into the setup_context::data buffer. + */ +struct lp_rast_triangle { + /* one-pixel sized trivial accept offsets for each plane */ + int ei1; + int ei2; + int ei3; + + /* one-pixel sized trivial reject offsets for each plane */ + int eo1; + int eo2; + int eo3; + + /* y deltas for vertex pairs (in fixed pt) */ + int dy12; + int dy23; + int dy31; + + /* x deltas for vertex pairs (in fixed pt) */ + int dx12; + int dx23; + int dx31; + + /* edge function values at minx,miny ?? */ + int c1, c2, c3; + + /* inputs for the shader */ + PIPE_ALIGN_VAR(16) struct lp_rast_shader_inputs inputs; +}; + + + +struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen, + struct lp_scene_queue *empty ); + +void lp_rast_destroy( struct lp_rasterizer * ); + +unsigned lp_rast_get_num_threads( struct lp_rasterizer * ); + +void lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, + const struct pipe_framebuffer_state *fb, + bool write_depth ); + + + +union lp_rast_cmd_arg { + const struct lp_rast_shader_inputs *shade_tile; + const struct lp_rast_triangle *triangle; + const struct lp_rast_state *set_state; + uint8_t clear_color[4]; + unsigned clear_zstencil; + struct lp_fence *fence; +}; + + +/* Cast wrappers. Hopefully these compile to noops! + */ +static INLINE union lp_rast_cmd_arg +lp_rast_arg_inputs( const struct lp_rast_shader_inputs *shade_tile ) +{ + union lp_rast_cmd_arg arg; + arg.shade_tile = shade_tile; + return arg; +} + +static INLINE union lp_rast_cmd_arg +lp_rast_arg_triangle( const struct lp_rast_triangle *triangle ) +{ + union lp_rast_cmd_arg arg; + arg.triangle = triangle; + return arg; +} + +static INLINE union lp_rast_cmd_arg +lp_rast_arg_state( const struct lp_rast_state *state ) +{ + union lp_rast_cmd_arg arg; + arg.set_state = state; + return arg; +} + +static INLINE union lp_rast_cmd_arg +lp_rast_arg_fence( struct lp_fence *fence ) +{ + union lp_rast_cmd_arg arg; + arg.fence = fence; + return arg; +} + + +static INLINE union lp_rast_cmd_arg +lp_rast_arg_null( void ) +{ + union lp_rast_cmd_arg arg; + arg.set_state = NULL; + return arg; +} + + + +/** + * Binnable Commands. + * These get put into bins by the setup code and are called when + * the bins are executed. + */ + +void lp_rast_clear_color( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_clear_zstencil( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_load_color( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_load_zstencil( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_set_state( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_triangle( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_shade_tile( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +void lp_rast_fence( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h new file mode 100644 index 0000000000..71e3a301e6 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -0,0 +1,172 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + +#ifndef LP_RAST_PRIV_H +#define LP_RAST_PRIV_H + +#include "os/os_thread.h" +#include "lp_rast.h" +#include "lp_tile_soa.h" + + +#define MAX_THREADS 8 /* XXX probably temporary here */ + + +struct pipe_transfer; +struct pipe_screen; +struct lp_rasterizer; + + +/** + * A tile's color and depth memory. + * We can choose whatever layout for the internal tile storage we prefer. + */ +struct lp_rast_tile +{ + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + + uint32_t *depth; +}; + + +/** + * Per-thread rasterization state + */ +struct lp_rasterizer_task +{ + struct lp_rast_tile tile; /** Tile color/z/stencil memory */ + + unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */ + + const struct lp_rast_state *current_state; + + /** "back" pointer */ + struct lp_rasterizer *rast; + + /** "my" index */ + unsigned thread_index; + + pipe_semaphore work_ready; + pipe_semaphore work_done; +}; + + +/** + * This is the state required while rasterizing tiles. + * Note that this contains per-thread information too. + * The tile size is TILE_SIZE x TILE_SIZE pixels. + */ +struct lp_rasterizer +{ + boolean clipped_tile; + boolean check_for_clipped_tiles; + + /* Framebuffer stuff + */ + struct pipe_screen *screen; + struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS]; + struct pipe_transfer *zsbuf_transfer; + void *cbuf_map[PIPE_MAX_COLOR_BUFS]; + void *zsbuf_map; + + struct { + struct pipe_framebuffer_state fb; + boolean write_color; + boolean write_zstencil; + unsigned clear_color; + unsigned clear_depth; + char clear_stencil; + } state; + + /** The incoming queue of scenes ready to rasterize */ + struct lp_scene_queue *full_scenes; + /** The outgoing queue of processed scenes to return to setup modulee */ + struct lp_scene_queue *empty_scenes; + + /** The scene currently being rasterized by the threads */ + struct lp_scene *curr_scene; + + /** A task object for each rasterization thread */ + struct lp_rasterizer_task tasks[MAX_THREADS]; + + unsigned num_threads; + pipe_thread threads[MAX_THREADS]; + + /** For synchronizing the rasterization threads */ + pipe_barrier barrier; +}; + + +void lp_rast_shade_quads( struct lp_rasterizer *rast, + unsigned thread_index, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y, + int32_t c1, int32_t c2, int32_t c3); + + +/** + * Shade all pixels in a 4x4 block. The fragment code omits the + * triangle in/out tests. + * \param x, y location of 4x4 block in window coords + */ +static INLINE void +lp_rast_shade_quads_all( struct lp_rasterizer *rast, + unsigned thread_index, + const struct lp_rast_shader_inputs *inputs, + unsigned x, unsigned y ) +{ + const struct lp_rast_state *state = rast->tasks[thread_index].current_state; + struct lp_rast_tile *tile = &rast->tasks[thread_index].tile; + const unsigned ix = x % TILE_SIZE, iy = y % TILE_SIZE; + uint8_t *color[PIPE_MAX_COLOR_BUFS]; + void *depth; + unsigned block_offset, i; + + /* offset of the containing 16x16 pixel block within the tile */ + block_offset = (iy / 4) * (16 * 16) + (ix / 4) * 16; + + /* color buffer */ + for (i = 0; i < rast->state.fb.nr_cbufs; i++) + color[i] = tile->color[i] + 4 * block_offset; + + /* depth buffer */ + depth = tile->depth + block_offset; + + /* run shader */ + state->jit_function[0]( &state->jit_context, + x, y, + inputs->a0, + inputs->dadx, + inputs->dady, + color, + depth, + INT_MIN, INT_MIN, INT_MIN, + NULL, NULL, NULL ); +} + + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c new file mode 100644 index 0000000000..3f76f159df --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -0,0 +1,251 @@ +/************************************************************************** + * + * Copyright 2007-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 VMWARE 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. + * + **************************************************************************/ + +/* + * Rasterization for binned triangles within a tile + */ + +#include <limits.h> +#include "util/u_math.h" +#include "lp_debug.h" +#include "lp_perf.h" +#include "lp_rast_priv.h" +#include "lp_tile_soa.h" + + +/** + * Map an index in [0,15] to an x,y position, multiplied by 4. + * This is used to get the position of each subtile in a 4x4 + * grid of edge step values. + * Note: we can use some bit twiddling to compute these values instead + * of using a look-up table, but there's no measurable performance + * difference. + */ +static const int pos_table4[16][2] = { + { 0, 0 }, + { 4, 0 }, + { 0, 4 }, + { 4, 4 }, + { 8, 0 }, + { 12, 0 }, + { 8, 4 }, + { 12, 4 }, + { 0, 8 }, + { 4, 8 }, + { 0, 12 }, + { 4, 12 }, + { 8, 8 }, + { 12, 8 }, + { 8, 12 }, + { 12, 12 } +}; + + +static const int pos_table16[16][2] = { + { 0, 0 }, + { 16, 0 }, + { 0, 16 }, + { 16, 16 }, + { 32, 0 }, + { 48, 0 }, + { 32, 16 }, + { 48, 16 }, + { 0, 32 }, + { 16, 32 }, + { 0, 48 }, + { 16, 48 }, + { 32, 32 }, + { 48, 32 }, + { 32, 48 }, + { 48, 48 } +}; + + +/** + * Shade all pixels in a 4x4 block. + */ +static void +block_full_4( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y ) +{ + lp_rast_shade_quads_all(rast_task->rast, + rast_task->thread_index, + &tri->inputs, + x, y); +} + + +/** + * Shade all pixels in a 16x16 block. + */ +static void +block_full_16( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y ) +{ + unsigned ix, iy; + assert(x % 16 == 0); + assert(y % 16 == 0); + for (iy = 0; iy < 16; iy += 4) + for (ix = 0; ix < 16; ix += 4) + block_full_4(rast_task, tri, x + ix, y + iy); +} + + +/** + * Pass the 4x4 pixel block to the shader function. + * Determination of which of the 16 pixels lies inside the triangle + * will be done as part of the fragment shader. + */ +static void +do_block_4( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y, + int c1, + int c2, + int c3 ) +{ + lp_rast_shade_quads(rast_task->rast, + rast_task->thread_index, + &tri->inputs, + x, y, + -c1, -c2, -c3); +} + + +/** + * Evaluate a 16x16 block of pixels to determine which 4x4 subblocks are in/out + * of the triangle's bounds. + */ +static void +do_block_16( struct lp_rasterizer_task *rast_task, + const struct lp_rast_triangle *tri, + int x, int y, + int c1, + int c2, + int c3 ) +{ + const int eo1 = tri->eo1 * 4; + const int eo2 = tri->eo2 * 4; + const int eo3 = tri->eo3 * 4; + const int *step0 = tri->inputs.step[0]; + const int *step1 = tri->inputs.step[1]; + const int *step2 = tri->inputs.step[2]; + int i; + + assert(x % 16 == 0); + assert(y % 16 == 0); + + for (i = 0; i < 16; i++) { + int cx1 = c1 + step0[i] * 4; + int cx2 = c2 + step1[i] * 4; + int cx3 = c3 + step2[i] * 4; + + if (cx1 + eo1 < 0 || + cx2 + eo2 < 0 || + cx3 + eo3 < 0) { + /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_4); + } + else { + int px = x + pos_table4[i][0]; + int py = y + pos_table4[i][1]; + /* Don't bother testing if the 4x4 block is entirely in/out of + * the triangle. It's a little faster to do it in the jit code. + */ + LP_COUNT(nr_non_empty_4); + do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); + } + } +} + + +/** + * Scan the tile in chunks and figure out which pixels to rasterize + * for this triangle. + */ +void +lp_rast_triangle( struct lp_rasterizer *rast, + unsigned thread_index, + const union lp_rast_cmd_arg arg ) +{ + struct lp_rasterizer_task *rast_task = &rast->tasks[thread_index]; + const struct lp_rast_triangle *tri = arg.triangle; + + int x = rast_task->x; + int y = rast_task->y; + unsigned i; + + int c1 = tri->c1 + tri->dx12 * y - tri->dy12 * x; + int c2 = tri->c2 + tri->dx23 * y - tri->dy23 * x; + int c3 = tri->c3 + tri->dx31 * y - tri->dy31 * x; + + int ei1 = tri->ei1 * 16; + int ei2 = tri->ei2 * 16; + int ei3 = tri->ei3 * 16; + + int eo1 = tri->eo1 * 16; + int eo2 = tri->eo2 * 16; + int eo3 = tri->eo3 * 16; + + LP_DBG(DEBUG_RAST, "lp_rast_triangle\n"); + + /* Walk over the tile to build a list of 4x4 pixel blocks which will + * be filled/shaded. We do this at two granularities: 16x16 blocks + * and then 4x4 blocks. + */ + for (i = 0; i < 16; i++) { + int cx1 = c1 + (tri->inputs.step[0][i] * 16); + int cx2 = c2 + (tri->inputs.step[1][i] * 16); + int cx3 = c3 + (tri->inputs.step[2][i] * 16); + + if (cx1 + eo1 < 0 || + cx2 + eo2 < 0 || + cx3 + eo3 < 0) { + /* the block is completely outside the triangle - nop */ + LP_COUNT(nr_empty_16); + } + else { + int px = x + pos_table16[i][0]; + int py = y + pos_table16[i][1]; + + if (cx1 + ei1 > 0 && + cx2 + ei2 > 0 && + cx3 + ei3 > 0) { + /* the block is completely inside the triangle */ + LP_COUNT(nr_fully_covered_16); + block_full_16(rast_task, tri, px, py); + } + else { + /* the block is partially in/out of the triangle */ + LP_COUNT(nr_partially_covered_16); + do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); + } + } + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c new file mode 100644 index 0000000000..b7116297ec --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -0,0 +1,392 @@ +/************************************************************************** + * + * 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 VMWARE 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 "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_simple_list.h" +#include "lp_scene.h" + + +struct lp_scene * +lp_scene_create(void) +{ + struct lp_scene *scene = CALLOC_STRUCT(lp_scene); + if (scene) + lp_scene_init(scene); + return scene; +} + + +void +lp_scene_destroy(struct lp_scene *scene) +{ + lp_scene_reset(scene); + lp_scene_free_bin_data(scene); + FREE(scene); +} + + +void +lp_scene_init(struct lp_scene *scene) +{ + unsigned i, j; + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); + } + + scene->data.head = + scene->data.tail = CALLOC_STRUCT(data_block); + + make_empty_list(&scene->textures); + + pipe_mutex_init(scene->mutex); +} + + +/** + * Check if the scene's bins are all empty. + * For debugging purposes. + */ +boolean +lp_scene_is_empty(struct lp_scene *scene ) +{ + unsigned x, y; + + for (y = 0; y < TILES_Y; y++) { + for (x = 0; x < TILES_X; x++) { + const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + const struct cmd_block_list *list = &bin->commands; + if (list->head != list->tail || list->head->count > 0) { + return FALSE; + } + } + } + return TRUE; +} + + +void +lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y) +{ + struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + struct cmd_block_list *list = &bin->commands; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->count = 0; +} + + +/** + * Set scene to empty state. + */ +void +lp_scene_reset(struct lp_scene *scene ) +{ + unsigned i, j; + + /* Free all but last binner command lists: + */ + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + lp_scene_bin_reset(scene, i, j); + } + } + + assert(lp_scene_is_empty(scene)); + + /* Free all but last binned data block: + */ + { + struct data_block_list *list = &scene->data; + struct data_block *block, *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->used = 0; + } + + /* Release texture refs + */ + { + struct texture_ref *ref, *next, *ref_list = &scene->textures; + for (ref = ref_list->next; ref != ref_list; ref = next) { + next = next_elem(ref); + pipe_texture_reference(&ref->texture, NULL); + FREE(ref); + } + make_empty_list(ref_list); + } +} + + +/** + * Free all data associated with the given bin, but don't free(scene). + */ +void +lp_scene_free_bin_data(struct lp_scene *scene) +{ + unsigned i, j; + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + /* lp_reset_scene() should have been already called */ + assert(bin->commands.head == bin->commands.tail); + FREE(bin->commands.head); + bin->commands.head = NULL; + bin->commands.tail = NULL; + } + + FREE(scene->data.head); + scene->data.head = NULL; + + pipe_mutex_destroy(scene->mutex); +} + + +void +lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ) +{ + assert(lp_scene_is_empty(scene)); + + scene->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; + scene->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; +} + + +void +lp_bin_new_cmd_block( struct cmd_block_list *list ) +{ + struct cmd_block *block = MALLOC_STRUCT(cmd_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; +} + + +void +lp_bin_new_data_block( struct data_block_list *list ) +{ + struct data_block *block = MALLOC_STRUCT(data_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; +} + + +/** Return number of bytes used for all bin data within a scene */ +unsigned +lp_scene_data_size( const struct lp_scene *scene ) +{ + unsigned size = 0; + const struct data_block *block; + for (block = scene->data.head; block; block = block->next) { + size += block->used; + } + return size; +} + + +/** Return number of bytes used for a single bin */ +unsigned +lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) +{ + struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y); + const struct cmd_block *cmd; + unsigned size = 0; + for (cmd = bin->commands.head; cmd; cmd = cmd->next) { + size += (cmd->count * + (sizeof(lp_rast_cmd) + sizeof(union lp_rast_cmd_arg))); + } + return size; +} + + +/** + * Add a reference to a texture by the scene. + */ +void +lp_scene_texture_reference( struct lp_scene *scene, + struct pipe_texture *texture ) +{ + struct texture_ref *ref = CALLOC_STRUCT(texture_ref); + if (ref) { + struct texture_ref *ref_list = &scene->textures; + pipe_texture_reference(&ref->texture, texture); + insert_at_tail(ref_list, ref); + } +} + + +/** + * Does this scene have a reference to the given texture? + */ +boolean +lp_scene_is_texture_referenced( const struct lp_scene *scene, + const struct pipe_texture *texture ) +{ + const struct texture_ref *ref_list = &scene->textures; + const struct texture_ref *ref; + foreach (ref, ref_list) { + if (ref->texture == texture) + return TRUE; + } + return FALSE; +} + + +/** + * Return last command in the bin + */ +static lp_rast_cmd +lp_get_last_command( const struct cmd_bin *bin ) +{ + const struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + if (i > 0) + return tail->cmd[i - 1]; + else + return NULL; +} + + +/** + * Replace the arg of the last command in the bin. + */ +static void +lp_replace_last_command_arg( struct cmd_bin *bin, + const union lp_rast_cmd_arg arg ) +{ + struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + assert(i > 0); + tail->arg[i - 1] = arg; +} + + + +/** + * Put a state-change command into all bins. + * If we find that the last command in a bin was also a state-change + * command, we can simply replace that one with the new one. + */ +void +lp_scene_bin_state_command( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + lp_rast_cmd last_cmd = lp_get_last_command(bin); + if (last_cmd == cmd) { + lp_replace_last_command_arg(bin, arg); + } + else { + lp_scene_bin_command( scene, i, j, cmd, arg ); + } + } + } +} + + +/** advance curr_x,y to the next bin */ +static boolean +next_bin(struct lp_scene *scene) +{ + scene->curr_x++; + if (scene->curr_x >= scene->tiles_x) { + scene->curr_x = 0; + scene->curr_y++; + } + if (scene->curr_y >= scene->tiles_y) { + /* no more bins */ + return FALSE; + } + return TRUE; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ) +{ + scene->curr_x = scene->curr_y = -1; +} + + +/** + * Return pointer to next bin to be rendered. + * The lp_scene::curr_x and ::curr_y fields will be advanced. + * Multiple rendering threads will call this function to get a chunk + * of work (a bin) to work on. + */ +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ) +{ + struct cmd_bin *bin = NULL; + + pipe_mutex_lock(scene->mutex); + + if (scene->curr_x < 0) { + /* first bin */ + scene->curr_x = 0; + scene->curr_y = 0; + } + else if (!next_bin(scene)) { + /* no more bins left */ + goto end; + } + + bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y); + *bin_x = scene->curr_x; + *bin_y = scene->curr_y; + +end: + /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ + pipe_mutex_unlock(scene->mutex); + return bin; +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h new file mode 100644 index 0000000000..fb478cc2eb --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -0,0 +1,301 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + + +/** + * Binner data structures and bin-related functions. + * Note: the "setup" code is concerned with building scenes while + * The "rast" code is concerned with consuming/executing scenes. + */ + +#ifndef LP_SCENE_H +#define LP_SCENE_H + +#include "os/os_thread.h" +#include "lp_tile_soa.h" +#include "lp_rast.h" + + +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. + */ +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 +#define TILES_X (MAXWIDTH / TILE_SIZE) +#define TILES_Y (MAXHEIGHT / TILE_SIZE) + + +#define CMD_BLOCK_MAX 128 +#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) + + + +/* switch to a non-pointer value for this: + */ +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +struct cmd_block { + lp_rast_cmd cmd[CMD_BLOCK_MAX]; + union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; + unsigned count; + struct cmd_block *next; +}; + +struct data_block { + ubyte data[DATA_BLOCK_SIZE]; + unsigned used; + struct data_block *next; +}; + +struct cmd_block_list { + struct cmd_block *head; + struct cmd_block *tail; +}; + +/** + * For each screen tile we have one of these bins. + */ +struct cmd_bin { + struct cmd_block_list commands; +}; + + +/** + * This stores bulk data which is shared by all bins within a scene. + * Examples include triangle data and state data. The commands in + * the per-tile bins will point to chunks of data in this structure. + */ +struct data_block_list { + struct data_block *head; + struct data_block *tail; +}; + + +/** List of texture references */ +struct texture_ref { + struct pipe_texture *texture; + struct texture_ref *prev, *next; /**< linked list w/ u_simple_list.h */ +}; + + +/** + * All bins and bin data are contained here. + * Per-bin data goes into the 'tile' bins. + * Shared data goes into the 'data' buffer. + * + * When there are multiple threads, will want to double-buffer between + * scenes: + */ +struct lp_scene { + struct cmd_bin tile[TILES_X][TILES_Y]; + struct data_block_list data; + + /** the framebuffer to render the scene into */ + struct pipe_framebuffer_state fb; + + /** list of textures referenced by the scene commands */ + struct texture_ref textures; + + boolean write_depth; + + /** + * Number of active tiles in each dimension. + * This basically the framebuffer size divided by tile size + */ + unsigned tiles_x, tiles_y; + + int curr_x, curr_y; /**< for iterating over bins */ + pipe_mutex mutex; +}; + + + +struct lp_scene *lp_scene_create(void); + +void lp_scene_destroy(struct lp_scene *scene); + + +void lp_scene_init(struct lp_scene *scene); + +boolean lp_scene_is_empty(struct lp_scene *scene ); + +void lp_scene_reset(struct lp_scene *scene ); + +void lp_scene_free_bin_data(struct lp_scene *scene); + +void lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ); + +void lp_bin_new_data_block( struct data_block_list *list ); + +void lp_bin_new_cmd_block( struct cmd_block_list *list ); + +unsigned lp_scene_data_size( const struct lp_scene *scene ); + +unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); + +void lp_scene_texture_reference( struct lp_scene *scene, + struct pipe_texture *texture ); + +boolean lp_scene_is_texture_referenced( const struct lp_scene *scene, + const struct pipe_texture *texture ); + + +/** + * Allocate space for a command/data in the bin's data buffer. + * Grow the block list if needed. + */ +static INLINE void * +lp_scene_alloc( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + tail->used += size; + return data; + } +} + + +/** + * As above, but with specific alignment. + */ +static INLINE void * +lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size, + unsigned alignment ) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; + tail->used += offset + size; + return data + offset; + } +} + + +/* Put back data if we decide not to use it, eg. culled triangles. + */ +static INLINE void +lp_scene_putback_data( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + assert(list->tail->used >= size); + list->tail->used -= size; +} + + +/** Return pointer to a particular tile's bin. */ +static INLINE struct cmd_bin * +lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y) +{ + return &scene->tile[x][y]; +} + + +/** Remove all commands from a bin */ +void +lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y); + + +/* Add a command to bin[x][y]. + */ +static INLINE void +lp_scene_bin_command( struct lp_scene *scene, + unsigned x, unsigned y, + lp_rast_cmd cmd, + union lp_rast_cmd_arg arg ) +{ + struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + struct cmd_block_list *list = &bin->commands; + + assert(x < scene->tiles_x); + assert(y < scene->tiles_y); + + if (list->tail->count == CMD_BLOCK_MAX) { + lp_bin_new_cmd_block( list ); + } + + { + struct cmd_block *tail = list->tail; + unsigned i = tail->count; + tail->cmd[i] = cmd; + tail->arg[i] = arg; + tail->count++; + } +} + + +/* Add a command to all active bins. + */ +static INLINE void +lp_scene_bin_everywhere( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ) +{ + unsigned i, j; + for (i = 0; i < scene->tiles_x; i++) + for (j = 0; j < scene->tiles_y; j++) + lp_scene_bin_command( scene, i, j, cmd, arg ); +} + + +void +lp_scene_bin_state_command( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ); + + +static INLINE unsigned +lp_scene_get_num_bins( const struct lp_scene *scene ) +{ + return scene->tiles_x * scene->tiles_y; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ); + +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ); + + +#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c new file mode 100644 index 0000000000..43d74e4d89 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -0,0 +1,122 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + + +/** + * Scene queue. We'll use two queues. One contains "full" scenes which + * are produced by the "setup" code. The other contains "empty" scenes + * which are produced by the "rast" code when it finishes rendering a scene. + */ + +#include "util/u_ringbuffer.h" +#include "util/u_memory.h" +#include "lp_scene_queue.h" + + + +#define MAX_SCENE_QUEUE 4 + +struct scene_packet { + struct util_packet header; + struct lp_scene *scene; +}; + +/** + * A queue of scenes + */ +struct lp_scene_queue +{ + struct util_ringbuffer *ring; +}; + + + +/** Allocate a new scene queue */ +struct lp_scene_queue * +lp_scene_queue_create(void) +{ + struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue); + if (queue == NULL) + return NULL; + + queue->ring = util_ringbuffer_create( MAX_SCENE_QUEUE * + sizeof( struct scene_packet ) / 4); + if (queue->ring == NULL) + goto fail; + + return queue; + +fail: + FREE(queue); + return NULL; +} + + +/** Delete a scene queue */ +void +lp_scene_queue_destroy(struct lp_scene_queue *queue) +{ + util_ringbuffer_destroy(queue->ring); + FREE(queue); +} + + +/** Remove first lp_scene from head of queue */ +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait) +{ + struct scene_packet packet; + enum pipe_error ret; + + ret = util_ringbuffer_dequeue(queue->ring, + &packet.header, + sizeof packet / 4, + wait ); + if (ret != PIPE_OK) + return NULL; + + return packet.scene; +} + + +/** Add an lp_scene to tail of queue */ +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene) +{ + struct scene_packet packet; + + packet.header.dwords = sizeof packet / 4; + packet.header.data24 = 0; + packet.scene = scene; + + util_ringbuffer_enqueue(queue->ring, &packet.header); +} + + + + + diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h new file mode 100644 index 0000000000..fd7c65a2c8 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h @@ -0,0 +1,51 @@ +/************************************************************************** + * + * 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 VMWARE 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. + * + **************************************************************************/ + + +#ifndef LP_SCENE_QUEUE +#define LP_SCENE_QUEUE + +struct lp_scene_queue; +struct lp_scene; + + +struct lp_scene_queue * +lp_scene_queue_create(void); + +void +lp_scene_queue_destroy(struct lp_scene_queue *queue); + +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait); + +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene); + + + + +#endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 9b47415f00..1cd3ea9a84 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -33,9 +33,11 @@ #include "lp_texture.h" #include "lp_buffer.h" +#include "lp_fence.h" #include "lp_winsys.h" #include "lp_jit.h" #include "lp_screen.h" +#include "lp_context.h" #include "lp_debug.h" #ifdef DEBUG @@ -51,6 +53,10 @@ static const struct debug_named_value lp_debug_flags[] = { { "query", DEBUG_QUERY }, { "screen", DEBUG_SCREEN }, { "jit", DEBUG_JIT }, + { "show_tiles", DEBUG_SHOW_TILES }, + { "show_subtiles", DEBUG_SHOW_SUBTILES }, + { "counters", DEBUG_COUNTERS }, + { "nopt", DEBUG_NO_LLVM_OPT }, {NULL, 0} }; #endif @@ -110,6 +116,16 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 0; default: return 0; } @@ -295,10 +311,12 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys) screen->base.is_format_supported = llvmpipe_is_format_supported; screen->base.surface_buffer_create = llvmpipe_surface_buffer_create; + screen->base.context_create = llvmpipe_create_context; screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer; llvmpipe_init_screen_texture_funcs(&screen->base); llvmpipe_init_screen_buffer_funcs(&screen->base); + llvmpipe_init_screen_fence_funcs(&screen->base); lp_jit_screen_init(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index b18f17c0cd..3186069899 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -26,1479 +26,704 @@ **************************************************************************/ /** - * \brief Primitive rasterization/rendering (points, lines, triangles) + * Tiling engine. * - * \author Keith Whitwell <keith@tungstengraphics.com> - * \author Brian Paul + * Builds per-tile display lists and executes them on calls to + * lp_setup_flush(). */ -#include "lp_context.h" -#include "lp_quad.h" -#include "lp_setup.h" -#include "lp_state.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_thread.h" -#include "util/u_format.h" -#include "util/u_math.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" -#include "lp_bld_debug.h" -#include "lp_tile_cache.h" -#include "lp_tile_soa.h" - - -#define DEBUG_VERTS 0 -#define DEBUG_FRAGS 0 - -/** - * Triangle edge info - */ -struct edge { - float dx; /**< X(v1) - X(v0), used only during setup */ - float dy; /**< Y(v1) - Y(v0), used only during setup */ - float dxdy; /**< dx/dy */ - float sx, sy; /**< first sample point coord */ - int lines; /**< number of lines on this edge */ -}; - - -#define MAX_QUADS 16 - +#include "util/u_pack_color.h" +#include "util/u_surface.h" +#include "lp_scene.h" +#include "lp_scene_queue.h" +#include "lp_buffer.h" +#include "lp_texture.h" +#include "lp_debug.h" +#include "lp_fence.h" +#include "lp_rast.h" +#include "lp_setup_context.h" -/** - * Triangle setup info (derived from draw_stage). - * Also used for line drawing (taking some liberties). - */ -struct setup_context { - struct llvmpipe_context *llvmpipe; - - /* Vertices are just an array of floats making up each attribute in - * turn. Currently fixed at 4 floats, but should change in time. - * Codegen will help cope with this. - */ - const float (*vmax)[4]; - const float (*vmid)[4]; - const float (*vmin)[4]; - const float (*vprovoke)[4]; - - struct edge ebot; - struct edge etop; - struct edge emaj; - - float oneoverarea; - int facing; +#include "draw/draw_context.h" +#include "draw/draw_vbuf.h" - float pixel_offset; - struct quad_header quad[MAX_QUADS]; - struct quad_header *quad_ptrs[MAX_QUADS]; - unsigned count; +static void set_scene_state( struct setup_context *, unsigned ); - struct quad_interp_coef coef; - struct { - int left[2]; /**< [0] = row0, [1] = row1 */ - int right[2]; - int y; - } span; +struct lp_scene * +lp_setup_get_current_scene(struct setup_context *setup) +{ + if (!setup->scene) { -#if DEBUG_FRAGS - uint numFragsEmitted; /**< per primitive */ - uint numFragsWritten; /**< per primitive */ -#endif + /* wait for a free/empty scene + */ + setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE); - unsigned winding; /* which winding to cull */ -}; + if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ + lp_scene_set_framebuffer_size(setup->scene, + setup->fb.width, + setup->fb.height); + } + return setup->scene; +} -/** - * Execute fragment shader for the four fragments in the quad. - */ -ALIGN_STACK static void -shade_quads(struct llvmpipe_context *llvmpipe, - struct quad_header *quads[], - unsigned nr) +first_triangle( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]) { - struct lp_fragment_shader *fs = llvmpipe->fs; - struct quad_header *quad = quads[0]; - const unsigned x = quad->input.x0; - const unsigned y = quad->input.y0; - uint8_t *tile; - uint8_t *color; - void *depth; - uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; - unsigned chan_index; - unsigned q; - - assert(fs->current); - if(!fs->current) - return; - - /* Sanity checks */ - assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH); - assert(x % TILE_VECTOR_WIDTH == 0); - assert(y % TILE_VECTOR_HEIGHT == 0); - for (q = 0; q < nr; ++q) { - assert(quads[q]->input.x0 == x + q*2); - assert(quads[q]->input.y0 == y); - } - - /* mask */ - for (q = 0; q < 4; ++q) - for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) - mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0; + set_scene_state( setup, SETUP_ACTIVE ); + lp_setup_choose_triangle( setup ); + setup->triangle( setup, v0, v1, v2 ); +} - /* color buffer */ - if(llvmpipe->framebuffer.nr_cbufs >= 1 && - llvmpipe->framebuffer.cbufs[0]) { - tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y); - color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0); - } - else - color = NULL; - - /* depth buffer */ - if(llvmpipe->zsbuf_map) { - assert((x % 2) == 0); - assert((y % 2) == 0); - depth = llvmpipe->zsbuf_map + - y*llvmpipe->zsbuf_transfer->stride + - 2*x*util_format_get_blocksize(llvmpipe->zsbuf_transfer->texture->format); - } - else - depth = NULL; - - /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ - assert(lp_check_alignment(mask, 16)); - - assert(lp_check_alignment(depth, 16)); - assert(lp_check_alignment(color, 16)); - assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16)); - - /* run shader */ - fs->current->jit_function( &llvmpipe->jit_context, - x, y, - quad->coef->a0, - quad->coef->dadx, - quad->coef->dady, - &mask[0][0], - color, - depth); +static void +first_line( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + set_scene_state( setup, SETUP_ACTIVE ); + lp_setup_choose_line( setup ); + setup->line( setup, v0, v1 ); } +static void +first_point( struct setup_context *setup, + const float (*v0)[4]) +{ + set_scene_state( setup, SETUP_ACTIVE ); + lp_setup_choose_point( setup ); + setup->point( setup, v0 ); +} +static void reset_context( struct setup_context *setup ) +{ + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + /* Reset derived state */ + setup->constants.stored_size = 0; + setup->constants.stored_data = NULL; + setup->fs.stored = NULL; + setup->dirty = ~0; -/** - * Do triangle cull test using tri determinant (sign indicates orientation) - * \return true if triangle is to be culled. - */ -static INLINE boolean -cull_tri(const struct setup_context *setup, float det) -{ - if (det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + /* no current bin */ + setup->scene = NULL; - if ((winding & setup->winding) == 0) - return FALSE; - } + /* Reset some state: + */ + setup->clear.flags = 0; - /* Culled: + /* Have an explicit "start-binning" call and get rid of this + * pointer twiddling? */ - return TRUE; + setup->line = first_line; + setup->point = first_point; + setup->triangle = first_triangle; } - -/** - * Clip setup->quad against the scissor/surface bounds. - */ -static INLINE void -quad_clip( struct setup_context *setup, struct quad_header *quad ) +/** Rasterize all scene's bins */ +static void +lp_setup_rasterize_scene( struct setup_context *setup, + boolean write_depth ) { - const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - - if (quad->input.x0 >= maxx || - quad->input.y0 >= maxy || - quad->input.x0 + 1 < minx || - quad->input.y0 + 1 < miny) { - /* totally clipped */ - quad->inout.mask = 0x0; - return; - } - if (quad->input.x0 < minx) - quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - if (quad->input.y0 < miny) - quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - if (quad->input.x0 == maxx - 1) - quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - if (quad->input.y0 == maxy - 1) - quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); -} + struct lp_scene *scene = lp_setup_get_current_scene(setup); + lp_rasterize_scene(setup->rast, + scene, + &setup->fb, + write_depth); + reset_context( setup ); -/** - * Given an X or Y coordinate, return the block/quad coordinate that it - * belongs to. - */ -static INLINE int block( int x ) -{ - return x & ~(2-1); + LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); } -static INLINE int block_x( int x ) + + +static void +begin_binning( struct setup_context *setup ) { - return x & ~(TILE_VECTOR_WIDTH - 1); + struct lp_scene *scene = lp_setup_get_current_scene(setup); + + LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__, + (setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load", + (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load"); + + if (setup->fb.nr_cbufs) { + if (setup->clear.flags & PIPE_CLEAR_COLOR) + lp_scene_bin_everywhere( scene, + lp_rast_clear_color, + setup->clear.color ); + else + lp_scene_bin_everywhere( scene, + lp_rast_load_color, + lp_rast_arg_null() ); + } + + if (setup->fb.zsbuf) { + if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) + lp_scene_bin_everywhere( scene, + lp_rast_clear_zstencil, + setup->clear.zstencil ); + else + lp_scene_bin_everywhere( scene, + lp_rast_load_zstencil, + lp_rast_arg_null() ); + } + + LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__); } -/** - * Emit a quad (pass to next stage) with clipping. +/* This basically bins and then flushes any outstanding full-screen + * clears. + * + * TODO: fast path for fullscreen clears and no triangles. */ -static INLINE void -clip_emit_quad( struct setup_context *setup, struct quad_header *quad ) +static void +execute_clears( struct setup_context *setup ) { - quad_clip( setup, quad ); - - if (quad->inout.mask) { - struct llvmpipe_context *lp = setup->llvmpipe; - -#if 1 - /* XXX: The blender expects 4 quads. This is far from efficient, but - * until we codegenerate single-quad variants of the fragment pipeline - * we need this hack. */ - const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE; - struct quad_header quads[4]; - struct quad_header *quad_ptrs[4]; - int x0 = block_x(quad->input.x0); - unsigned i; - - assert(nr_quads == 4); - - for(i = 0; i < nr_quads; ++i) { - int x = x0 + 2*i; - if(x == quad->input.x0) - memcpy(&quads[i], quad, sizeof quads[i]); - else { - memset(&quads[i], 0, sizeof quads[i]); - quads[i].input.x0 = x; - quads[i].input.y0 = quad->input.y0; - quads[i].coef = quad->coef; - } - quad_ptrs[i] = &quads[i]; - } + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - shade_quads( lp, quad_ptrs, nr_quads ); -#else - shade_quads( lp, &quad, 1 ); -#endif - } + begin_binning( setup ); + lp_setup_rasterize_scene( setup, TRUE ); } -/** - * Render a horizontal span of quads - */ -static void flush_spans( struct setup_context *setup ) +static void +set_scene_state( struct setup_context *setup, + unsigned new_state ) { - const int step = TILE_VECTOR_WIDTH; - const int xleft0 = setup->span.left[0]; - const int xleft1 = setup->span.left[1]; - const int xright0 = setup->span.right[0]; - const int xright1 = setup->span.right[1]; - - - int minleft = block_x(MIN2(xleft0, xleft1)); - int maxright = MAX2(xright0, xright1); - int x; - - for (x = minleft; x < maxright; x += step) { - unsigned skip_left0 = CLAMP(xleft0 - x, 0, step); - unsigned skip_left1 = CLAMP(xleft1 - x, 0, step); - unsigned skip_right0 = CLAMP(x + step - xright0, 0, step); - unsigned skip_right1 = CLAMP(x + step - xright1, 0, step); - unsigned lx = x; - const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE; - unsigned q = 0; - - unsigned skipmask_left0 = (1U << skip_left0) - 1U; - unsigned skipmask_left1 = (1U << skip_left1) - 1U; - - /* These calculations fail when step == 32 and skip_right == 0. - */ - unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0); - unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1); - - unsigned mask0 = ~skipmask_left0 & ~skipmask_right0; - unsigned mask1 = ~skipmask_left1 & ~skipmask_right1; - - if (mask0 | mask1) { - for(q = 0; q < nr_quads; ++q) { - unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2); - setup->quad[q].input.x0 = lx; - setup->quad[q].input.y0 = setup->span.y; - setup->quad[q].inout.mask = quadmask; - setup->quad_ptrs[q] = &setup->quad[q]; - mask0 >>= 2; - mask1 >>= 2; - lx += 2; - } - assert(!(mask0 | mask1)); + unsigned old_state = setup->state; - shade_quads(setup->llvmpipe, setup->quad_ptrs, nr_quads ); + if (old_state == new_state) + return; + + LP_DBG(DEBUG_SETUP, "%s old %d new %d\n", __FUNCTION__, old_state, new_state); + + switch (new_state) { + case SETUP_ACTIVE: + begin_binning( setup ); + break; + + case SETUP_CLEARED: + if (old_state == SETUP_ACTIVE) { + assert(0); + return; } + break; + + case SETUP_FLUSHED: + if (old_state == SETUP_CLEARED) + execute_clears( setup ); + else + lp_setup_rasterize_scene( setup, TRUE ); + break; } - - setup->span.y = 0; - setup->span.right[0] = 0; - setup->span.right[1] = 0; - setup->span.left[0] = 1000000; /* greater than right[0] */ - setup->span.left[1] = 1000000; /* greater than right[1] */ + setup->state = new_state; } -#if DEBUG_VERTS -static void print_vertex(const struct setup_context *setup, - const float (*v)[4]) +void +lp_setup_flush( struct setup_context *setup, + unsigned flags ) { - int i; - debug_printf(" Vertex: (%p)\n", v); - for (i = 0; i < setup->quad[0].nr_attrs; i++) { - debug_printf(" %d: %f %f %f %f\n", i, - v[i][0], v[i][1], v[i][2], v[i][3]); - if (util_is_inf_or_nan(v[i][0])) { - debug_printf(" NaN!\n"); - } - } + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + + set_scene_state( setup, SETUP_FLUSHED ); } -#endif -/** - * Sort the vertices from top to bottom order, setting up the triangle - * edge fields (ebot, emaj, etop). - * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise - */ -static boolean setup_sort_vertices( struct setup_context *setup, - float det, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) -{ - setup->vprovoke = v2; - - /* determine bottom to top order of vertices */ - { - float y0 = v0[0][1]; - float y1 = v1[0][1]; - float y2 = v2[0][1]; - if (y0 <= y1) { - if (y1 <= y2) { - /* y0<=y1<=y2 */ - setup->vmin = v0; - setup->vmid = v1; - setup->vmax = v2; - } - else if (y2 <= y0) { - /* y2<=y0<=y1 */ - setup->vmin = v2; - setup->vmid = v0; - setup->vmax = v1; - } - else { - /* y0<=y2<=y1 */ - setup->vmin = v0; - setup->vmid = v2; - setup->vmax = v1; - } - } - else { - if (y0 <= y2) { - /* y1<=y0<=y2 */ - setup->vmin = v1; - setup->vmid = v0; - setup->vmax = v2; - } - else if (y2 <= y1) { - /* y2<=y1<=y0 */ - setup->vmin = v2; - setup->vmid = v1; - setup->vmax = v0; - } - else { - /* y1<=y2<=y0 */ - setup->vmin = v1; - setup->vmid = v2; - setup->vmax = v0; - } - } - } - setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; - setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; - setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; - setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; - setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; - setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; - - /* - * Compute triangle's area. Use 1/area to compute partial - * derivatives of attributes later. - * - * The area will be the same as prim->det, but the sign may be - * different depending on how the vertices get sorted above. - * - * To determine whether the primitive is front or back facing we - * use the prim->det value because its sign is correct. - */ - { - const float area = (setup->emaj.dx * setup->ebot.dy - - setup->ebot.dx * setup->emaj.dy); - - setup->oneoverarea = 1.0f / area; - - /* - debug_printf("%s one-over-area %f area %f det %f\n", - __FUNCTION__, setup->oneoverarea, area, det ); - */ - if (util_is_inf_or_nan(setup->oneoverarea)) - return FALSE; - } +void +lp_setup_bind_framebuffer( struct setup_context *setup, + const struct pipe_framebuffer_state *fb ) +{ + struct lp_scene *scene = lp_setup_get_current_scene(setup); - /* We need to know if this is a front or back-facing triangle for: - * - the GLSL gl_FrontFacing fragment attribute (bool) - * - two-sided stencil test - */ - setup->facing = - ((det > 0.0) ^ - (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW)); + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - /* Prepare pixel offset for rasterisation: - * - pixel center (0.5, 0.5) for GL, or - * - assume (0.0, 0.0) for other APIs. - */ - if (setup->llvmpipe->rasterizer->gl_rasterization_rules) { - setup->pixel_offset = 0.5f; - } else { - setup->pixel_offset = 0.0f; - } + set_scene_state( setup, SETUP_FLUSHED ); - return TRUE; -} + /* re-get scene pointer, may have a new scene after flushing */ + scene = lp_setup_get_current_scene(setup); + util_copy_framebuffer_state(&setup->fb, fb); -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a triangle. - */ -static void tri_pos_coeff( struct setup_context *setup, - uint vertSlot, unsigned i) -{ - float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; - float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - assert(i <= 3); - - setup->coef.dadx[0][i] = dadx; - setup->coef.dady[0][i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (pixel_offset, pixel_offset). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ + lp_scene_set_framebuffer_size(scene, setup->fb.width, setup->fb.height); } -/** - * Compute a0 for a constant-valued coefficient (GL_FLAT shading). - * The value value comes from vertex[slot][i]. - * The result will be put into setup->coef[slot].a0[i]. - * \param slot which attribute slot - * \param i which component of the slot (0..3) - */ -static void const_pos_coeff( struct setup_context *setup, - uint vertSlot, unsigned i) +void +lp_setup_clear( struct setup_context *setup, + const float *color, + double depth, + unsigned stencil, + unsigned flags ) { - setup->coef.dadx[0][i] = 0; - setup->coef.dady[0][i] = 0; - - /* need provoking vertex info! - */ - setup->coef.a0[0][i] = setup->vprovoke[vertSlot][i]; -} + struct lp_scene *scene = lp_setup_get_current_scene(setup); + unsigned i; + LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); -/** - * Compute a0 for a constant-valued coefficient (GL_FLAT shading). - * The value value comes from vertex[slot][i]. - * The result will be put into setup->coef[slot].a0[i]. - * \param slot which attribute slot - * \param i which component of the slot (0..3) - */ -static void const_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - setup->coef.dadx[1 + attrib][i] = 0; - setup->coef.dady[1 + attrib][i] = 0; - /* need provoking vertex info! - */ - setup->coef.a0[1 + attrib][i] = setup->vprovoke[vertSlot][i]; + if (flags & PIPE_CLEAR_COLOR) { + for (i = 0; i < 4; ++i) + setup->clear.color.clear_color[i] = float_to_ubyte(color[i]); } -} - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a triangle. - */ -static void tri_linear_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; - float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - assert(i <= 3); - - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (0.5, 0.5). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ + if (flags & PIPE_CLEAR_DEPTHSTENCIL) { + setup->clear.zstencil.clear_zstencil = + util_pack_z_stencil(setup->fb.zsbuf->format, + depth, + stencil); } -} + if (setup->state == SETUP_ACTIVE) { + /* Add the clear to existing scene. In the unusual case where + * both color and depth-stencil are being cleared when there's + * already been some rendering, we could discard the currently + * binned scene and start again, but I don't see that as being + * a common usage. + */ + if (flags & PIPE_CLEAR_COLOR) + lp_scene_bin_everywhere( scene, + lp_rast_clear_color, + setup->clear.color ); -/** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a triangle. - * We basically multiply the vertex value by 1/w before computing - * the plane coefficients (a0, dadx, dady). - * Later, when we compute the value at a particular fragment position we'll - * divide the interpolated value by the interpolated W at that fragment. - */ -static void tri_persp_coeff( struct setup_context *setup, - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - /* premultiply by 1/w (v[0][3] is always W): + if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) + lp_scene_bin_everywhere( scene, + lp_rast_clear_zstencil, + setup->clear.zstencil ); + } + else { + /* Put ourselves into the 'pre-clear' state, specifically to try + * and accumulate multiple clears to color and depth_stencil + * buffers which the app or state-tracker might issue + * separately. */ - float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; - float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; - float botda = mida - mina; - float majda = maxa - mina; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - /* - debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, - setup->vmin[vertSlot][i], - setup->vmid[vertSlot][i], - setup->vmax[vertSlot][i] - ); - */ - assert(i <= 3); - - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (mina - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); + set_scene_state( setup, SETUP_CLEARED ); + + setup->clear.flags |= flags; } } /** - * Special coefficient setup for gl_FragCoord. - * X and Y are trivial, though Y has to be inverted for OpenGL. - * Z and W are copied from posCoef which should have already been computed. - * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. + * Emit a fence. */ -static void -setup_fragcoord_coeff(struct setup_context *setup, uint slot) +struct pipe_fence_handle * +lp_setup_fence( struct setup_context *setup ) { - /*X*/ - setup->coef.a0[1 + slot][0] = 0; - setup->coef.dadx[1 + slot][0] = 1.0; - setup->coef.dady[1 + slot][0] = 0.0; - /*Y*/ - setup->coef.a0[1 + slot][1] = 0.0; - setup->coef.dadx[1 + slot][1] = 0.0; - setup->coef.dady[1 + slot][1] = 1.0; - /*Z*/ - setup->coef.a0[1 + slot][2] = setup->coef.a0[0][2]; - setup->coef.dadx[1 + slot][2] = setup->coef.dadx[0][2]; - setup->coef.dady[1 + slot][2] = setup->coef.dady[0][2]; - /*W*/ - setup->coef.a0[1 + slot][3] = setup->coef.a0[0][3]; - setup->coef.dadx[1 + slot][3] = setup->coef.dadx[0][3]; - setup->coef.dady[1 + slot][3] = setup->coef.dady[0][3]; -} + struct lp_scene *scene = lp_setup_get_current_scene(setup); + const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */ + struct lp_fence *fence = lp_fence_create(rank); + LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank); + set_scene_state( setup, SETUP_ACTIVE ); -/** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. - */ -static void setup_tri_coefficients( struct setup_context *setup ) -{ - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; + /* insert the fence into all command bins */ + lp_scene_bin_everywhere( scene, + lp_rast_fence, + lp_rast_arg_fence(fence) ); - /* z and w are done by linear interpolation: - */ - tri_pos_coeff(setup, 0, 2); - tri_pos_coeff(setup, 0, 3); + return (struct pipe_fence_handle *) fence; +} - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_LINEAR: - tri_linear_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - tri_persp_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } +void +lp_setup_set_triangle_state( struct setup_context *setup, + unsigned cull_mode, + boolean ccw_is_frontface, + boolean scissor ) +{ + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } - } + setup->ccw_is_frontface = ccw_is_frontface; + setup->cullmode = cull_mode; + setup->triangle = first_triangle; + setup->scissor_test = scissor; } -static void setup_tri_edges( struct setup_context *setup ) +void +lp_setup_set_fs_inputs( struct setup_context *setup, + const struct lp_shader_input *input, + unsigned nr ) { - float vmin_x = setup->vmin[0][0] + setup->pixel_offset; - float vmid_x = setup->vmid[0][0] + setup->pixel_offset; - - float vmin_y = setup->vmin[0][1] - setup->pixel_offset; - float vmid_y = setup->vmid[0][1] - setup->pixel_offset; - float vmax_y = setup->vmax[0][1] - setup->pixel_offset; - - setup->emaj.sy = ceilf(vmin_y); - setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); - setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; - setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; - - setup->etop.sy = ceilf(vmid_y); - setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); - setup->etop.dxdy = setup->etop.dx / setup->etop.dy; - setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; - - setup->ebot.sy = ceilf(vmin_y); - setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); - setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; - setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; -} + LP_DBG(DEBUG_SETUP, "%s %p %u\n", __FUNCTION__, (void *) input, nr); + memcpy( setup->fs.input, input, nr * sizeof input[0] ); + setup->fs.nr_inputs = nr; +} -/** - * Render the upper or lower half of a triangle. - * Scissoring/cliprect is applied here too. - */ -static void subtriangle( struct setup_context *setup, - struct edge *eleft, - struct edge *eright, - unsigned lines ) +void +lp_setup_set_fs_functions( struct setup_context *setup, + lp_jit_frag_func jit_function0, + lp_jit_frag_func jit_function1, + boolean opaque ) { - const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - int y, start_y, finish_y; - int sy = (int)eleft->sy; - - assert((int)eleft->sy == (int) eright->sy); - - /* clip top/bottom */ - start_y = sy; - if (start_y < miny) - start_y = miny; - - finish_y = sy + lines; - if (finish_y > maxy) - finish_y = maxy; - - start_y -= sy; - finish_y -= sy; - - /* - debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); - */ - - for (y = start_y; y < finish_y; y++) { - - /* avoid accumulating adds as floats don't have the precision to - * accurately iterate large triangle edges that way. luckily we - * can just multiply these days. - * - * this is all drowned out by the attribute interpolation anyway. - */ - int left = (int)(eleft->sx + y * eleft->dxdy); - int right = (int)(eright->sx + y * eright->dxdy); - - /* clip left/right */ - if (left < minx) - left = minx; - if (right > maxx) - right = maxx; - - if (left < right) { - int _y = sy + y; - if (block(_y) != setup->span.y) { - flush_spans(setup); - setup->span.y = block(_y); - } + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function0); + /* FIXME: reference count */ - setup->span.left[_y&1] = left; - setup->span.right[_y&1] = right; - } - } - - - /* save the values so that emaj can be restarted: - */ - eleft->sx += lines * eleft->dxdy; - eright->sx += lines * eright->dxdy; - eleft->sy += lines; - eright->sy += lines; + setup->fs.current.jit_function[0] = jit_function0; + setup->fs.current.jit_function[1] = jit_function1; + setup->fs.current.opaque = opaque; + setup->dirty |= LP_SETUP_NEW_FS; } - -/** - * Recalculate prim's determinant. This is needed as we don't have - * get this information through the vbuf_render interface & we must - * calculate it here. - */ -static float -calc_det( const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) +void +lp_setup_set_fs_constants(struct setup_context *setup, + struct pipe_buffer *buffer) { - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0][0] - v2[0][0]; - const float ey = v0[0][1] - v2[0][1]; - const float fx = v1[0][0] - v2[0][0]; - const float fy = v1[0][1] - v2[0][1]; - - /* det = cross(e,f).z */ - return ex * fy - ey * fx; + LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer); + + pipe_buffer_reference(&setup->constants.current, buffer); + + setup->dirty |= LP_SETUP_NEW_CONSTANTS; } -/** - * Do setup for triangle rasterization, then render the triangle. - */ -void llvmpipe_setup_tri( struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) +void +lp_setup_set_alpha_ref_value( struct setup_context *setup, + float alpha_ref_value ) { - float det; - -#if DEBUG_VERTS - debug_printf("Setup triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif + LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value); - if (setup->llvmpipe->no_rast) - return; - - det = calc_det(v0, v1, v2); - /* - debug_printf("%s\n", __FUNCTION__ ); - */ + if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) { + setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value; + setup->dirty |= LP_SETUP_NEW_FS; + } +} -#if DEBUG_FRAGS - setup->numFragsEmitted = 0; - setup->numFragsWritten = 0; -#endif +void +lp_setup_set_blend_color( struct setup_context *setup, + const struct pipe_blend_color *blend_color ) +{ + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (cull_tri( setup, det )) - return; + assert(blend_color); - if (!setup_sort_vertices( setup, det, v0, v1, v2 )) - return; - setup_tri_coefficients( setup ); - setup_tri_edges( setup ); + if(memcmp(&setup->blend_color.current, blend_color, sizeof *blend_color) != 0) { + memcpy(&setup->blend_color.current, blend_color, sizeof *blend_color); + setup->dirty |= LP_SETUP_NEW_BLEND_COLOR; + } +} - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_TRIANGLES); - setup->span.y = 0; - setup->span.right[0] = 0; - setup->span.right[1] = 0; - /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ +void +lp_setup_set_scissor( struct setup_context *setup, + const struct pipe_scissor_state *scissor ) +{ + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - /* init_constant_attribs( setup ); */ + assert(scissor); - if (setup->oneoverarea < 0.0) { - /* emaj on left: - */ - subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); - subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); - } - else { - /* emaj on right: - */ - subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); - subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); + if (memcmp(&setup->scissor.current, scissor, sizeof(*scissor)) != 0) { + setup->scissor.current = *scissor; /* struct copy */ + setup->dirty |= LP_SETUP_NEW_SCISSOR; } - - flush_spans( setup ); - -#if DEBUG_FRAGS - printf("Tri: %u frags emitted, %u written\n", - setup->numFragsEmitted, - setup->numFragsWritten); -#endif } - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a line. - */ -static void -linear_pos_coeff(struct setup_context *setup, - uint vertSlot, uint i) +void +lp_setup_set_flatshade_first( struct setup_context *setup, + boolean flatshade_first ) { - const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[0][i] = dadx; - setup->coef.dady[0][i] = dady; - setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); + setup->flatshade_first = flatshade_first; } -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a line. - */ -static void -line_linear_coeff(struct setup_context *setup, - unsigned attrib, - uint vertSlot) +void +lp_setup_set_vertex_info( struct setup_context *setup, + struct vertex_info *vertex_info ) { - unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); - } + /* XXX: just silently holding onto the pointer: + */ + setup->vertex_info = vertex_info; } /** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a line. + * Called during state validation when LP_NEW_TEXTURE is set. */ -static void -line_persp_coeff(struct setup_context *setup, - unsigned attrib, - uint vertSlot) +void +lp_setup_set_sampler_textures( struct setup_context *setup, + unsigned num, struct pipe_texture **texture) { unsigned i; - for (i = 0; i < NUM_CHANNELS; ++i) { - /* XXX double-check/verify this arithmetic */ - const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; - const float da = a1 - a0; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - setup->coef.dadx[1 + attrib][i] = dadx; - setup->coef.dady[1 + attrib][i] = dady; - setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] - - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + - dady * (setup->vmin[0][1] - setup->pixel_offset))); + + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); + + assert(num <= PIPE_MAX_SAMPLERS); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + if(tex) { + struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); + struct lp_jit_texture *jit_tex; + jit_tex = &setup->fs.current.jit_context.textures[i]; + jit_tex->width = tex->width0; + jit_tex->height = tex->height0; + jit_tex->stride = lp_tex->stride[0]; + if(!lp_tex->dt) + jit_tex->data = lp_tex->data; + else + /* FIXME: map the rendertarget */ + assert(0); + + /* the scene references this texture */ + { + struct lp_scene *scene = lp_setup_get_current_scene(setup); + lp_scene_texture_reference(scene, tex); + } + } } + + setup->dirty |= LP_SETUP_NEW_FS; } /** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmax are initialized. + * Is the given texture referenced by any scene? + * Note: we have to check all scenes including any scenes currently + * being rendered and the current scene being built. */ -static INLINE boolean -setup_line_coefficients(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) +unsigned +lp_setup_is_texture_referenced( const struct setup_context *setup, + const struct pipe_texture *texture ) { - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; - float area; - - /* use setup->vmin, vmax to point to vertices */ - if (llvmpipe->rasterizer->flatshade_first) - setup->vprovoke = v0; - else - setup->vprovoke = v1; - setup->vmin = v0; - setup->vmax = v1; - - setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; - setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; - - /* NOTE: this is not really area but something proportional to it */ - area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; - if (area == 0.0f || util_is_inf_or_nan(area)) - return FALSE; - setup->oneoverarea = 1.0f / area; - - /* z and w are done by linear interpolation: - */ - linear_pos_coeff(setup, 0, 2); - linear_pos_coeff(setup, 0, 3); - - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; - - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_LINEAR: - line_linear_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - line_persp_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } + unsigned i; - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } + /* check the render targets */ + for (i = 0; i < setup->fb.nr_cbufs; i++) { + if (setup->fb.cbufs[i]->texture == texture) + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + } + if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) { + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; } - return TRUE; -} - -/** - * Plot a pixel in a line segment. - */ -static INLINE void -plot(struct setup_context *setup, int x, int y) -{ - const int iy = y & 1; - const int ix = x & 1; - const int quadX = x - ix; - const int quadY = y - iy; - const int mask = (1 << ix) << (2 * iy); - - if (quadX != setup->quad[0].input.x0 || - quadY != setup->quad[0].input.y0) - { - /* flush prev quad, start new quad */ - - if (setup->quad[0].input.x0 != -1) - clip_emit_quad( setup, &setup->quad[0] ); - - setup->quad[0].input.x0 = quadX; - setup->quad[0].input.y0 = quadY; - setup->quad[0].inout.mask = 0x0; + /* check textures referenced by the scene */ + for (i = 0; i < Elements(setup->scenes); i++) { + if (lp_scene_is_texture_referenced(setup->scenes[i], texture)) { + return PIPE_REFERENCED_FOR_READ; + } } - setup->quad[0].inout.mask |= mask; + return PIPE_UNREFERENCED; } /** - * Do setup for line rasterization, then render the line. - * Single-pixel width, no stipple, etc. We rely on the 'draw' module - * to handle stippling and wide lines. + * Called by vbuf code when we're about to draw something. */ void -llvmpipe_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]) +lp_setup_update_state( struct setup_context *setup ) { - int x0 = (int) v0[0][0]; - int x1 = (int) v1[0][0]; - int y0 = (int) v0[0][1]; - int y1 = (int) v1[0][1]; - int dx = x1 - x0; - int dy = y1 - y0; - int xstep, ystep; - -#if DEBUG_VERTS - debug_printf("Setup line:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); -#endif - - if (setup->llvmpipe->no_rast) - return; - - if (dx == 0 && dy == 0) - return; + struct lp_scene *scene = lp_setup_get_current_scene(setup); - if (!setup_line_coefficients(setup, v0, v1)) - return; - - assert(v0[0][0] < 1.0e9); - assert(v0[0][1] < 1.0e9); - assert(v1[0][0] < 1.0e9); - assert(v1[0][1] < 1.0e9); - - if (dx < 0) { - dx = -dx; /* make positive */ - xstep = -1; - } - else { - xstep = 1; - } + LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (dy < 0) { - dy = -dy; /* make positive */ - ystep = -1; - } - else { - ystep = 1; - } + assert(setup->fs.current.jit_function); - assert(dx >= 0); - assert(dy >= 0); - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_LINES); + if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) { + uint8_t *stored; + unsigned i, j; - setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1; - setup->quad[0].inout.mask = 0x0; + stored = lp_scene_alloc_aligned(scene, 4 * 16, 16); - /* XXX temporary: set coverage to 1.0 so the line appears - * if AA mode happens to be enabled. - */ - setup->quad[0].input.coverage[0] = - setup->quad[0].input.coverage[1] = - setup->quad[0].input.coverage[2] = - setup->quad[0].input.coverage[3] = 1.0; - - if (dx > dy) { - /*** X-major line ***/ - int i; - const int errorInc = dy + dy; - int error = errorInc - dx; - const int errorDec = error - dx; - - for (i = 0; i < dx; i++) { - plot(setup, x0, y0); - - x0 += xstep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - y0 += ystep; - } - } - } - else { - /*** Y-major line ***/ - int i; - const int errorInc = dx + dx; - int error = errorInc - dy; - const int errorDec = error - dy; - - for (i = 0; i < dy; i++) { - plot(setup, x0, y0); - - y0 += ystep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - x0 += xstep; - } + /* smear each blend color component across 16 ubyte elements */ + for (i = 0; i < 4; ++i) { + uint8_t c = float_to_ubyte(setup->blend_color.current.color[i]); + for (j = 0; j < 16; ++j) + stored[i*16 + j] = c; } - } - /* draw final quad */ - if (setup->quad[0].inout.mask) { - clip_emit_quad( setup, &setup->quad[0] ); + setup->blend_color.stored = stored; + + setup->fs.current.jit_context.blend_color = setup->blend_color.stored; + setup->dirty |= LP_SETUP_NEW_FS; } -} + if (setup->dirty & LP_SETUP_NEW_SCISSOR) { + float *stored; -static void -point_persp_coeff(struct setup_context *setup, - const float (*vert)[4], - unsigned attrib, - uint vertSlot) -{ - unsigned i; - for(i = 0; i < NUM_CHANNELS; ++i) { - setup->coef.dadx[1 + attrib][i] = 0.0F; - setup->coef.dady[1 + attrib][i] = 0.0F; - setup->coef.a0[1 + attrib][i] = vert[vertSlot][i] * vert[0][3]; - } -} + stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16); + stored[0] = (float) setup->scissor.current.minx; + stored[1] = (float) setup->scissor.current.miny; + stored[2] = (float) setup->scissor.current.maxx; + stored[3] = (float) setup->scissor.current.maxy; -/** - * Do setup for point rasterization, then render the point. - * Round or square points... - * XXX could optimize a lot for 1-pixel points. - */ -void -llvmpipe_setup_point( struct setup_context *setup, - const float (*v0)[4] ) -{ - struct llvmpipe_context *llvmpipe = setup->llvmpipe; - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - const int sizeAttr = setup->llvmpipe->psize_slot; - const float size - = sizeAttr > 0 ? v0[sizeAttr][0] - : setup->llvmpipe->rasterizer->point_size; - const float halfSize = 0.5F * size; - const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; - const float x = v0[0][0]; /* Note: data[0] is always position */ - const float y = v0[0][1]; - const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); - uint fragSlot; - -#if DEBUG_VERTS - debug_printf("Setup point:\n"); - print_vertex(setup, v0); -#endif - - if (llvmpipe->no_rast) - return; + setup->scissor.stored = stored; - assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_POINTS); - - /* For points, all interpolants are constant-valued. - * However, for point sprites, we'll need to setup texcoords appropriately. - * XXX: which coefficients are the texcoords??? - * We may do point sprites as textured quads... - * - * KW: We don't know which coefficients are texcoords - ultimately - * the choice of what interpolation mode to use for each attribute - * should be determined by the fragment program, using - * per-attribute declaration statements that include interpolation - * mode as a parameter. So either the fragment program will have - * to be adjusted for pointsprite vs normal point behaviour, or - * otherwise a special interpolation mode will have to be defined - * which matches the required behaviour for point sprites. But - - * the latter is not a feature of normal hardware, and as such - * probably should be ruled out on that basis. - */ - setup->vprovoke = v0; + setup->fs.current.jit_context.scissor_xmin = stored[0]; + setup->fs.current.jit_context.scissor_ymin = stored[1]; + setup->fs.current.jit_context.scissor_xmax = stored[2]; + setup->fs.current.jit_context.scissor_ymax = stored[3]; - /* setup Z, W */ - const_pos_coeff(setup, 0, 2); - const_pos_coeff(setup, 0, 3); + setup->dirty |= LP_SETUP_NEW_FS; + } - for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->attrib[fragSlot].src_index; + if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { + struct pipe_buffer *buffer = setup->constants.current; - switch (vinfo->attrib[fragSlot].interp_mode) { - case INTERP_CONSTANT: - /* fall-through */ - case INTERP_LINEAR: - const_coeff(setup, fragSlot, vertSlot); - break; - case INTERP_PERSPECTIVE: - point_persp_coeff(setup, setup->vprovoke, fragSlot, vertSlot); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } + if(buffer) { + unsigned current_size = buffer->size; + const void *current_data = llvmpipe_buffer(buffer)->data; - if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { - setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing; - setup->coef.dadx[1 + fragSlot][0] = 0.0; - setup->coef.dady[1 + fragSlot][0] = 0.0; - } - } + /* TODO: copy only the actually used constants? */ + if(setup->constants.stored_size != current_size || + !setup->constants.stored_data || + memcmp(setup->constants.stored_data, + current_data, + current_size) != 0) { + void *stored; - if (halfSize <= 0.5 && !round) { - /* special case for 1-pixel points */ - const int ix = ((int) x) & 1; - const int iy = ((int) y) & 1; - setup->quad[0].input.x0 = (int) x - ix; - setup->quad[0].input.y0 = (int) y - iy; - setup->quad[0].inout.mask = (1 << ix) << (2 * iy); - clip_emit_quad( setup, &setup->quad[0] ); - } - else { - if (round) { - /* rounded points */ - const int ixmin = block((int) (x - halfSize)); - const int ixmax = block((int) (x + halfSize)); - const int iymin = block((int) (y - halfSize)); - const int iymax = block((int) (y + halfSize)); - const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - const float rmax = halfSize + 0.7071F; - const float rmin2 = MAX2(0.0F, rmin * rmin); - const float rmax2 = rmax * rmax; - const float cscale = 1.0F / (rmax2 - rmin2); - int ix, iy; - - for (iy = iymin; iy <= iymax; iy += 2) { - for (ix = ixmin; ix <= ixmax; ix += 2) { - float dx, dy, dist2, cover; - - setup->quad[0].inout.mask = 0x0; - - dx = (ix + 0.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_TOP_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_TOP_RIGHT; - } - - dx = (ix + 0.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); - setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT; - } - - if (setup->quad[0].inout.mask) { - setup->quad[0].input.x0 = ix; - setup->quad[0].input.y0 = iy; - clip_emit_quad( setup, &setup->quad[0] ); - } + stored = lp_scene_alloc(scene, current_size); + if(stored) { + memcpy(stored, + current_data, + current_size); + setup->constants.stored_size = current_size; + setup->constants.stored_data = stored; } } } else { - /* square points */ - const int xmin = (int) (x + 0.75 - halfSize); - const int ymin = (int) (y + 0.25 - halfSize); - const int xmax = xmin + (int) size; - const int ymax = ymin + (int) size; - /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ - const int ixmin = block(xmin); - const int ixmax = block(xmax - 1); - const int iymin = block(ymin); - const int iymax = block(ymax - 1); - int ix, iy; - - /* - debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); - */ - for (iy = iymin; iy <= iymax; iy += 2) { - uint rowMask = 0xf; - if (iy < ymin) { - /* above the top edge */ - rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - } - if (iy + 1 >= ymax) { - /* below the bottom edge */ - rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); - } + setup->constants.stored_size = 0; + setup->constants.stored_data = NULL; + } - for (ix = ixmin; ix <= ixmax; ix += 2) { - uint mask = rowMask; - - if (ix < xmin) { - /* fragment is past left edge of point, turn off left bits */ - mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - } - if (ix + 1 >= xmax) { - /* past the right edge */ - mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - } - - setup->quad[0].inout.mask = mask; - setup->quad[0].input.x0 = ix; - setup->quad[0].input.y0 = iy; - clip_emit_quad( setup, &setup->quad[0] ); - } + setup->fs.current.jit_context.constants = setup->constants.stored_data; + setup->dirty |= LP_SETUP_NEW_FS; + } + + + if(setup->dirty & LP_SETUP_NEW_FS) { + if(!setup->fs.stored || + memcmp(setup->fs.stored, + &setup->fs.current, + sizeof setup->fs.current) != 0) { + /* The fs state that's been stored in the scene is different from + * the new, current state. So allocate a new lp_rast_state object + * and append it to the bin's setup data buffer. + */ + struct lp_rast_state *stored = + (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored); + if(stored) { + memcpy(stored, + &setup->fs.current, + sizeof setup->fs.current); + setup->fs.stored = stored; + + /* put the state-set command into all bins */ + lp_scene_bin_state_command( scene, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); } } } + + setup->dirty = 0; + + assert(setup->fs.stored); } -void llvmpipe_setup_prepare( struct setup_context *setup ) + + +/* Only caller is lp_setup_vbuf_destroy() + */ +void +lp_setup_destroy( struct setup_context *setup ) { - struct llvmpipe_context *lp = setup->llvmpipe; + reset_context( setup ); - if (lp->dirty) { - llvmpipe_update_derived(lp); - } + pipe_buffer_reference(&setup->constants.current, NULL); - if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && - lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && - lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { - /* we'll do culling */ - setup->winding = lp->rasterizer->cull_mode; - } - else { - /* 'draw' will do culling */ - setup->winding = PIPE_WINDING_NONE; + /* free the scenes in the 'empty' queue */ + while (1) { + struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE); + if (!scene) + break; + lp_scene_destroy(scene); } -} - + lp_rast_destroy( setup->rast ); -void llvmpipe_setup_destroy_context( struct setup_context *setup ) -{ - align_free( setup ); + FREE( setup ); } /** - * Create a new primitive setup/render stage. + * Create a new primitive tiling engine. Plug it into the backend of + * the draw module. Currently also creates a rasterizer to use with + * it. */ -struct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe ) +struct setup_context * +lp_setup_create( struct pipe_screen *screen, + struct draw_context *draw ) { - struct setup_context *setup; unsigned i; + struct setup_context *setup = CALLOC_STRUCT(setup_context); - setup = align_malloc(sizeof(struct setup_context), 16); if (!setup) return NULL; - memset(setup, 0, sizeof *setup); - setup->llvmpipe = llvmpipe; + lp_setup_init_vbuf(setup); + + setup->empty_scenes = lp_scene_queue_create(); + if (!setup->empty_scenes) + goto fail; - for (i = 0; i < MAX_QUADS; i++) { - setup->quad[i].coef = &setup->coef; + setup->rast = lp_rast_create( screen, setup->empty_scenes ); + if (!setup->rast) + goto fail; + + setup->vbuf = draw_vbuf_stage(draw, &setup->base); + if (!setup->vbuf) + goto fail; + + draw_set_rasterize_stage(draw, setup->vbuf); + draw_set_render(draw, &setup->base); + + /* create some empty scenes */ + for (i = 0; i < MAX_SCENES; i++) { + setup->scenes[i] = lp_scene_create(); + lp_scene_enqueue(setup->empty_scenes, setup->scenes[i]); } - setup->span.left[0] = 1000000; /* greater than right[0] */ - setup->span.left[1] = 1000000; /* greater than right[1] */ + setup->triangle = first_triangle; + setup->line = first_line; + setup->point = first_point; + + setup->dirty = ~0; return setup; + +fail: + if (setup->rast) + lp_rast_destroy( setup->rast ); + + if (setup->vbuf) + ; + + if (setup->empty_scenes) + lp_scene_queue_destroy(setup->empty_scenes); + + FREE(setup); + return NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 89c43da046..0e155a7dc3 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -27,27 +27,113 @@ #ifndef LP_SETUP_H #define LP_SETUP_H -struct setup_context; -struct llvmpipe_context; +#include "pipe/p_compiler.h" +#include "lp_jit.h" + +struct draw_context; +struct vertex_info; + +enum lp_interp { + LP_INTERP_CONSTANT, + LP_INTERP_LINEAR, + LP_INTERP_PERSPECTIVE, + LP_INTERP_POSITION, + LP_INTERP_FACING +}; + +/* Describes how to generate all the fragment shader inputs from the + * the vertices passed into our triangle/line/point functions. + * + * Vertices are treated as an array of float[4] values, indexed by + * src_index. + */ +struct lp_shader_input { + enum lp_interp interp; /* how to interpolate values */ + unsigned src_index; /* where to find values in incoming vertices */ +}; + +struct pipe_texture; +struct pipe_surface; +struct pipe_buffer; +struct pipe_blend_color; +struct pipe_screen; +struct pipe_framebuffer_state; +struct lp_fragment_shader; +struct lp_jit_context; + +struct setup_context * +lp_setup_create( struct pipe_screen *screen, + struct draw_context *draw ); + +void +lp_setup_clear(struct setup_context *setup, + const float *clear_color, + double clear_depth, + unsigned clear_stencil, + unsigned flags); + +struct pipe_fence_handle * +lp_setup_fence( struct setup_context *setup ); + + +void +lp_setup_flush( struct setup_context *setup, + unsigned flags ); + + +void +lp_setup_bind_framebuffer( struct setup_context *setup, + const struct pipe_framebuffer_state *fb ); void -llvmpipe_setup_tri( struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ); +lp_setup_set_triangle_state( struct setup_context *setup, + unsigned cullmode, + boolean front_is_ccw, + boolean scissor ); void -llvmpipe_setup_line(struct setup_context *setup, - const float (*v0)[4], - const float (*v1)[4]); +lp_setup_set_fs_inputs( struct setup_context *setup, + const struct lp_shader_input *interp, + unsigned nr ); void -llvmpipe_setup_point( struct setup_context *setup, - const float (*v0)[4] ); +lp_setup_set_fs_functions( struct setup_context *setup, + lp_jit_frag_func jit_function0, + lp_jit_frag_func jit_function1, + boolean opaque ); +void +lp_setup_set_fs_constants(struct setup_context *setup, + struct pipe_buffer *buffer); + + +void +lp_setup_set_alpha_ref_value( struct setup_context *setup, + float alpha_ref_value ); + +void +lp_setup_set_blend_color( struct setup_context *setup, + const struct pipe_blend_color *blend_color ); + +void +lp_setup_set_scissor( struct setup_context *setup, + const struct pipe_scissor_state *scissor ); + +void +lp_setup_set_sampler_textures( struct setup_context *setup, + unsigned num, struct pipe_texture **texture); + +unsigned +lp_setup_is_texture_referenced( const struct setup_context *setup, + const struct pipe_texture *texture ); + +void +lp_setup_set_flatshade_first( struct setup_context *setup, + boolean flatshade_first ); + +void +lp_setup_set_vertex_info( struct setup_context *setup, + struct vertex_info *info ); -struct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe ); -void llvmpipe_setup_prepare( struct setup_context *setup ); -void llvmpipe_setup_destroy_context( struct setup_context *setup ); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h new file mode 100644 index 0000000000..a5fc34e54a --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -0,0 +1,159 @@ +/************************************************************************** + * + * Copyright 2007-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 VMWARE 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. + * + **************************************************************************/ + + +/** + * The setup code is concerned with point/line/triangle setup and + * putting commands/data into the bins. + */ + + +#ifndef LP_SETUP_CONTEXT_H +#define LP_SETUP_CONTEXT_H + +#include "lp_setup.h" +#include "lp_rast.h" +#include "lp_tile_soa.h" /* for TILE_SIZE */ +#include "lp_scene.h" + +#include "draw/draw_vbuf.h" + +#define LP_SETUP_NEW_FS 0x01 +#define LP_SETUP_NEW_CONSTANTS 0x02 +#define LP_SETUP_NEW_BLEND_COLOR 0x04 +#define LP_SETUP_NEW_SCISSOR 0x08 + + +struct lp_scene_queue; + + +/** Max number of scenes */ +#define MAX_SCENES 2 + + + +/** + * Point/line/triangle setup context. + * Note: "stored" below indicates data which is stored in the bins, + * not arbitrary malloc'd memory. + * + * + * Subclass of vbuf_render, plugged directly into the draw module as + * the rendering backend. + */ +struct setup_context +{ + struct vbuf_render base; + + struct vertex_info *vertex_info; + uint prim; + uint vertex_size; + uint nr_vertices; + uint vertex_buffer_size; + void *vertex_buffer; + + /* Final pipeline stage for draw module. Draw module should + * create/install this itself now. + */ + struct draw_stage *vbuf; + struct lp_rasterizer *rast; + struct lp_scene *scenes[MAX_SCENES]; /**< all the scenes */ + struct lp_scene *scene; /**< current scene being built */ + struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */ + + boolean flatshade_first; + boolean ccw_is_frontface; + boolean scissor_test; + unsigned cullmode; + + struct pipe_framebuffer_state fb; + + struct { + unsigned flags; + union lp_rast_cmd_arg color; /**< lp_rast_clear_color() cmd */ + union lp_rast_cmd_arg zstencil; /**< lp_rast_clear_zstencil() cmd */ + } clear; + + enum { + SETUP_FLUSHED, + SETUP_CLEARED, + SETUP_ACTIVE + } state; + + struct { + struct lp_shader_input input[PIPE_MAX_ATTRIBS]; + unsigned nr_inputs; + + const struct lp_rast_state *stored; /**< what's in the scene */ + struct lp_rast_state current; /**< currently set state */ + } fs; + + /** fragment shader constants */ + struct { + struct pipe_buffer *current; + unsigned stored_size; + const void *stored_data; + } constants; + + struct { + struct pipe_blend_color current; + uint8_t *stored; + } blend_color; + + struct { + struct pipe_scissor_state current; + const void *stored; + } scissor; + + unsigned dirty; /**< bitmask of LP_SETUP_NEW_x bits */ + + void (*point)( struct setup_context *, + const float (*v0)[4]); + + void (*line)( struct setup_context *, + const float (*v0)[4], + const float (*v1)[4]); + + void (*triangle)( struct setup_context *, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4]); +}; + +void lp_setup_choose_triangle( struct setup_context *setup ); +void lp_setup_choose_line( struct setup_context *setup ); +void lp_setup_choose_point( struct setup_context *setup ); + +struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup); + +void lp_setup_init_vbuf(struct setup_context *setup); + +void lp_setup_update_state( struct setup_context *setup ); + +void lp_setup_destroy( struct setup_context *setup ); + +#endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.h b/src/gallium/drivers/llvmpipe/lp_setup_line.c index d91cd35b3b..feea79d394 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * + * Copyright 2007 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 @@ -10,11 +10,11 @@ * 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. @@ -22,28 +22,26 @@ * 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 TGSI_DUMP_C_H -#define TGSI_DUMP_C_H +/* + * Binning code for lines + */ -#include "pipe/p_shader_tokens.h" +#include "lp_setup_context.h" -#if defined __cplusplus -extern "C" { -#endif - -#define TGSI_DUMP_C_IGNORED 1 -#define TGSI_DUMP_C_DEFAULT 2 +static void line_nop( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4] ) +{ +} -void -tgsi_dump_c( - const struct tgsi_token *tokens, - uint flags ); -#if defined __cplusplus +void +lp_setup_choose_line( struct setup_context *setup ) +{ + setup->line = line_nop; } -#endif -#endif /* TGSI_DUMP_C_H */ + diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h b/src/gallium/drivers/llvmpipe/lp_setup_point.c index 0676e2f42a..f03ca729b2 100644 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 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 @@ -10,11 +10,11 @@ * 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. @@ -22,17 +22,25 @@ * 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 LP_VBUF_H -#define LP_VBUF_H +/* + * Binning code for points + */ +#include "lp_setup_context.h" -struct llvmpipe_context; +static void point_nop( struct setup_context *setup, + const float (*v0)[4] ) +{ +} -extern struct vbuf_render * -lp_create_vbuf_backend(struct llvmpipe_context *llvmpipe); + +void +lp_setup_choose_point( struct setup_context *setup ) +{ + setup->point = point_nop; +} -#endif /* LP_VBUF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c new file mode 100644 index 0000000000..9e59a6602c --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -0,0 +1,618 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +/* + * Binning code for triangles + */ + +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_perf.h" +#include "lp_setup_context.h" +#include "lp_rast.h" + +#define NUM_CHANNELS 4 + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + */ +static void constant_coef( struct lp_rast_triangle *tri, + unsigned slot, + const float value, + unsigned i ) +{ + tri->inputs.a0[slot][i] = value; + tri->inputs.dadx[slot][i] = 0.0f; + tri->inputs.dady[slot][i] = 0.0f; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static void linear_coef( struct lp_rast_triangle *tri, + float oneoverarea, + unsigned slot, + const float (*v1)[4], + const float (*v2)[4], + const float (*v3)[4], + unsigned vert_attr, + unsigned i) +{ + float a1 = v1[vert_attr][i]; + float a2 = v2[vert_attr][i]; + float a3 = v3[vert_attr][i]; + + float da12 = a1 - a2; + float da31 = a3 - a1; + float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * oneoverarea; + float dady = (da31 * tri->dx12 - tri->dx31 * da12) * oneoverarea; + + tri->inputs.dadx[slot][i] = dadx; + tri->inputs.dady[slot][i] = dady; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + tri->inputs.a0[slot][i] = (a1 - + (dadx * (v1[0][0] - 0.5f) + + dady * (v1[0][1] - 0.5f))); +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + * We basically multiply the vertex value by 1/w before computing + * the plane coefficients (a0, dadx, dady). + * Later, when we compute the value at a particular fragment position we'll + * divide the interpolated value by the interpolated W at that fragment. + */ +static void perspective_coef( struct lp_rast_triangle *tri, + float oneoverarea, + unsigned slot, + const float (*v1)[4], + const float (*v2)[4], + const float (*v3)[4], + unsigned vert_attr, + unsigned i) +{ + /* premultiply by 1/w (v[0][3] is always 1/w): + */ + float a1 = v1[vert_attr][i] * v1[0][3]; + float a2 = v2[vert_attr][i] * v2[0][3]; + float a3 = v3[vert_attr][i] * v3[0][3]; + float da12 = a1 - a2; + float da31 = a3 - a1; + float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * oneoverarea; + float dady = (da31 * tri->dx12 - tri->dx31 * da12) * oneoverarea; + + tri->inputs.dadx[slot][i] = dadx; + tri->inputs.dady[slot][i] = dady; + tri->inputs.a0[slot][i] = (a1 - + (dadx * (v1[0][0] - 0.5f) + + dady * (v1[0][1] - 0.5f))); +} + + +/** + * Special coefficient setup for gl_FragCoord. + * X and Y are trivial + * Z and W are copied from position_coef which should have already been computed. + * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. + */ +static void +setup_fragcoord_coef(struct lp_rast_triangle *tri, + float oneoverarea, + unsigned slot, + const float (*v1)[4], + const float (*v2)[4], + const float (*v3)[4]) +{ + /*X*/ + tri->inputs.a0[slot][0] = 0.0; + tri->inputs.dadx[slot][0] = 1.0; + tri->inputs.dady[slot][0] = 0.0; + /*Y*/ + tri->inputs.a0[slot][1] = 0.0; + tri->inputs.dadx[slot][1] = 0.0; + tri->inputs.dady[slot][1] = 1.0; + /*Z*/ + linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 2); + /*W*/ + linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 3); +} + + +static void setup_facing_coef( struct lp_rast_triangle *tri, + unsigned slot, + boolean frontface ) +{ + constant_coef( tri, slot, 1.0f - frontface, 0 ); + constant_coef( tri, slot, 0.0f, 1 ); /* wasted */ + constant_coef( tri, slot, 0.0f, 2 ); /* wasted */ + constant_coef( tri, slot, 0.0f, 3 ); /* wasted */ +} + + +/** + * Compute the tri->coef[] array dadx, dady, a0 values. + */ +static void setup_tri_coefficients( struct setup_context *setup, + struct lp_rast_triangle *tri, + float oneoverarea, + const float (*v1)[4], + const float (*v2)[4], + const float (*v3)[4], + boolean frontface) +{ + unsigned slot; + + /* The internal position input is in slot zero: + */ + setup_fragcoord_coef(tri, oneoverarea, 0, v1, v2, v3); + + /* setup interpolation for all the remaining attributes: + */ + for (slot = 0; slot < setup->fs.nr_inputs; slot++) { + unsigned vert_attr = setup->fs.input[slot].src_index; + unsigned i; + + switch (setup->fs.input[slot].interp) { + case LP_INTERP_CONSTANT: + for (i = 0; i < NUM_CHANNELS; i++) + constant_coef(tri, slot+1, v3[vert_attr][i], i); + break; + + case LP_INTERP_LINEAR: + for (i = 0; i < NUM_CHANNELS; i++) + linear_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + break; + + case LP_INTERP_PERSPECTIVE: + for (i = 0; i < NUM_CHANNELS; i++) + perspective_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + break; + + case LP_INTERP_POSITION: + /* XXX: fix me - duplicates the values in slot zero. + */ + setup_fragcoord_coef(tri, oneoverarea, slot+1, v1, v2, v3); + break; + + case LP_INTERP_FACING: + setup_facing_coef(tri, slot+1, frontface); + break; + + default: + assert(0); + } + } +} + + + +static INLINE int subpixel_snap( float a ) +{ + return util_iround(FIXED_ONE * a - (FIXED_ONE / 2)); +} + + + +/** + * Alloc space for a new triangle plus the input.a0/dadx/dady arrays + * immediately after it. + * The memory is allocated from the per-scene pool, not per-tile. + * \param tri_size returns number of bytes allocated + * \param nr_inputs number of fragment shader inputs + * \return pointer to triangle space + */ +static INLINE struct lp_rast_triangle * +alloc_triangle(struct lp_scene *scene, unsigned nr_inputs, unsigned *tri_size) +{ + unsigned input_array_sz = NUM_CHANNELS * (nr_inputs + 1) * sizeof(float); + struct lp_rast_triangle *tri; + unsigned bytes; + char *inputs; + + assert(sizeof(*tri) % 16 == 0); + + bytes = sizeof(*tri) + (3 * input_array_sz); + + tri = lp_scene_alloc_aligned( scene, bytes, 16 ); + + inputs = (char *) (tri + 1); + tri->inputs.a0 = (float (*)[4]) inputs; + tri->inputs.dadx = (float (*)[4]) (inputs + input_array_sz); + tri->inputs.dady = (float (*)[4]) (inputs + 2 * input_array_sz); + + *tri_size = bytes; + + return tri; +} + + + +/** + * Do basic setup for triangle rasterization and determine which + * framebuffer tiles are touched. Put the triangle in the scene's + * bins for the tiles which we overlap. + */ +static void +do_triangle_ccw(struct setup_context *setup, + const float (*v1)[4], + const float (*v2)[4], + const float (*v3)[4], + boolean frontfacing ) +{ + /* x/y positions in fixed point */ + const int x1 = subpixel_snap(v1[0][0]); + const int x2 = subpixel_snap(v2[0][0]); + const int x3 = subpixel_snap(v3[0][0]); + const int y1 = subpixel_snap(v1[0][1]); + const int y2 = subpixel_snap(v2[0][1]); + const int y3 = subpixel_snap(v3[0][1]); + + struct lp_scene *scene = lp_setup_get_current_scene(setup); + struct lp_rast_triangle *tri; + int area; + float oneoverarea; + int minx, maxx, miny, maxy; + unsigned tri_bytes; + + tri = alloc_triangle(scene, setup->fs.nr_inputs, &tri_bytes); + + tri->dx12 = x1 - x2; + tri->dx23 = x2 - x3; + tri->dx31 = x3 - x1; + + tri->dy12 = y1 - y2; + tri->dy23 = y2 - y3; + tri->dy31 = y3 - y1; + + area = (tri->dx12 * tri->dy31 - tri->dx31 * tri->dy12); + + LP_COUNT(nr_tris); + + /* Cull non-ccw and zero-sized triangles. + * + * XXX: subject to overflow?? + */ + if (area <= 0) { + lp_scene_putback_data( scene, tri_bytes ); + LP_COUNT(nr_culled_tris); + return; + } + + /* Bounding rectangle (in pixels) */ + minx = (MIN3(x1, x2, x3) + (FIXED_ONE-1)) >> FIXED_ORDER; + maxx = (MAX3(x1, x2, x3) + (FIXED_ONE-1)) >> FIXED_ORDER; + miny = (MIN3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER; + maxy = (MAX3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER; + + if (setup->scissor_test) { + minx = MAX2(minx, setup->scissor.current.minx); + maxx = MIN2(maxx, setup->scissor.current.maxx); + miny = MAX2(miny, setup->scissor.current.miny); + maxy = MIN2(maxy, setup->scissor.current.maxy); + } + + if (miny == maxy || + minx == maxx) { + lp_scene_putback_data( scene, tri_bytes ); + LP_COUNT(nr_culled_tris); + return; + } + + /* + */ + oneoverarea = ((float)FIXED_ONE) / (float)area; + + /* Setup parameter interpolants: + */ + setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing ); + + /* half-edge constants, will be interated over the whole render target. + */ + tri->c1 = tri->dy12 * x1 - tri->dx12 * y1; + tri->c2 = tri->dy23 * x2 - tri->dx23 * y2; + tri->c3 = tri->dy31 * x3 - tri->dx31 * y3; + + /* correct for top-left fill convention: + */ + if (tri->dy12 < 0 || (tri->dy12 == 0 && tri->dx12 > 0)) tri->c1++; + if (tri->dy23 < 0 || (tri->dy23 == 0 && tri->dx23 > 0)) tri->c2++; + if (tri->dy31 < 0 || (tri->dy31 == 0 && tri->dx31 > 0)) tri->c3++; + + tri->dy12 *= FIXED_ONE; + tri->dy23 *= FIXED_ONE; + tri->dy31 *= FIXED_ONE; + + tri->dx12 *= FIXED_ONE; + tri->dx23 *= FIXED_ONE; + tri->dx31 *= FIXED_ONE; + + /* find trivial reject offsets for each edge for a single-pixel + * sized block. These will be scaled up at each recursive level to + * match the active blocksize. Scaling in this way works best if + * the blocks are square. + */ + tri->eo1 = 0; + if (tri->dy12 < 0) tri->eo1 -= tri->dy12; + if (tri->dx12 > 0) tri->eo1 += tri->dx12; + + tri->eo2 = 0; + if (tri->dy23 < 0) tri->eo2 -= tri->dy23; + if (tri->dx23 > 0) tri->eo2 += tri->dx23; + + tri->eo3 = 0; + if (tri->dy31 < 0) tri->eo3 -= tri->dy31; + if (tri->dx31 > 0) tri->eo3 += tri->dx31; + + /* Calculate trivial accept offsets from the above. + */ + tri->ei1 = tri->dx12 - tri->dy12 - tri->eo1; + tri->ei2 = tri->dx23 - tri->dy23 - tri->eo2; + tri->ei3 = tri->dx31 - tri->dy31 - tri->eo3; + + /* Fill in the inputs.step[][] arrays. + * We've manually unrolled some loops here. + */ + { + const int xstep1 = -tri->dy12; + const int xstep2 = -tri->dy23; + const int xstep3 = -tri->dy31; + const int ystep1 = tri->dx12; + const int ystep2 = tri->dx23; + const int ystep3 = tri->dx31; + +#define SETUP_STEP(i, x, y) \ + do { \ + tri->inputs.step[0][i] = x * xstep1 + y * ystep1; \ + tri->inputs.step[1][i] = x * xstep2 + y * ystep2; \ + tri->inputs.step[2][i] = x * xstep3 + y * ystep3; \ + } while (0) + + SETUP_STEP(0, 0, 0); + SETUP_STEP(1, 1, 0); + SETUP_STEP(2, 0, 1); + SETUP_STEP(3, 1, 1); + + SETUP_STEP(4, 2, 0); + SETUP_STEP(5, 3, 0); + SETUP_STEP(6, 2, 1); + SETUP_STEP(7, 3, 1); + + SETUP_STEP(8, 0, 2); + SETUP_STEP(9, 1, 2); + SETUP_STEP(10, 0, 3); + SETUP_STEP(11, 1, 3); + + SETUP_STEP(12, 2, 2); + SETUP_STEP(13, 3, 2); + SETUP_STEP(14, 2, 3); + SETUP_STEP(15, 3, 3); +#undef STEP + } + + /* + * All fields of 'tri' are now set. The remaining code here is + * concerned with binning. + */ + + /* Convert to tile coordinates: + */ + minx = minx / TILE_SIZE; + miny = miny / TILE_SIZE; + maxx = maxx / TILE_SIZE; + maxy = maxy / TILE_SIZE; + + /* Clamp maxx, maxy to framebuffer size + */ + maxx = MIN2(maxx, scene->tiles_x - 1); + maxy = MIN2(maxy, scene->tiles_y - 1); + + /* Determine which tile(s) intersect the triangle's bounding box + */ + if (miny == maxy && minx == maxx) + { + /* Triangle is contained in a single tile: + */ + lp_scene_bin_command( scene, minx, miny, lp_rast_triangle, + lp_rast_arg_triangle(tri) ); + } + else + { + int c1 = (tri->c1 + + tri->dx12 * miny * TILE_SIZE - + tri->dy12 * minx * TILE_SIZE); + int c2 = (tri->c2 + + tri->dx23 * miny * TILE_SIZE - + tri->dy23 * minx * TILE_SIZE); + int c3 = (tri->c3 + + tri->dx31 * miny * TILE_SIZE - + tri->dy31 * minx * TILE_SIZE); + + int ei1 = tri->ei1 << TILE_ORDER; + int ei2 = tri->ei2 << TILE_ORDER; + int ei3 = tri->ei3 << TILE_ORDER; + + int eo1 = tri->eo1 << TILE_ORDER; + int eo2 = tri->eo2 << TILE_ORDER; + int eo3 = tri->eo3 << TILE_ORDER; + + int xstep1 = -(tri->dy12 << TILE_ORDER); + int xstep2 = -(tri->dy23 << TILE_ORDER); + int xstep3 = -(tri->dy31 << TILE_ORDER); + + int ystep1 = tri->dx12 << TILE_ORDER; + int ystep2 = tri->dx23 << TILE_ORDER; + int ystep3 = tri->dx31 << TILE_ORDER; + int x, y; + + + /* Test tile-sized blocks against the triangle. + * Discard blocks fully outside the tri. If the block is fully + * contained inside the tri, bin an lp_rast_shade_tile command. + * Else, bin a lp_rast_triangle command. + */ + for (y = miny; y <= maxy; y++) + { + int cx1 = c1; + int cx2 = c2; + int cx3 = c3; + boolean in = FALSE; /* are we inside the triangle? */ + + for (x = minx; x <= maxx; x++) + { + if (cx1 + eo1 < 0 || + cx2 + eo2 < 0 || + cx3 + eo3 < 0) + { + /* do nothing */ + LP_COUNT(nr_empty_64); + if (in) + break; /* exiting triangle, all done with this row */ + } + else if (cx1 + ei1 > 0 && + cx2 + ei2 > 0 && + cx3 + ei3 > 0) + { + /* triangle covers the whole tile- shade whole tile */ + LP_COUNT(nr_fully_covered_64); + in = TRUE; + if(setup->fs.current.opaque) { + lp_scene_bin_reset( scene, x, y ); + lp_scene_bin_command( scene, x, y, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); + } + lp_scene_bin_command( scene, x, y, + lp_rast_shade_tile, + lp_rast_arg_inputs(&tri->inputs) ); + } + else + { + /* rasterizer/shade partial tile */ + LP_COUNT(nr_partially_covered_64); + in = TRUE; + lp_scene_bin_command( scene, x, y, + lp_rast_triangle, + lp_rast_arg_triangle(tri) ); + } + + /* Iterate cx values across the region: + */ + cx1 += xstep1; + cx2 += xstep2; + cx3 += xstep3; + } + + /* Iterate c values down the region: + */ + c1 += ystep1; + c2 += ystep2; + c3 += ystep3; + } + } +} + + +static void triangle_cw( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + do_triangle_ccw( setup, v1, v0, v2, !setup->ccw_is_frontface ); +} + + +static void triangle_ccw( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + do_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface ); +} + + +static void triangle_both( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0][0] - v2[0][0]; + const float ey = v0[0][1] - v2[0][1]; + const float fx = v1[0][0] - v2[0][0]; + const float fy = v1[0][1] - v2[0][1]; + + /* det = cross(e,f).z */ + if (ex * fy - ey * fx < 0.0f) + triangle_ccw( setup, v0, v1, v2 ); + else + triangle_cw( setup, v0, v1, v2 ); +} + + +static void triangle_nop( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ +} + + +void +lp_setup_choose_triangle( struct setup_context *setup ) +{ + switch (setup->cullmode) { + case PIPE_WINDING_NONE: + setup->triangle = triangle_both; + break; + case PIPE_WINDING_CCW: + setup->triangle = triangle_cw; + break; + case PIPE_WINDING_CW: + setup->triangle = triangle_ccw; + break; + default: + setup->triangle = triangle_nop; + break; + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c new file mode 100644 index 0000000000..24291da91e --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -0,0 +1,518 @@ +/************************************************************************** + * + * Copyright 2007 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. + * + **************************************************************************/ + +/** + * Interface between 'draw' module's output and the llvmpipe rasterizer/setup + * code. When the 'draw' module has finished filling a vertex buffer, the + * draw_arrays() functions below will be called. Loop over the vertices and + * call the point/line/tri setup functions. + * + * Authors + * Brian Paul + */ + + +#include "lp_setup_context.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "util/u_memory.h" + + +#define LP_MAX_VBUF_INDEXES 1024 +#define LP_MAX_VBUF_SIZE 4096 + + + +/** cast wrapper */ +static struct setup_context * +setup_context(struct vbuf_render *vbr) +{ + return (struct setup_context *) vbr; +} + + + +static const struct vertex_info * +lp_setup_get_vertex_info(struct vbuf_render *vbr) +{ + struct setup_context *setup = setup_context(vbr); + return setup->vertex_info; +} + + +static boolean +lp_setup_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) +{ + struct setup_context *setup = setup_context(vbr); + unsigned size = vertex_size * nr_vertices; + + if (setup->vertex_buffer_size < size) { + align_free(setup->vertex_buffer); + setup->vertex_buffer = align_malloc(size, 16); + setup->vertex_buffer_size = size; + } + + setup->vertex_size = vertex_size; + setup->nr_vertices = nr_vertices; + + return setup->vertex_buffer != NULL; +} + +static void +lp_setup_release_vertices(struct vbuf_render *vbr) +{ + /* keep the old allocation for next time */ +} + +static void * +lp_setup_map_vertices(struct vbuf_render *vbr) +{ + struct setup_context *setup = setup_context(vbr); + return setup->vertex_buffer; +} + +static void +lp_setup_unmap_vertices(struct vbuf_render *vbr, + ushort min_index, + ushort max_index ) +{ + struct setup_context *setup = setup_context(vbr); + assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size ); + /* do nothing */ +} + + +static boolean +lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim) +{ + setup_context(vbr)->prim = prim; + return TRUE; +} + +typedef const float (*const_float4_ptr)[4]; + +static INLINE const_float4_ptr get_vert( const void *vertex_buffer, + int index, + int stride ) +{ + return (const_float4_ptr)((char *)vertex_buffer + index * stride); +} + +/** + * draw elements / indexed primitives + */ +static void +lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) +{ + struct setup_context *setup = setup_context(vbr); + const unsigned stride = setup->vertex_info->size * sizeof(float); + const void *vertex_buffer = setup->vertex_buffer; + unsigned i; + + lp_setup_update_state(setup); + + switch (setup->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup->point( setup, + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + if (nr) { + setup->line( setup, + get_vert(vertex_buffer, indices[nr-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + } + else { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i+(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-(i&1)], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i+(i&1)-2], stride), + get_vert(vertex_buffer, indices[i-(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride)); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + default: + assert(0); + } +} + + +/** + * This function is hit when the draw module is working in pass-through mode. + * It's up to us to convert the vertex array into point/line/tri prims. + */ +static void +lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) +{ + struct setup_context *setup = setup_context(vbr); + const unsigned stride = setup->vertex_info->size * sizeof(float); + const void *vertex_buffer = + (void *) get_vert(setup->vertex_buffer, start, stride); + unsigned i; + + lp_setup_update_state(setup); + + switch (setup->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup->point( setup, + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup->line( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + if (nr) { + setup->line( setup, + get_vert(vertex_buffer, nr-1, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride) ); + } + } + else { + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (setup->flatshade_first) { + for (i = 2; i < nr; i++) { + setup->triangle( setup, + get_vert(vertex_buffer, i+(i&1)-1, stride), + get_vert(vertex_buffer, i-(i&1), stride), + get_vert(vertex_buffer, i-2, stride) ); + } + } + else { + for (i = 2; i < nr; i++) { + setup->triangle( setup, + get_vert(vertex_buffer, i+(i&1)-2, stride), + get_vert(vertex_buffer, i-(i&1)-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (setup->flatshade_first) { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + } + else { + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (setup->flatshade_first) { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup->triangle( setup, + + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + default: + assert(0); + } +} + + + +static void +lp_setup_vbuf_destroy(struct vbuf_render *vbr) +{ + lp_setup_destroy(setup_context(vbr)); +} + + +/** + * Create the post-transform vertex handler for the given context. + */ +void +lp_setup_init_vbuf(struct setup_context *setup) +{ + setup->base.max_indices = LP_MAX_VBUF_INDEXES; + setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE; + + setup->base.get_vertex_info = lp_setup_get_vertex_info; + setup->base.allocate_vertices = lp_setup_allocate_vertices; + setup->base.map_vertices = lp_setup_map_vertices; + setup->base.unmap_vertices = lp_setup_unmap_vertices; + setup->base.set_primitive = lp_setup_set_primitive; + setup->base.draw = lp_setup_draw; + setup->base.draw_arrays = lp_setup_draw_arrays; + setup->base.release_vertices = lp_setup_release_vertices; + setup->base.destroy = lp_setup_vbuf_destroy; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 7020da145f..8f68f12bed 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -36,7 +36,7 @@ #include "pipe/p_state.h" #include "tgsi/tgsi_scan.h" #include "lp_jit.h" -#include "lp_bld_sample.h" /* for struct lp_sampler_static_state */ +#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */ #define LP_NEW_VIEWPORT 0x1 @@ -54,6 +54,7 @@ #define LP_NEW_VERTEX 0x1000 #define LP_NEW_VS 0x2000 #define LP_NEW_QUERY 0x4000 +#define LP_NEW_BLEND_COLOR 0x8000 struct vertex_info; @@ -65,11 +66,18 @@ struct lp_fragment_shader; struct lp_fragment_shader_variant_key { - enum pipe_format zsbuf_format; struct pipe_depth_state depth; struct pipe_alpha_state alpha; struct pipe_blend_state blend; - + enum pipe_format zsbuf_format; + unsigned nr_cbufs:8; + unsigned flatshade:1; + unsigned scissor:1; + + struct { + ubyte colormask; + } cbuf_blend[PIPE_MAX_COLOR_BUFS]; + struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS]; }; @@ -80,9 +88,9 @@ struct lp_fragment_shader_variant struct lp_fragment_shader_variant_key key; - LLVMValueRef function; + LLVMValueRef function[2]; - lp_jit_frag_func jit_function; + lp_jit_frag_func jit_function[2]; struct lp_fragment_shader_variant *next; }; @@ -154,7 +162,7 @@ void llvmpipe_set_clip_state( struct pipe_context *, void llvmpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, - const struct pipe_constant_buffer *buf); + struct pipe_buffer *buf); void *llvmpipe_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -212,23 +220,10 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); void -llvmpipe_map_transfers(struct llvmpipe_context *lp); - -void -llvmpipe_unmap_transfers(struct llvmpipe_context *lp); - -void llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp); void llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp); -struct vertex_info * -llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe); - -struct vertex_info * -llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe); - - #endif diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c index a94cd05ef2..9b950e82d8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c @@ -73,7 +73,9 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - unsigned i, j; + + if(!blend_color) + return; if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0) return; @@ -82,13 +84,7 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe, memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color); - if(!llvmpipe->jit_context.blend_color) - llvmpipe->jit_context.blend_color = align_malloc(4 * 16, 16); - for (i = 0; i < 4; ++i) { - uint8_t c = float_to_ubyte(blend_color->color[i]); - for (j = 0; j < 16; ++j) - llvmpipe->jit_context.blend_color[i*16 + j] = c; - } + llvmpipe->dirty |= LP_NEW_BLEND_COLOR; } @@ -117,9 +113,6 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe, llvmpipe->depth_stencil = depth_stencil; - if(llvmpipe->depth_stencil) - llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value; - llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 6c1ef6bc42..bdd906e1a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -33,166 +33,113 @@ #include "draw/draw_private.h" #include "lp_context.h" #include "lp_screen.h" -#include "lp_tex_cache.h" +#include "lp_setup.h" #include "lp_state.h" -/** - * Mark the current vertex layout as "invalid". - * We'll validate the vertex layout later, when we start to actually - * render a point or line or tri. - */ -static void -invalidate_vertex_layout(struct llvmpipe_context *llvmpipe) -{ - llvmpipe->vertex_info.num_attribs = 0; -} - /** * The vertex info describes how to convert the post-transformed vertices * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * - * This function validates the vertex layout and returns a pointer to a - * vertex_info object. + * This function validates the vertex layout. */ -struct vertex_info * -llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe) +static void +compute_vertex_info(struct llvmpipe_context *llvmpipe) { + const struct lp_fragment_shader *lpfs = llvmpipe->fs; struct vertex_info *vinfo = &llvmpipe->vertex_info; + const uint num = draw_num_shader_outputs(llvmpipe->draw); + uint i; - if (vinfo->num_attribs == 0) { - /* compute vertex layout now */ - const struct lp_fragment_shader *lpfs = llvmpipe->fs; - struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf; - const uint num = draw_current_shader_outputs(llvmpipe->draw); - uint i; - - /* Tell draw_vbuf to simply emit the whole post-xform vertex - * as-is. No longer any need to try and emit draw vertex_header - * info. - */ - vinfo_vbuf->num_attribs = 0; - for (i = 0; i < num; i++) { - draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); - } - draw_compute_vertex_size(vinfo_vbuf); + /* Tell setup to tell the draw module to simply emit the whole + * post-xform vertex as-is. + * + * Not really sure if this is the best approach. + */ + vinfo->num_attribs = 0; + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, i); + } + draw_compute_vertex_size(vinfo); - /* - * Loop over fragment shader inputs, searching for the matching output - * from the vertex shader. - */ - vinfo->num_attribs = 0; - for (i = 0; i < lpfs->info.num_inputs; i++) { - int src; - enum interp_mode interp; - switch (lpfs->info.input_interpolate[i]) { - case TGSI_INTERPOLATE_CONSTANT: - interp = INTERP_CONSTANT; - break; - case TGSI_INTERPOLATE_LINEAR: - interp = INTERP_LINEAR; - break; - case TGSI_INTERPOLATE_PERSPECTIVE: - interp = INTERP_PERSPECTIVE; - break; - default: - assert(0); - interp = INTERP_LINEAR; - } + lp_setup_set_vertex_info(llvmpipe->setup, vinfo); + +/* + llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, + TGSI_SEMANTIC_PSIZE, 0); +*/ + + /* Now match FS inputs against emitted vertex data. It's also + * entirely possible to just have a fixed layout for FS input, + * determined by the fragment shader itself, and adjust the draw + * outputs to match that. + */ + { + struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS]; + for (i = 0; i < lpfs->info.num_inputs; i++) { + + /* This can be precomputed, except for flatshade: + */ switch (lpfs->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_FACE: + inputs[i].interp = LP_INTERP_FACING; + break; case TGSI_SEMANTIC_POSITION: - interp = INTERP_POS; + inputs[i].interp = LP_INTERP_POSITION; break; - case TGSI_SEMANTIC_COLOR: - if (llvmpipe->rasterizer->flatshade) { - interp = INTERP_CONSTANT; - } + /* Colors are linearly interpolated in the fragment shader + * even when flatshading is active. This just tells the + * setup module to use coefficients with ddx==0 and + * ddy==0. + */ + if (llvmpipe->rasterizer->flatshade) + inputs[i].interp = LP_INTERP_CONSTANT; + else + inputs[i].interp = LP_INTERP_LINEAR; break; - } - /* this includes texcoords and varying vars */ - src = draw_find_shader_output(llvmpipe->draw, - lpfs->info.input_semantic_name[i], - lpfs->info.input_semantic_index[i]); - draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src); - } + default: + switch (lpfs->info.input_interpolate[i]) { + case TGSI_INTERPOLATE_CONSTANT: + inputs[i].interp = LP_INTERP_CONSTANT; + break; + case TGSI_INTERPOLATE_LINEAR: + inputs[i].interp = LP_INTERP_LINEAR; + break; + case TGSI_INTERPOLATE_PERSPECTIVE: + inputs[i].interp = LP_INTERP_PERSPECTIVE; + break; + default: + assert(0); + break; + } + } - llvmpipe->psize_slot = draw_find_shader_output(llvmpipe->draw, - TGSI_SEMANTIC_PSIZE, 0); - if (llvmpipe->psize_slot > 0) { - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, - llvmpipe->psize_slot); + /* Search for each input in current vs output: + */ + inputs[i].src_index = + draw_find_shader_output(llvmpipe->draw, + lpfs->info.input_semantic_name[i], + lpfs->info.input_semantic_index[i]); } - draw_compute_vertex_size(vinfo); + lp_setup_set_fs_inputs(llvmpipe->setup, + inputs, + lpfs->info.num_inputs); } - - return vinfo; } /** - * Called from vbuf module. + * Handle state changes. + * Called just prior to drawing anything (pipe::draw_arrays(), etc). * - * Note that there's actually two different vertex layouts in llvmpipe. - * - * The normal one is computed in llvmpipe_get_vertex_info() above and is - * used by the point/line/tri "setup" code. - * - * The other one (this one) is only used by the vbuf module (which is - * not normally used by default but used in testing). For the vbuf module, - * we basically want to pass-through the draw module's vertex layout as-is. - * When the llvmpipe vbuf code begins drawing, the normal vertex layout - * will come into play again. - */ -struct vertex_info * -llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe) -{ - (void) llvmpipe_get_vertex_info(llvmpipe); - return &llvmpipe->vertex_info_vbuf; -} - - -/** - * Recompute cliprect from scissor bounds, scissor enable and surface size. - */ -static void -compute_cliprect(struct llvmpipe_context *lp) -{ - /* LP_NEW_FRAMEBUFFER - */ - uint surfWidth = lp->framebuffer.width; - uint surfHeight = lp->framebuffer.height; - - /* LP_NEW_RASTERIZER - */ - if (lp->rasterizer->scissor) { - - /* LP_NEW_SCISSOR - * - * clip to scissor rect: - */ - lp->cliprect.minx = MAX2(lp->scissor.minx, 0); - lp->cliprect.miny = MAX2(lp->scissor.miny, 0); - lp->cliprect.maxx = MIN2(lp->scissor.maxx, surfWidth); - lp->cliprect.maxy = MIN2(lp->scissor.maxy, surfHeight); - } - else { - /* clip to surface bounds */ - lp->cliprect.minx = 0; - lp->cliprect.miny = 0; - lp->cliprect.maxx = surfWidth; - lp->cliprect.maxy = surfHeight; - } -} - - -/* Hopefully this will remain quite simple, otherwise need to pull in + * Hopefully this will remain quite simple, otherwise need to pull in * something like the state tracker mechanism. */ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) @@ -206,28 +153,40 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) llvmpipe->dirty |= LP_NEW_TEXTURE; } - if (llvmpipe->dirty & (LP_NEW_SAMPLER | - LP_NEW_TEXTURE)) { - /* TODO */ - } - if (llvmpipe->dirty & (LP_NEW_RASTERIZER | LP_NEW_FS | LP_NEW_VS)) - invalidate_vertex_layout( llvmpipe ); - - if (llvmpipe->dirty & (LP_NEW_SCISSOR | - LP_NEW_RASTERIZER | - LP_NEW_FRAMEBUFFER)) - compute_cliprect(llvmpipe); + compute_vertex_info( llvmpipe ); if (llvmpipe->dirty & (LP_NEW_FS | LP_NEW_BLEND | + LP_NEW_SCISSOR | LP_NEW_DEPTH_STENCIL_ALPHA | + LP_NEW_RASTERIZER | LP_NEW_SAMPLER | LP_NEW_TEXTURE)) llvmpipe_update_fs( llvmpipe ); + if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) + lp_setup_set_blend_color(llvmpipe->setup, + &llvmpipe->blend_color); + + if (llvmpipe->dirty & LP_NEW_SCISSOR) + lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); + + if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) + lp_setup_set_alpha_ref_value(llvmpipe->setup, + llvmpipe->depth_stencil->alpha.ref_value); + + if (llvmpipe->dirty & LP_NEW_CONSTANTS) + lp_setup_set_fs_constants(llvmpipe->setup, + llvmpipe->constants[PIPE_SHADER_FRAGMENT]); + + if (llvmpipe->dirty & LP_NEW_TEXTURE) + lp_setup_set_sampler_textures(llvmpipe->setup, + llvmpipe->num_textures, + llvmpipe->texture); llvmpipe->dirty = 0; } + diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index b73ca2d41e..15c10d8e2e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -31,6 +31,8 @@ * Code generate the whole fragment pipeline. * * The fragment pipeline consists of the following stages: + * - triangle edge in/out testing + * - scissor test * - stipple (TBI) * - early depth test * - fragment shader @@ -58,36 +60,39 @@ * @author Jose Fonseca <jfonseca@vmware.com> */ +#include <limits.h> #include "pipe/p_defines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_format.h" #include "util/u_debug_dump.h" -#include "pipe/internal/p_winsys_screen.h" +#include "os/os_time.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "tgsi/tgsi_dump.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_parse.h" -#include "lp_bld_type.h" -#include "lp_bld_const.h" -#include "lp_bld_conv.h" -#include "lp_bld_intr.h" -#include "lp_bld_logic.h" -#include "lp_bld_depth.h" -#include "lp_bld_interp.h" -#include "lp_bld_tgsi.h" -#include "lp_bld_alpha.h" -#include "lp_bld_blend.h" -#include "lp_bld_swizzle.h" -#include "lp_bld_flow.h" -#include "lp_bld_debug.h" -#include "lp_screen.h" -#include "lp_context.h" +#include "gallivm/lp_bld_type.h" +#include "gallivm/lp_bld_const.h" +#include "gallivm/lp_bld_conv.h" +#include "gallivm/lp_bld_intr.h" +#include "gallivm/lp_bld_logic.h" +#include "gallivm/lp_bld_depth.h" +#include "gallivm/lp_bld_interp.h" +#include "gallivm/lp_bld_tgsi.h" +#include "gallivm/lp_bld_alpha.h" +#include "gallivm/lp_bld_blend.h" +#include "gallivm/lp_bld_swizzle.h" +#include "gallivm/lp_bld_flow.h" +#include "gallivm/lp_bld_debug.h" #include "lp_buffer.h" +#include "lp_context.h" +#include "lp_debug.h" +#include "lp_perf.h" +#include "lp_screen.h" +#include "lp_setup.h" #include "lp_state.h" -#include "lp_quad.h" #include "lp_tex_sample.h" -#include "lp_debug.h" static const unsigned char quad_offset_x[4] = {0, 1, 0, 1}; @@ -187,7 +192,187 @@ generate_depth(LLVMBuilderRef builder, /** + * Generate the code to do inside/outside triangle testing for the + * four pixels in a 2x2 quad. This will set the four elements of the + * quad mask vector to 0 or ~0. + * \param i which quad of the quad group to test, in [0,3] + */ +static void +generate_tri_edge_mask(LLVMBuilderRef builder, + unsigned i, + LLVMValueRef *mask, /* ivec4, out */ + LLVMValueRef c0, /* int32 */ + LLVMValueRef c1, /* int32 */ + LLVMValueRef c2, /* int32 */ + LLVMValueRef step0_ptr, /* ivec4 */ + LLVMValueRef step1_ptr, /* ivec4 */ + LLVMValueRef step2_ptr) /* ivec4 */ +{ +#define OPTIMIZE_IN_OUT_TEST 0 +#if OPTIMIZE_IN_OUT_TEST + struct lp_build_if_state ifctx; + LLVMValueRef not_draw_all; +#endif + struct lp_build_flow_context *flow; + struct lp_type i32_type; + LLVMTypeRef i32vec4_type, mask_type; + LLVMValueRef c0_vec, c1_vec, c2_vec; + LLVMValueRef in_out_mask; + + assert(i < 4); + + /* int32 vector type */ + memset(&i32_type, 0, sizeof i32_type); + i32_type.floating = FALSE; /* values are integers */ + i32_type.sign = TRUE; /* values are signed */ + i32_type.norm = FALSE; /* values are not normalized */ + i32_type.width = 32; /* 32-bit int values */ + i32_type.length = 4; /* 4 elements per vector */ + + i32vec4_type = lp_build_int32_vec4_type(); + + mask_type = LLVMIntType(32 * 4); + + /* + * Use a conditional here to do detailed pixel in/out testing. + * We only have to do this if c0 != INT_MIN. + */ + flow = lp_build_flow_create(builder); + lp_build_flow_scope_begin(flow); + + { +#if OPTIMIZE_IN_OUT_TEST + /* not_draw_all = (c0 != INT_MIN) */ + not_draw_all = LLVMBuildICmp(builder, + LLVMIntNE, + c0, + LLVMConstInt(LLVMInt32Type(), INT_MIN, 0), + ""); + + in_out_mask = lp_build_int_const_scalar(i32_type, ~0); + + + lp_build_flow_scope_declare(flow, &in_out_mask); + + /* if (not_draw_all) {... */ + lp_build_if(&ifctx, flow, builder, not_draw_all); +#endif + { + LLVMValueRef step0_vec, step1_vec, step2_vec; + LLVMValueRef m0_vec, m1_vec, m2_vec; + LLVMValueRef index, m; + + /* c0_vec = {c0, c0, c0, c0} + * Note that we emit this code four times but LLVM optimizes away + * three instances of it. + */ + c0_vec = lp_build_broadcast(builder, i32vec4_type, c0); + c1_vec = lp_build_broadcast(builder, i32vec4_type, c1); + c2_vec = lp_build_broadcast(builder, i32vec4_type, c2); + lp_build_name(c0_vec, "edgeconst0vec"); + lp_build_name(c1_vec, "edgeconst1vec"); + lp_build_name(c2_vec, "edgeconst2vec"); + + /* load step0vec, step1, step2 vec from memory */ + index = LLVMConstInt(LLVMInt32Type(), i, 0); + step0_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step0_ptr, &index, 1, ""), ""); + step1_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step1_ptr, &index, 1, ""), ""); + step2_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step2_ptr, &index, 1, ""), ""); + lp_build_name(step0_vec, "step0vec"); + lp_build_name(step1_vec, "step1vec"); + lp_build_name(step2_vec, "step2vec"); + + /* m0_vec = step0_ptr[i] > c0_vec */ + m0_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step0_vec, c0_vec); + m1_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step1_vec, c1_vec); + m2_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step2_vec, c2_vec); + + /* in_out_mask = m0_vec & m1_vec & m2_vec */ + m = LLVMBuildAnd(builder, m0_vec, m1_vec, ""); + in_out_mask = LLVMBuildAnd(builder, m, m2_vec, ""); + lp_build_name(in_out_mask, "inoutmaskvec"); + } +#if OPTIMIZE_IN_OUT_TEST + lp_build_endif(&ifctx); +#endif + + } + lp_build_flow_scope_end(flow); + lp_build_flow_destroy(flow); + + /* This is the initial alive/dead pixel mask for a quad of four pixels. + * It's an int[4] vector with each word set to 0 or ~0. + * Words will get cleared when pixels faile the Z test, etc. + */ + *mask = in_out_mask; +} + + +static LLVMValueRef +generate_scissor_test(LLVMBuilderRef builder, + LLVMValueRef context_ptr, + const struct lp_build_interp_soa_context *interp, + struct lp_type type) +{ + LLVMTypeRef vec_type = lp_build_vec_type(type); + LLVMValueRef xpos = interp->pos[0], ypos = interp->pos[1]; + LLVMValueRef xmin, ymin, xmax, ymax; + LLVMValueRef m0, m1, m2, m3, m; + + /* xpos, ypos contain the window coords for the four pixels in the quad */ + assert(xpos); + assert(ypos); + + /* get the current scissor bounds, convert to vectors */ + xmin = lp_jit_context_scissor_xmin_value(builder, context_ptr); + xmin = lp_build_broadcast(builder, vec_type, xmin); + + ymin = lp_jit_context_scissor_ymin_value(builder, context_ptr); + ymin = lp_build_broadcast(builder, vec_type, ymin); + + xmax = lp_jit_context_scissor_xmax_value(builder, context_ptr); + xmax = lp_build_broadcast(builder, vec_type, xmax); + + ymax = lp_jit_context_scissor_ymax_value(builder, context_ptr); + ymax = lp_build_broadcast(builder, vec_type, ymax); + + /* compare the fragment's position coordinates against the scissor bounds */ + m0 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, xpos, xmin); + m1 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, ypos, ymin); + m2 = lp_build_compare(builder, type, PIPE_FUNC_LESS, xpos, xmax); + m3 = lp_build_compare(builder, type, PIPE_FUNC_LESS, ypos, ymax); + + /* AND all the masks together */ + m = LLVMBuildAnd(builder, m0, m1, ""); + m = LLVMBuildAnd(builder, m, m2, ""); + m = LLVMBuildAnd(builder, m, m3, ""); + + lp_build_name(m, "scissormask"); + + return m; +} + + +static LLVMValueRef +build_int32_vec_const(int value) +{ + struct lp_type i32_type; + + memset(&i32_type, 0, sizeof i32_type); + i32_type.floating = FALSE; /* values are integers */ + i32_type.sign = TRUE; /* values are signed */ + i32_type.norm = FALSE; /* values are not normalized */ + i32_type.width = 32; /* 32-bit int values */ + i32_type.length = 4; /* 4 elements per vector */ + return lp_build_int_const_scalar(i32_type, value); +} + + + +/** * Generate the fragment shader, depth/stencil test, and alpha tests. + * \param i which quad in the tile, in range [0,3] + * \param do_tri_test if 1, do triangle edge in/out testing */ static void generate_fs(struct llvmpipe_context *lp, @@ -200,8 +385,15 @@ generate_fs(struct llvmpipe_context *lp, const struct lp_build_interp_soa_context *interp, struct lp_build_sampler_soa *sampler, LLVMValueRef *pmask, - LLVMValueRef *color, - LLVMValueRef depth_ptr) + LLVMValueRef (*color)[4], + LLVMValueRef depth_ptr, + unsigned do_tri_test, + LLVMValueRef c0, + LLVMValueRef c1, + LLVMValueRef c2, + LLVMValueRef step0_ptr, + LLVMValueRef step1_ptr, + LLVMValueRef step2_ptr) { const struct tgsi_token *tokens = shader->base.tokens; LLVMTypeRef elem_type; @@ -215,6 +407,9 @@ generate_fs(struct llvmpipe_context *lp, boolean early_depth_test; unsigned attrib; unsigned chan; + unsigned cbuf; + + assert(i < 4); elem_type = lp_build_elem_type(type); vec_type = lp_build_vec_type(type); @@ -229,14 +424,32 @@ generate_fs(struct llvmpipe_context *lp, lp_build_flow_scope_begin(flow); /* Declare the color and z variables */ - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - color[chan] = LLVMGetUndef(vec_type); - lp_build_flow_scope_declare(flow, &color[chan]); + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { + for(chan = 0; chan < NUM_CHANNELS; ++chan) { + color[cbuf][chan] = LLVMGetUndef(vec_type); + lp_build_flow_scope_declare(flow, &color[cbuf][chan]); + } } lp_build_flow_scope_declare(flow, &z); + /* do triangle edge testing */ + if (do_tri_test) { + generate_tri_edge_mask(builder, i, pmask, + c0, c1, c2, step0_ptr, step1_ptr, step2_ptr); + } + else { + *pmask = build_int32_vec_const(~0); + } + + /* 'mask' will control execution based on quad's pixel alive/killed state */ lp_build_mask_begin(&mask, flow, type, *pmask); + if (key->scissor) { + LLVMValueRef smask = + generate_scissor_test(builder, context_ptr, interp, type); + lp_build_mask_update(&mask, smask); + } + early_depth_test = key->depth.enabled && !key->alpha.enabled && @@ -255,19 +468,21 @@ generate_fs(struct llvmpipe_context *lp, for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) { for(chan = 0; chan < NUM_CHANNELS; ++chan) { if(outputs[attrib][chan]) { - lp_build_name(outputs[attrib][chan], "output%u.%u.%c", i, attrib, "xyzw"[chan]); + LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], ""); + lp_build_name(out, "output%u.%u.%c", i, attrib, "xyzw"[chan]); switch (shader->info.output_semantic_name[attrib]) { case TGSI_SEMANTIC_COLOR: { unsigned cbuf = shader->info.output_semantic_index[attrib]; - lp_build_name(outputs[attrib][chan], "color%u.%u.%c", i, attrib, "rgba"[chan]); + lp_build_name(out, "color%u.%u.%c", i, attrib, "rgba"[chan]); /* Alpha test */ /* XXX: should the alpha reference value be passed separately? */ + /* XXX: should only test the final assignment to alpha */ if(cbuf == 0 && chan == 3) { - LLVMValueRef alpha = outputs[attrib][chan]; + LLVMValueRef alpha = out; LLVMValueRef alpha_ref_value; alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr); alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value); @@ -275,15 +490,13 @@ generate_fs(struct llvmpipe_context *lp, &mask, alpha, alpha_ref_value); } - if(cbuf == 0) - color[chan] = outputs[attrib][chan]; - + color[cbuf][chan] = out; break; } case TGSI_SEMANTIC_POSITION: if(chan == 2) - z = outputs[attrib][chan]; + z = out; break; } } @@ -332,6 +545,8 @@ generate_blend(const struct pipe_blend_state *blend, lp_build_context_init(&bld, builder, type); flow = lp_build_flow_create(builder); + + /* we'll use this mask context to skip blending if all pixels are dead */ lp_build_mask_begin(&mask_ctx, flow, type, mask); vec_type = lp_build_vec_type(type); @@ -354,7 +569,7 @@ generate_blend(const struct pipe_blend_state *blend, lp_build_blend_soa(builder, blend, type, src, dst, con, res); for(chan = 0; chan < 4; ++chan) { - if(blend->colormask & (1 << chan)) { + if(blend->rt[0].colormask & (1 << chan)) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); lp_build_name(res[chan], "res.%c", "rgba"[chan]); res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]); @@ -369,14 +584,18 @@ generate_blend(const struct pipe_blend_state *blend, /** * Generate the runtime callable function for the whole fragment pipeline. + * Note that the function which we generate operates on a block of 16 + * pixels at at time. The block contains 2x2 quads. Each quad contains + * 2x2 pixels. */ -static struct lp_fragment_shader_variant * +static void generate_fragment(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, - const struct lp_fragment_shader_variant_key *key) + struct lp_fragment_shader_variant *variant, + unsigned do_tri_test) { struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen); - struct lp_fragment_shader_variant *variant; + const struct lp_fragment_shader_variant_key *key = &variant->key; struct lp_type fs_type; struct lp_type blend_type; LLVMTypeRef fs_elem_type; @@ -384,17 +603,18 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; LLVMTypeRef blend_int_vec_type; - LLVMTypeRef arg_types[9]; + LLVMTypeRef arg_types[14]; LLVMTypeRef func_type; + LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type(); LLVMValueRef context_ptr; LLVMValueRef x; LLVMValueRef y; LLVMValueRef a0_ptr; LLVMValueRef dadx_ptr; LLVMValueRef dady_ptr; - LLVMValueRef mask_ptr; - LLVMValueRef color_ptr; + LLVMValueRef color_ptr_ptr; LLVMValueRef depth_ptr; + LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr; LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef x0; @@ -402,71 +622,15 @@ generate_fragment(struct llvmpipe_context *lp, struct lp_build_sampler_soa *sampler; struct lp_build_interp_soa_context interp; LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH]; - LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; + LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; LLVMValueRef blend_mask; LLVMValueRef blend_in_color[NUM_CHANNELS]; + LLVMValueRef function; unsigned num_fs; unsigned i; unsigned chan; + unsigned cbuf; - if (LP_DEBUG & DEBUG_JIT) { - tgsi_dump(shader->base.tokens, 0); - if(key->depth.enabled) { - debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format)); - debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE)); - debug_printf("depth.writemask = %u\n", key->depth.writemask); - } - if(key->alpha.enabled) { - debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); - debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); - } - if(key->blend.logicop_enable) { - debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); - } - else if(key->blend.blend_enable) { - debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE)); - debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE)); - debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE)); - debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE)); - debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE)); - debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE)); - } - debug_printf("blend.colormask = 0x%x\n", key->blend.colormask); - for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { - if(key->sampler[i].format) { - debug_printf("sampler[%u] = \n", i); - debug_printf(" .format = %s\n", - pf_name(key->sampler[i].format)); - debug_printf(" .target = %s\n", - debug_dump_tex_target(key->sampler[i].target, TRUE)); - debug_printf(" .pot = %u %u %u\n", - key->sampler[i].pot_width, - key->sampler[i].pot_height, - key->sampler[i].pot_depth); - debug_printf(" .wrap = %s %s %s\n", - debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), - debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), - debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); - debug_printf(" .min_img_filter = %s\n", - debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); - debug_printf(" .min_mip_filter = %s\n", - debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); - debug_printf(" .mag_img_filter = %s\n", - debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); - if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) - debug_printf(" .compare_func = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE)); - debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); - debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter); - } - } - } - - variant = CALLOC_STRUCT(lp_fragment_shader_variant); - if(!variant) - return NULL; - - variant->shader = shader; - memcpy(&variant->key, key, sizeof *key); /* TODO: actually pick these based on the fs and color buffer * characteristics. */ @@ -476,8 +640,8 @@ generate_fragment(struct llvmpipe_context *lp, fs_type.sign = TRUE; /* values are signed */ fs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ fs_type.width = 32; /* 32-bit float */ - fs_type.length = 4; /* 4 element per vector */ - num_fs = 4; + fs_type.length = 4; /* 4 elements per vector */ + num_fs = 4; /* number of quads per block */ memset(&blend_type, 0, sizeof blend_type); blend_type.floating = FALSE; /* values are integers */ @@ -504,27 +668,47 @@ generate_fragment(struct llvmpipe_context *lp, arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */ arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */ arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */ - arg_types[6] = LLVMPointerType(fs_int_vec_type, 0); /* mask */ - arg_types[7] = LLVMPointerType(blend_vec_type, 0); /* color */ - arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ + arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */ + arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ + arg_types[8] = LLVMInt32Type(); /* c0 */ + arg_types[9] = LLVMInt32Type(); /* c1 */ + arg_types[10] = LLVMInt32Type(); /* c2 */ + /* Note: the step arrays are built as int32[16] but we interpret + * them here as int32_vec4[4]. + */ + arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ + arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ + arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); - variant->function = LLVMAddFunction(screen->module, "shader", func_type); - LLVMSetFunctionCallConv(variant->function, LLVMCCallConv); + function = LLVMAddFunction(screen->module, "shader", func_type); + LLVMSetFunctionCallConv(function, LLVMCCallConv); + + variant->function[do_tri_test] = function; + + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? + */ for(i = 0; i < Elements(arg_types); ++i) if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) - LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute); - - context_ptr = LLVMGetParam(variant->function, 0); - x = LLVMGetParam(variant->function, 1); - y = LLVMGetParam(variant->function, 2); - a0_ptr = LLVMGetParam(variant->function, 3); - dadx_ptr = LLVMGetParam(variant->function, 4); - dady_ptr = LLVMGetParam(variant->function, 5); - mask_ptr = LLVMGetParam(variant->function, 6); - color_ptr = LLVMGetParam(variant->function, 7); - depth_ptr = LLVMGetParam(variant->function, 8); + LLVMAddAttribute(LLVMGetParam(function, i), LLVMNoAliasAttribute); + + context_ptr = LLVMGetParam(function, 0); + x = LLVMGetParam(function, 1); + y = LLVMGetParam(function, 2); + a0_ptr = LLVMGetParam(function, 3); + dadx_ptr = LLVMGetParam(function, 4); + dady_ptr = LLVMGetParam(function, 5); + color_ptr_ptr = LLVMGetParam(function, 6); + depth_ptr = LLVMGetParam(function, 7); + c0 = LLVMGetParam(function, 8); + c1 = LLVMGetParam(function, 9); + c2 = LLVMGetParam(function, 10); + step0_ptr = LLVMGetParam(function, 11); + step1_ptr = LLVMGetParam(function, 12); + step2_ptr = LLVMGetParam(function, 13); lp_build_name(context_ptr, "context"); lp_build_name(x, "x"); @@ -532,36 +716,45 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(a0_ptr, "a0"); lp_build_name(dadx_ptr, "dadx"); lp_build_name(dady_ptr, "dady"); - lp_build_name(mask_ptr, "mask"); - lp_build_name(color_ptr, "color"); + lp_build_name(color_ptr_ptr, "color_ptr"); lp_build_name(depth_ptr, "depth"); + lp_build_name(c0, "c0"); + lp_build_name(c1, "c1"); + lp_build_name(c2, "c2"); + lp_build_name(step0_ptr, "step0"); + lp_build_name(step1_ptr, "step1"); + lp_build_name(step2_ptr, "step2"); /* * Function body */ - block = LLVMAppendBasicBlock(variant->function, "entry"); + block = LLVMAppendBasicBlock(function, "entry"); builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, block); generate_pos0(builder, x, y, &x0, &y0); - lp_build_interp_soa_init(&interp, shader->base.tokens, builder, fs_type, + lp_build_interp_soa_init(&interp, + shader->base.tokens, + key->flatshade, + builder, fs_type, a0_ptr, dadx_ptr, dady_ptr, - x0, y0, 2, 0); + x0, y0); /* code generated texture sampling */ sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr); + /* loop over quads in the block */ for(i = 0; i < num_fs; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - LLVMValueRef out_color[NUM_CHANNELS]; + LLVMValueRef out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS]; LLVMValueRef depth_ptr_i; + int cbuf; if(i != 0) - lp_build_interp_soa_update(&interp); + lp_build_interp_soa_update(&interp, i); - fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), ""); depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, ""); generate_fs(lp, shader, key, @@ -571,71 +764,162 @@ generate_fragment(struct llvmpipe_context *lp, i, &interp, sampler, - &fs_mask[i], + &fs_mask[i], /* output */ out_color, - depth_ptr_i); - - for(chan = 0; chan < NUM_CHANNELS; ++chan) - fs_out_color[chan][i] = out_color[chan]; + depth_ptr_i, + do_tri_test, + c0, c1, c2, + step0_ptr, step1_ptr, step2_ptr); + + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) + for(chan = 0; chan < NUM_CHANNELS; ++chan) + fs_out_color[cbuf][chan][i] = out_color[cbuf][chan]; } sampler->destroy(sampler); - /* - * Convert the fs's output color and mask to fit to the blending type. + /* Loop over color outputs / color buffers to do blending. */ + for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { + LLVMValueRef color_ptr; + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0); - for(chan = 0; chan < NUM_CHANNELS; ++chan) { - lp_build_conv(builder, fs_type, blend_type, - fs_out_color[chan], num_fs, - &blend_in_color[chan], 1); - lp_build_name(blend_in_color[chan], "color.%c", "rgba"[chan]); + /* + * Convert the fs's output color and mask to fit to the blending type. + */ + for(chan = 0; chan < NUM_CHANNELS; ++chan) { + lp_build_conv(builder, fs_type, blend_type, + fs_out_color[cbuf][chan], num_fs, + &blend_in_color[chan], 1); + lp_build_name(blend_in_color[chan], "color%d.%c", cbuf, "rgba"[chan]); + } + lp_build_conv_mask(builder, fs_type, blend_type, + fs_mask, num_fs, + &blend_mask, 1); + + color_ptr = LLVMBuildLoad(builder, + LLVMBuildGEP(builder, color_ptr_ptr, &index, 1, ""), + ""); + lp_build_name(color_ptr, "color_ptr%d", cbuf); + + /* + * Blending. + */ + generate_blend(&key->blend, + builder, + blend_type, + context_ptr, + blend_mask, + blend_in_color, + color_ptr); } - lp_build_conv_mask(builder, fs_type, blend_type, - fs_mask, num_fs, - &blend_mask, 1); - - /* - * Blending. - */ - - generate_blend(&key->blend, - builder, - blend_type, - context_ptr, - blend_mask, - blend_in_color, - color_ptr); - LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); - /* - * Translate the LLVM IR into machine code. - */ + /* Verify the LLVM IR. If invalid, dump and abort */ #ifdef DEBUG - if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { - LLVMDumpValue(variant->function); - assert(0); + if(LLVMVerifyFunction(function, LLVMPrintMessageAction)) { + if (1) + LLVMDumpValue(function); + abort(); } #endif - LLVMRunFunctionPassManager(screen->pass, variant->function); + /* Apply optimizations to LLVM IR */ + if (1) + LLVMRunFunctionPassManager(screen->pass, function); if (LP_DEBUG & DEBUG_JIT) { - LLVMDumpValue(variant->function); + /* Print the LLVM IR to stderr */ + LLVMDumpValue(function); debug_printf("\n"); } - variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function); + /* + * Translate the LLVM IR into machine code. + */ + variant->jit_function[do_tri_test] = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function); if (LP_DEBUG & DEBUG_ASM) - lp_disassemble(variant->jit_function); + lp_disassemble(variant->jit_function[do_tri_test]); +} + + +static struct lp_fragment_shader_variant * +generate_variant(struct llvmpipe_context *lp, + struct lp_fragment_shader *shader, + const struct lp_fragment_shader_variant_key *key) +{ + struct lp_fragment_shader_variant *variant; + + if (LP_DEBUG & DEBUG_JIT) { + unsigned i; + tgsi_dump(shader->base.tokens, 0); + if(key->depth.enabled) { + debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format)); + debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE)); + debug_printf("depth.writemask = %u\n", key->depth.writemask); + } + if(key->alpha.enabled) { + debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); + debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); + } + if(key->blend.logicop_enable) { + debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); + } + else if(key->blend.rt[0].blend_enable) { + debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); + debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); + debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); + debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); + debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); + debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); + } + debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); + for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { + if(key->sampler[i].format) { + debug_printf("sampler[%u] = \n", i); + debug_printf(" .format = %s\n", + pf_name(key->sampler[i].format)); + debug_printf(" .target = %s\n", + debug_dump_tex_target(key->sampler[i].target, TRUE)); + debug_printf(" .pot = %u %u %u\n", + key->sampler[i].pot_width, + key->sampler[i].pot_height, + key->sampler[i].pot_depth); + debug_printf(" .wrap = %s %s %s\n", + debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), + debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), + debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); + debug_printf(" .min_img_filter = %s\n", + debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); + debug_printf(" .min_mip_filter = %s\n", + debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); + debug_printf(" .mag_img_filter = %s\n", + debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); + if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) + debug_printf(" .compare_func = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE)); + debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); + } + } + } + + variant = CALLOC_STRUCT(lp_fragment_shader_variant); + if(!variant) + return NULL; + + variant->shader = shader; + memcpy(&variant->key, key, sizeof *key); + + generate_fragment(lp, shader, variant, 0); + generate_fragment(lp, shader, variant, 1); + + /* insert new variant into linked list */ variant->next = shader->variants; shader->variants = variant; @@ -693,11 +977,15 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) variant = shader->variants; while(variant) { struct lp_fragment_shader_variant *next = variant->next; - - if(variant->function) { - if(variant->jit_function) - LLVMFreeMachineCodeForFunction(screen->engine, variant->function); - LLVMDeleteFunction(variant->function); + unsigned i; + + for (i = 0; i < Elements(variant->function); i++) { + if (variant->function[i]) { + if (variant->jit_function[i]) + LLVMFreeMachineCodeForFunction(screen->engine, + variant->function[i]); + LLVMDeleteFunction(variant->function[i]); + } } FREE(variant); @@ -714,27 +1002,25 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *constants) + struct pipe_buffer *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - struct pipe_buffer *buffer = constants ? constants->buffer : NULL; - unsigned size = buffer ? buffer->size : 0; - const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL; + unsigned size = constants ? constants->size : 0; + const void *data = constants ? llvmpipe_buffer(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); + if(llvmpipe->constants[shader] == constants) + return; + draw_flush(llvmpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer); - - if(shader == PIPE_SHADER_FRAGMENT) { - llvmpipe->jit_context.constants = data; - } + pipe_buffer_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { - draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, data, size); } @@ -769,21 +1055,30 @@ make_variant_key(struct llvmpipe_context *lp, key->alpha.func = lp->depth_stencil->alpha.func; /* alpha.ref_value is passed in jit_context */ - if(lp->framebuffer.cbufs[0]) { - const struct util_format_description *format_desc; - unsigned chan; + key->flatshade = lp->rasterizer->flatshade; + key->scissor = lp->rasterizer->scissor; + if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); + } - format_desc = util_format_description(lp->framebuffer.cbufs[0]->format); + key->nr_cbufs = lp->framebuffer.nr_cbufs; + for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { + const struct util_format_description *format_desc; + unsigned chan; + + format_desc = util_format_description(lp->framebuffer.cbufs[i]->format); assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB || format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB); - /* mask out color channels not present in the color buffer */ + /* mask out color channels not present in the color buffer. + * Should be simple to incorporate per-cbuf writemasks: + */ for(chan = 0; chan < 4; ++chan) { enum util_format_swizzle swizzle = format_desc->swizzle[chan]; - if(swizzle > 4) - key->blend.colormask &= ~(1 << chan); + + if(swizzle <= UTIL_FORMAT_SWIZZLE_W) + key->blend.rt[0].colormask |= (1 << chan); } } @@ -793,12 +1088,17 @@ make_variant_key(struct llvmpipe_context *lp, } +/** + * Update fragment state. This is called just prior to drawing + * something when some fragment-related state has changed. + */ void llvmpipe_update_fs(struct llvmpipe_context *lp) { struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant; + boolean opaque; make_variant_key(lp, shader, &key); @@ -810,8 +1110,34 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) variant = variant->next; } - if(!variant) - variant = generate_fragment(lp, shader, &key); + if (!variant) { + int64_t t0, t1; + int64_t dt; + t0 = os_time_get(); + + variant = generate_variant(lp, shader, &key); + + t1 = os_time_get(); + dt = t1 - t0; + LP_COUNT_ADD(llvm_compile_time, dt); + LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */ + } shader->current = variant; + + /* TODO: put this in the variant */ + /* TODO: most of these can be relaxed, in particular the colormask */ + opaque = !key.blend.logicop_enable && + !key.blend.rt[0].blend_enable && + key.blend.rt[0].colormask == 0xf && + !key.alpha.enabled && + !key.depth.enabled && + !key.scissor && + !shader->info.uses_kill + ? TRUE : FALSE; + + lp_setup_set_fs_functions(lp->setup, + shader->current->jit_function[0], + shader->current->jit_function[1], + opaque); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index aa3b5a3f91..feb012816c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -29,6 +29,7 @@ #include "util/u_memory.h" #include "lp_context.h" #include "lp_state.h" +#include "lp_setup.h" #include "draw/draw_context.h" @@ -53,6 +54,17 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, llvmpipe->rasterizer = rasterizer; + /* Note: we can immediately set the triangle state here and + * not worry about binning because we handle culling during + * triangle setup, not when rasterizing the bins. + */ + if (llvmpipe->rasterizer) { + lp_setup_set_triangle_state( llvmpipe->setup, + llvmpipe->rasterizer->cull_mode, + llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, + llvmpipe->rasterizer->scissor); + } + llvmpipe->dirty |= LP_NEW_RASTERIZER; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index d382f9ca87..b30a075776 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -29,6 +29,7 @@ * Brian Paul */ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "draw/draw_context.h" @@ -36,8 +37,6 @@ #include "lp_context.h" #include "lp_context.h" #include "lp_state.h" -#include "lp_texture.h" -#include "lp_tex_cache.h" #include "draw/draw_context.h" @@ -125,17 +124,6 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference(&llvmpipe->texture[i], tex); - lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex); - - if(tex) { - struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); - struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i]; - jit_tex->width = tex->width0; - jit_tex->height = tex->height0; - jit_tex->stride = lp_tex->stride[0]; - if(!lp_tex->dt) - jit_tex->data = lp_tex->data; - } } llvmpipe->num_textures = num; @@ -166,7 +154,6 @@ llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe, struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; pipe_texture_reference(&llvmpipe->vertex_textures[i], tex); - lp_tex_tile_cache_set_texture(llvmpipe->vertex_tex_cache[i], tex); } llvmpipe->num_vertex_textures = num_textures; diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index e37ff04f3d..048ac5b968 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -28,10 +28,12 @@ /* Authors: Keith Whitwell <keith@tungstengraphics.com> */ +#include "pipe/p_state.h" +#include "util/u_inlines.h" +#include "util/u_surface.h" #include "lp_context.h" #include "lp_state.h" -#include "lp_surface.h" -#include "lp_tile_cache.h" +#include "lp_setup.h" #include "draw/draw_context.h" @@ -39,54 +41,19 @@ /** - * XXX this might get moved someday * Set the framebuffer surface info: color buffers, zbuffer, stencil buffer. - * Here, we flush the old surfaces and update the tile cache to point to the new - * surfaces. */ void llvmpipe_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct llvmpipe_context *lp = llvmpipe_context(pipe); - uint i; - draw_flush(lp->draw); + boolean changed = !util_framebuffer_state_equal(&lp->framebuffer, fb); - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - /* check if changing cbuf */ - if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) { - /* flush old */ - lp_tile_cache_map_transfers(lp->cbuf_cache[i]); - lp_flush_tile_cache(lp->cbuf_cache[i]); + if (changed) { - /* assign new */ - pipe_surface_reference(&lp->framebuffer.cbufs[i], fb->cbufs[i]); - - /* update cache */ - lp_tile_cache_set_surface(lp->cbuf_cache[i], fb->cbufs[i]); - } - } - - lp->framebuffer.nr_cbufs = fb->nr_cbufs; - - /* zbuf changing? */ - if (lp->framebuffer.zsbuf != fb->zsbuf) { - - if(lp->zsbuf_transfer) { - struct pipe_screen *screen = pipe->screen; - - if(lp->zsbuf_map) { - screen->transfer_unmap(screen, lp->zsbuf_transfer); - lp->zsbuf_map = NULL; - } - - screen->tex_transfer_destroy(lp->zsbuf_transfer); - lp->zsbuf_transfer = NULL; - } - - /* assign new */ - pipe_surface_reference(&lp->framebuffer.zsbuf, fb->zsbuf); + util_copy_framebuffer_state(&lp->framebuffer, fb); /* Tell draw module how deep the Z/depth buffer is */ if (lp->framebuffer.zsbuf) { @@ -103,10 +70,9 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe, } draw_set_mrd(lp->draw, mrd); } - } - lp->framebuffer.width = fb->width; - lp->framebuffer.height = fb->height; + lp_setup_bind_framebuffer( lp->setup, &lp->framebuffer ); - lp->dirty |= LP_NEW_FRAMEBUFFER; + lp->dirty |= LP_NEW_FRAMEBUFFER; + } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c index 1a17631a4c..57ac25ea0c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -31,7 +31,6 @@ #include "lp_context.h" #include "lp_state.h" -#include "lp_surface.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h index 39d80726e6..ca0f737b29 100644 --- a/src/gallium/drivers/llvmpipe/lp_test.h +++ b/src/gallium/drivers/llvmpipe/lp_test.h @@ -53,7 +53,7 @@ #include "util/u_math.h" #include "util/u_debug_dump.h" -#include "lp_bld_type.h" +#include "gallivm/lp_bld_type.h" #define LP_TEST_NUM_SAMPLES 32 diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index 29fff91981..e49b705598 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -37,10 +37,9 @@ */ -#include "lp_bld_type.h" -#include "lp_bld_arit.h" -#include "lp_bld_blend.h" -#include "lp_bld_debug.h" +#include "gallivm/lp_bld_type.h" +#include "gallivm/lp_bld_blend.h" +#include "gallivm/lp_bld_debug.h" #include "lp_test.h" @@ -104,18 +103,18 @@ write_tsv_row(FILE *fp, fprintf(fp, "%s\t%s\t%s\t", - blend->rgb_func != blend->alpha_func ? "true" : "false", - blend->rgb_src_factor != blend->alpha_src_factor ? "true" : "false", - blend->rgb_dst_factor != blend->alpha_dst_factor ? "true" : "false"); + blend->rt[0].rgb_func != blend->rt[0].alpha_func ? "true" : "false", + blend->rt[0].rgb_src_factor != blend->rt[0].alpha_src_factor ? "true" : "false", + blend->rt[0].rgb_dst_factor != blend->rt[0].alpha_dst_factor ? "true" : "false"); fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%s\n", - debug_dump_blend_func(blend->rgb_func, TRUE), - debug_dump_blend_factor(blend->rgb_src_factor, TRUE), - debug_dump_blend_factor(blend->rgb_dst_factor, TRUE), - debug_dump_blend_func(blend->alpha_func, TRUE), - debug_dump_blend_factor(blend->alpha_src_factor, TRUE), - debug_dump_blend_factor(blend->alpha_dst_factor, TRUE)); + debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), + debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), + debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fflush(fp); } @@ -137,12 +136,12 @@ dump_blend_type(FILE *fp, fprintf(fp, " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s", - "rgb_func", debug_dump_blend_func(blend->rgb_func, TRUE), - "rgb_src_factor", debug_dump_blend_factor(blend->rgb_src_factor, TRUE), - "rgb_dst_factor", debug_dump_blend_factor(blend->rgb_dst_factor, TRUE), - "alpha_func", debug_dump_blend_func(blend->alpha_func, TRUE), - "alpha_src_factor", debug_dump_blend_factor(blend->alpha_src_factor, TRUE), - "alpha_dst_factor", debug_dump_blend_factor(blend->alpha_dst_factor, TRUE)); + "rgb_func", debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), + "rgb_src_factor", debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + "rgb_dst_factor", debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + "alpha_func", debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), + "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fprintf(fp, " ...\n"); fflush(fp); @@ -401,13 +400,15 @@ compute_blend_ref(const struct pipe_blend_state *blend, double src_term[4]; double dst_term[4]; - compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, con, src_term); - compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, con, dst_term); + compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor, + src, src, dst, con, src_term); + compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor, + dst, src, dst, con, dst_term); /* * Combine RGB terms */ - switch (blend->rgb_func) { + switch (blend->rt[0].rgb_func) { case PIPE_BLEND_ADD: ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */ ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */ @@ -440,7 +441,7 @@ compute_blend_ref(const struct pipe_blend_state *blend, /* * Combine A terms */ - switch (blend->alpha_func) { + switch (blend->rt[0].alpha_func) { case PIPE_BLEND_ADD: ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */ break; @@ -462,7 +463,7 @@ compute_blend_ref(const struct pipe_blend_state *blend, } -ALIGN_STACK +PIPE_ALIGN_STACK static boolean test_one(unsigned verbose, FILE *fp, @@ -531,11 +532,11 @@ test_one(unsigned verbose, success = TRUE; for(i = 0; i < n && success; ++i) { if(mode == AoS) { - ALIGN16_ATTRIB uint8_t src[LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t con[LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t res[LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t src[LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t dst[LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t con[LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t res[LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t ref[LP_NATIVE_VECTOR_WIDTH/8]; int64_t start_counter = 0; int64_t end_counter = 0; @@ -596,11 +597,11 @@ test_one(unsigned verbose, if(mode == SoA) { const unsigned stride = type.length*type.width/8; - ALIGN16_ATTRIB uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8]; - ALIGN16_ATTRIB uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t src[4*LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t dst[4*LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t con[4*LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t res[4*LP_NATIVE_VECTOR_WIDTH/8]; + PIPE_ALIGN_VAR(16) uint8_t ref[4*LP_NATIVE_VECTOR_WIDTH/8]; int64_t start_counter = 0; int64_t end_counter = 0; boolean mismatch; @@ -806,14 +807,14 @@ test_all(unsigned verbose, FILE *fp) continue; memset(&blend, 0, sizeof blend); - blend.blend_enable = 1; - blend.rgb_func = *rgb_func; - blend.rgb_src_factor = *rgb_src_factor; - blend.rgb_dst_factor = *rgb_dst_factor; - blend.alpha_func = *alpha_func; - blend.alpha_src_factor = *alpha_src_factor; - blend.alpha_dst_factor = *alpha_dst_factor; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = *rgb_func; + blend.rt[0].rgb_src_factor = *rgb_src_factor; + blend.rt[0].rgb_dst_factor = *rgb_dst_factor; + blend.rt[0].alpha_func = *alpha_func; + blend.rt[0].alpha_src_factor = *alpha_src_factor; + blend.rt[0].alpha_dst_factor = *alpha_dst_factor; + blend.rt[0].colormask = PIPE_MASK_RGBA; if(!test_one(verbose, fp, &blend, mode, *type)) success = FALSE; @@ -865,14 +866,14 @@ test_some(unsigned verbose, FILE *fp, unsigned long n) type = &blend_types[rand() % num_types]; memset(&blend, 0, sizeof blend); - blend.blend_enable = 1; - blend.rgb_func = *rgb_func; - blend.rgb_src_factor = *rgb_src_factor; - blend.rgb_dst_factor = *rgb_dst_factor; - blend.alpha_func = *alpha_func; - blend.alpha_src_factor = *alpha_src_factor; - blend.alpha_dst_factor = *alpha_dst_factor; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = *rgb_func; + blend.rt[0].rgb_src_factor = *rgb_src_factor; + blend.rt[0].rgb_dst_factor = *rgb_dst_factor; + blend.rt[0].alpha_func = *alpha_func; + blend.rt[0].alpha_src_factor = *alpha_src_factor; + blend.rt[0].alpha_dst_factor = *alpha_dst_factor; + blend.rt[0].colormask = PIPE_MASK_RGBA; if(!test_one(verbose, fp, &blend, mode, *type)) success = FALSE; diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index faddfb9677..958cc40538 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -34,10 +34,10 @@ */ -#include "lp_bld_type.h" -#include "lp_bld_const.h" -#include "lp_bld_conv.h" -#include "lp_bld_debug.h" +#include "gallivm/lp_bld_type.h" +#include "gallivm/lp_bld_const.h" +#include "gallivm/lp_bld_conv.h" +#include "gallivm/lp_bld_debug.h" #include "lp_test.h" @@ -142,7 +142,7 @@ add_conv_test(LLVMModuleRef module, } -ALIGN_STACK +PIPE_ALIGN_STACK static boolean test_one(unsigned verbose, FILE *fp, @@ -230,8 +230,8 @@ test_one(unsigned verbose, for(i = 0; i < n && success; ++i) { unsigned src_stride = src_type.length*src_type.width/8; unsigned dst_stride = dst_type.length*dst_type.width/8; - ALIGN16_ATTRIB uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; - ALIGN16_ATTRIB uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; + PIPE_ALIGN_VAR(16) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; + PIPE_ALIGN_VAR(16) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH]; int64_t start_counter = 0; diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index 23ea9ebbe7..48828bd0a0 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -38,7 +38,7 @@ #include "util/u_cpu_detect.h" #include "util/u_format.h" -#include "lp_bld_format.h" +#include "gallivm/lp_bld_format.h" #include "lp_test.h" @@ -199,7 +199,7 @@ add_store_rgba_test(LLVMModuleRef module, } -ALIGN_STACK +PIPE_ALIGN_STACK static boolean test_format(unsigned verbose, FILE *fp, const struct pixel_test_case *test) { diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c index 314544aa9a..14ff00469b 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_main.c +++ b/src/gallium/drivers/llvmpipe/lp_test_main.c @@ -36,8 +36,8 @@ #include "util/u_cpu_detect.h" -#include "lp_bld_const.h" -#include "lp_bld_misc.h" +#include "gallivm/lp_bld_const.h" +#include "gallivm/lp_bld_misc.h" #include "lp_test.h" diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c deleted file mode 100644 index a6d9a2c1ac..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_tex_cache.c +++ /dev/null @@ -1,304 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * Texture tile caching. - * - * Author: - * Brian Paul - */ - -#include "pipe/p_inlines.h" -#include "util/u_memory.h" -#include "util/u_tile.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "lp_context.h" -#include "lp_surface.h" -#include "lp_texture.h" -#include "lp_tex_cache.h" - - - -/** - * Return the position in the cache for the tile that contains win pos (x,y). - * We currently use a direct mapped cache so this is like a hack key. - * At some point we should investige something more sophisticated, like - * a LRU replacement policy. - */ -#define CACHE_POS(x, y) \ - (((x) + (y) * 5) % NUM_ENTRIES) - - - -/** - * Is the tile at (x,y) in cleared state? - */ -static INLINE uint -is_clear_flag_set(const uint *bitvec, union tex_tile_address addr) -{ - int pos, bit; - pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x; - assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32); - bit = bitvec[pos / 32] & (1 << (pos & 31)); - return bit; -} - - -/** - * Mark the tile at (x,y) as not cleared. - */ -static INLINE void -clear_clear_flag(uint *bitvec, union tex_tile_address addr) -{ - int pos; - pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x; - assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32); - bitvec[pos / 32] &= ~(1 << (pos & 31)); -} - - -struct llvmpipe_tex_tile_cache * -lp_create_tex_tile_cache( struct pipe_screen *screen ) -{ - struct llvmpipe_tex_tile_cache *tc; - uint pos; - - tc = CALLOC_STRUCT( llvmpipe_tex_tile_cache ); - if (tc) { - tc->screen = screen; - for (pos = 0; pos < NUM_ENTRIES; pos++) { - tc->entries[pos].addr.bits.invalid = 1; - } - tc->last_tile = &tc->entries[0]; /* any tile */ - } - return tc; -} - - -void -lp_destroy_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc) -{ - struct pipe_screen *screen; - uint pos; - - for (pos = 0; pos < NUM_ENTRIES; pos++) { - /*assert(tc->entries[pos].x < 0);*/ - } - if (tc->transfer) { - screen = tc->transfer->texture->screen; - screen->tex_transfer_destroy(tc->transfer); - } - if (tc->tex_trans) { - screen = tc->tex_trans->texture->screen; - screen->tex_transfer_destroy(tc->tex_trans); - } - - FREE( tc ); -} - - -void -lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_tile_cache *tc) -{ - if (tc->transfer && !tc->transfer_map) - tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); - - if (tc->tex_trans && !tc->tex_trans_map) - tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); -} - - -void -lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc) -{ - if (tc->transfer_map) { - tc->screen->transfer_unmap(tc->screen, tc->transfer); - tc->transfer_map = NULL; - } - - if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } -} - -void -lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc) -{ - if (tc->texture) { - struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture); - if (lpt->timestamp != tc->timestamp) { - /* texture was modified, invalidate all cached tiles */ - uint i; - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->timestamp = lpt->timestamp; - } - } -} - -/** - * Specify the texture to cache. - */ -void -lp_tex_tile_cache_set_texture(struct llvmpipe_tex_tile_cache *tc, - struct pipe_texture *texture) -{ - uint i; - - assert(!tc->transfer); - - if (tc->texture != texture) { - pipe_texture_reference(&tc->texture, texture); - - if (tc->tex_trans) { - struct pipe_screen *screen = tc->tex_trans->texture->screen; - - if (tc->tex_trans_map) { - screen->transfer_unmap(screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - /* mark as entries as invalid/empty */ - /* XXX we should try to avoid this when the teximage hasn't changed */ - for (i = 0; i < NUM_ENTRIES; i++) { - tc->entries[i].addr.bits.invalid = 1; - } - - tc->tex_face = -1; /* any invalid value here */ - } -} - - -/** - * Given the texture face, level, zslice, x and y values, compute - * the cache entry position/index where we'd hope to find the - * cached texture tile. - * This is basically a direct-map cache. - * XXX There's probably lots of ways in which we can improve this. - */ -static INLINE uint -tex_cache_pos( union tex_tile_address addr ) -{ - uint entry = (addr.bits.x + - addr.bits.y * 9 + - addr.bits.z * 3 + - addr.bits.face + - addr.bits.level * 7); - - return entry % NUM_ENTRIES; -} - -/** - * Similar to lp_get_cached_tile() but for textures. - * Tiles are read-only and indexed with more params. - */ -const struct llvmpipe_cached_tex_tile * -lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, - union tex_tile_address addr ) -{ - struct pipe_screen *screen = tc->screen; - struct llvmpipe_cached_tex_tile *tile; - - tile = tc->entries + tex_cache_pos( addr ); - - if (addr.value != tile->addr.value) { - - /* cache miss. Most misses are because we've invaldiated the - * texture cache previously -- most commonly on binding a new - * texture. Currently we effectively flush the cache on texture - * bind. - */ -#if 0 - _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n" - " tile %u: x=%d y=%d z=%d face=%d level=%d\n", - pos, x/TEX_TILE_SIZE, y/TEX_TILE_SIZE, z, face, level, - pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level); -#endif - - /* check if we need to get a new transfer */ - if (!tc->tex_trans || - tc->tex_face != addr.bits.face || - tc->tex_level != addr.bits.level || - tc->tex_z != addr.bits.z) { - /* get new transfer (view into texture) */ - - if (tc->tex_trans) { - if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); - tc->tex_trans_map = NULL; - } - - screen->tex_transfer_destroy(tc->tex_trans); - tc->tex_trans = NULL; - } - - tc->tex_trans = - screen->get_tex_transfer(screen, tc->texture, - addr.bits.face, - addr.bits.level, - addr.bits.z, - PIPE_TRANSFER_READ, 0, 0, - u_minify(tc->texture->width0, addr.bits.level), - u_minify(tc->texture->height0, addr.bits.level)); - - tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); - - tc->tex_face = addr.bits.face; - tc->tex_level = addr.bits.level; - tc->tex_z = addr.bits.z; - } - - { - unsigned x = addr.bits.x * TEX_TILE_SIZE; - unsigned y = addr.bits.y * TEX_TILE_SIZE; - unsigned w = TEX_TILE_SIZE; - unsigned h = TEX_TILE_SIZE; - - if (pipe_clip_tile(x, y, &w, &h, tc->tex_trans)) { - assert(0); - } - - util_format_read_4ub(tc->tex_trans->texture->format, - (uint8_t *)tile->color, sizeof tile->color[0], - tc->tex_trans_map, tc->tex_trans->stride, - x, y, w, h); - } - - tile->addr = addr; - } - - tc->last_tile = tile; - return tile; -} diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.h b/src/gallium/drivers/llvmpipe/lp_tex_cache.h deleted file mode 100644 index 05fded78e1..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_tex_cache.h +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -#ifndef LP_TEX_CACHE_H -#define LP_TEX_CACHE_H - - -#include "pipe/p_compiler.h" - - -struct llvmpipe_context; -struct llvmpipe_tex_tile_cache; - - -/** - * Cache tile size (width and height). This needs to be a power of two. - */ -#define TEX_TILE_SIZE 64 - - -/* If we need to support > 4096, just expand this to be a 64 bit - * union, or consider tiling in Z as well. - */ -union tex_tile_address { - struct { - unsigned x:6; /* 4096 / TEX_TILE_SIZE */ - unsigned y:6; /* 4096 / TEX_TILE_SIZE */ - unsigned z:12; /* 4096 -- z not tiled */ - unsigned face:3; - unsigned level:4; - unsigned invalid:1; - } bits; - unsigned value; -}; - - -struct llvmpipe_cached_tex_tile -{ - union tex_tile_address addr; - uint8_t color[TEX_TILE_SIZE][TEX_TILE_SIZE][4]; -}; - -#define NUM_ENTRIES 50 - - -/** XXX move these */ -#define MAX_TEX_WIDTH 2048 -#define MAX_TEX_HEIGHT 2048 - - -struct llvmpipe_tex_tile_cache -{ - struct pipe_screen *screen; - struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_transfer *transfer; - void *transfer_map; - - struct pipe_texture *texture; /**< if caching a texture */ - unsigned timestamp; - - struct llvmpipe_cached_tex_tile entries[NUM_ENTRIES]; - - struct pipe_transfer *tex_trans; - void *tex_trans_map; - int tex_face, tex_level, tex_z; - - struct llvmpipe_cached_tex_tile *last_tile; /**< most recently retrieved tile */ -}; - - -extern struct llvmpipe_tex_tile_cache * -lp_create_tex_tile_cache( struct pipe_screen *screen ); - -extern void -lp_destroy_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc); - -extern void -lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_tile_cache *tc); - -extern void -lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc); - -extern void -lp_tex_tile_cache_set_texture(struct llvmpipe_tex_tile_cache *tc, - struct pipe_texture *texture); - -void -lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc); - -extern const struct llvmpipe_cached_tex_tile * -lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, - union tex_tile_address addr ); - -static INLINE union tex_tile_address -tex_tile_address( unsigned x, - unsigned y, - unsigned z, - unsigned face, - unsigned level ) -{ - union tex_tile_address addr; - - addr.value = 0; - addr.bits.x = x / TEX_TILE_SIZE; - addr.bits.y = y / TEX_TILE_SIZE; - addr.bits.z = z; - addr.bits.face = face; - addr.bits.level = level; - - return addr; -} - -/* Quickly retrieve tile if it matches last lookup. - */ -static INLINE const struct llvmpipe_cached_tex_tile * -lp_get_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc, - union tex_tile_address addr ) -{ - if (tc->last_tile->addr.value == addr.value) - return tc->last_tile; - - return lp_find_cached_tex_tile( tc, addr ); -} - - -#endif /* LP_TEX_CACHE_H */ - diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c index d2a6ae21f5..2533275dc1 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c @@ -42,12 +42,11 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "lp_bld_debug.h" -#include "lp_bld_type.h" -#include "lp_bld_intr.h" -#include "lp_bld_sample.h" -#include "lp_bld_tgsi.h" -#include "lp_state.h" +#include "gallivm/lp_bld_debug.h" +#include "gallivm/lp_bld_type.h" +#include "gallivm/lp_bld_sample.h" +#include "gallivm/lp_bld_tgsi.h" +#include "lp_jit.h" #include "lp_tex_sample.h" diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 2c135029ea..022bf92cb4 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -32,45 +32,42 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "lp_context.h" -#include "lp_state.h" -#include "lp_texture.h" -#include "lp_tex_cache.h" #include "lp_screen.h" +#include "lp_texture.h" +#include "lp_tile_size.h" #include "lp_winsys.h" -/* Simple, maximally packed layout. - */ - -/* Conventional allocation path for non-display textures: +/** + * Conventional allocation path for non-display textures: + * Simple, maximally packed layout. */ static boolean llvmpipe_texture_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture * lpt) + struct llvmpipe_texture *lpt) { struct pipe_texture *pt = &lpt->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; unsigned depth = pt->depth0; - unsigned buffer_size = 0; for (level = 0; level <= pt->last_level; level++) { unsigned nblocksx, nblocksy; /* Allocate storage for whole quads. This is particularly important - * for depth surfaces, which are currently stored in a swizzled format. */ - nblocksx = util_format_get_nblocksx(pt->format, align(width, 2)); - nblocksy = util_format_get_nblocksy(pt->format, align(height, 2)); + * for depth surfaces, which are currently stored in a swizzled format. + */ + nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE)); + nblocksy = util_format_get_nblocksy(pt->format, align(height, TILE_SIZE)); lpt->stride[level] = align(nblocksx * util_format_get_blocksize(pt->format), 16); @@ -80,7 +77,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * lpt->stride[level]); - width = u_minify(width, 1); + width = u_minify(width, 1); height = u_minify(height, 1); depth = u_minify(depth, 1); } @@ -90,16 +87,23 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, return lpt->data != NULL; } + + static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture * lpt) + struct llvmpipe_texture *lpt) { struct llvmpipe_winsys *winsys = screen->winsys; + /* Round up the surface size to a multiple of the tile size to + * avoid tile clipping. + */ + unsigned width = align(lpt->base.width0, TILE_SIZE); + unsigned height = align(lpt->base.height0, TILE_SIZE); + lpt->dt = winsys->displaytarget_create(winsys, lpt->base.format, - lpt->base.width0, - lpt->base.height0, + width, height, 16, &lpt->stride[0] ); @@ -107,9 +111,6 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, } - - - static struct pipe_texture * llvmpipe_texture_create(struct pipe_screen *_screen, const struct pipe_texture *templat) @@ -126,7 +127,7 @@ llvmpipe_texture_create(struct pipe_screen *_screen, /* XXX: The xlib state tracker is brain-dead and will request * PIPE_FORMAT_Z16_UNORM no matter how much we tell it we don't support it. */ - if(lpt->base.format == PIPE_FORMAT_Z16_UNORM) + if (lpt->base.format == PIPE_FORMAT_Z16_UNORM) lpt->base.format = PIPE_FORMAT_Z32_UNORM; if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | @@ -178,6 +179,7 @@ llvmpipe_texture_blanket(struct pipe_screen * screen, return &lpt->base; #else + debug_printf("llvmpipe_texture_blanket() not implemented!"); return NULL; #endif } @@ -189,12 +191,15 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen); struct llvmpipe_texture *lpt = llvmpipe_texture(pt); - if(lpt->dt) { + if (lpt->dt) { + /* display target */ struct llvmpipe_winsys *winsys = screen->winsys; winsys->displaytarget_destroy(winsys, lpt->dt); } - else + else { + /* regular texture */ align_free(lpt->data); + } FREE(lpt); } @@ -236,7 +241,7 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. The tile cache will look for this. */ + /* Mark the surface as dirty. */ lpt->timestamp++; llvmpipe_screen(screen)->timestamp++; } @@ -298,8 +303,8 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen, pipe_texture_reference(&pt->texture, texture); pt->x = x; pt->y = y; - pt->width = w; - pt->height = h; + pt->width = align(w, TILE_SIZE); + pt->height = align(h, TILE_SIZE); pt->stride = lptex->stride[level]; pt->usage = usage; pt->face = face; @@ -356,7 +361,8 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, lpt = llvmpipe_texture(transfer->texture); format = lpt->base.format; - if(lpt->dt) { + if (lpt->dt) { + /* display target */ struct llvmpipe_winsys *winsys = screen->winsys; map = winsys->displaytarget_map(winsys, lpt->dt, @@ -364,16 +370,16 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, if (map == NULL) return NULL; } - else + else { + /* regular texture */ map = lpt->data; + } /* May want to different things here depending on read/write nature * of the map: */ - if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) - { + if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { /* Do something to notify sharing contexts of a texture change. - * In llvmpipe, that would mean flushing the texture cache. */ screen->timestamp++; } @@ -387,29 +393,24 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, static void -llvmpipe_transfer_unmap(struct pipe_screen *_screen, +llvmpipe_transfer_unmap(struct pipe_screen *screen, struct pipe_transfer *transfer) { - struct llvmpipe_screen *screen = llvmpipe_screen(_screen); + struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen); struct llvmpipe_texture *lpt; assert(transfer->texture); lpt = llvmpipe_texture(transfer->texture); - if(lpt->dt) { - struct llvmpipe_winsys *winsys = screen->winsys; + if (lpt->dt) { + /* display target */ + struct llvmpipe_winsys *winsys = lp_screen->winsys; winsys->displaytarget_unmap(winsys, lpt->dt); } } void -llvmpipe_init_texture_funcs(struct llvmpipe_context *lp) -{ -} - - -void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = llvmpipe_texture_create; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index 00a20763e4..87c905bc02 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -37,6 +37,7 @@ struct pipe_screen; struct llvmpipe_context; struct llvmpipe_displaytarget; + struct llvmpipe_texture { struct pipe_texture base; @@ -58,6 +59,7 @@ struct llvmpipe_texture unsigned timestamp; }; + struct llvmpipe_transfer { struct pipe_transfer base; @@ -73,6 +75,14 @@ llvmpipe_texture(struct pipe_texture *pt) return (struct llvmpipe_texture *) pt; } + +static INLINE const struct llvmpipe_texture * +llvmpipe_texture_const(const struct pipe_texture *pt) +{ + return (const struct llvmpipe_texture *) pt; +} + + static INLINE struct llvmpipe_transfer * llvmpipe_transfer(struct pipe_transfer *pt) { @@ -81,10 +91,7 @@ llvmpipe_transfer(struct pipe_transfer *pt) extern void -llvmpipe_init_texture_funcs( struct llvmpipe_context *llvmpipe ); - -extern void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); -#endif /* LP_TEXTURE */ +#endif /* LP_TEXTURE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c deleted file mode 100644 index 7a1ecf5107..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c +++ /dev/null @@ -1,358 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * Texture tile caching. - * - * Author: - * Brian Paul - */ - -#include "pipe/p_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_tile.h" -#include "util/u_rect.h" -#include "lp_context.h" -#include "lp_surface.h" -#include "lp_texture.h" -#include "lp_tile_soa.h" -#include "lp_tile_cache.h" - - -#define MAX_WIDTH 4096 -#define MAX_HEIGHT 4096 - - -enum llvmpipe_tile_status -{ - LP_TILE_STATUS_UNDEFINED = 0, - LP_TILE_STATUS_CLEAR = 1, - LP_TILE_STATUS_DEFINED = 2 -}; - - -struct llvmpipe_cached_tile -{ - enum llvmpipe_tile_status status; - - /** color in SOA format */ - uint8_t *color; -}; - - -struct llvmpipe_tile_cache -{ - struct pipe_screen *screen; - struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_transfer *transfer; - void *transfer_map; - - struct llvmpipe_cached_tile entries[MAX_WIDTH/TILE_SIZE][MAX_HEIGHT/TILE_SIZE]; - - uint8_t clear_color[4]; /**< for color bufs */ - uint clear_val; /**< for z+stencil, or packed color clear value */ - - struct llvmpipe_cached_tile *last_tile; /**< most recently retrieved tile */ -}; - - -struct llvmpipe_tile_cache * -lp_create_tile_cache( struct pipe_screen *screen ) -{ - struct llvmpipe_tile_cache *tc; - int maxLevels, maxTexSize; - - /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */ - maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); - maxTexSize = 1 << (maxLevels - 1); - assert(MAX_WIDTH >= maxTexSize); - - tc = CALLOC_STRUCT( llvmpipe_tile_cache ); - if(!tc) - return NULL; - - tc->screen = screen; - - return tc; -} - - -void -lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc) -{ - struct pipe_screen *screen; - unsigned x, y; - - for (y = 0; y < MAX_HEIGHT; y += TILE_SIZE) { - for (x = 0; x < MAX_WIDTH; x += TILE_SIZE) { - struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; - - if(tile->color) - align_free(tile->color); - } - } - - if (tc->transfer) { - screen = tc->transfer->texture->screen; - screen->tex_transfer_destroy(tc->transfer); - } - - FREE( tc ); -} - - -/** - * Specify the surface to cache. - */ -void -lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc, - struct pipe_surface *ps) -{ - if (tc->transfer) { - struct pipe_screen *screen = tc->transfer->texture->screen; - - if (ps == tc->surface) - return; - - if (tc->transfer_map) { - screen->transfer_unmap(screen, tc->transfer); - tc->transfer_map = NULL; - } - - screen->tex_transfer_destroy(tc->transfer); - tc->transfer = NULL; - } - - tc->surface = ps; - - if (ps) { - struct pipe_screen *screen = ps->texture->screen; - unsigned x, y; - - tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face, - ps->level, ps->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, ps->width, ps->height); - - for (y = 0; y < ps->height; y += TILE_SIZE) { - for (x = 0; x < ps->width; x += TILE_SIZE) { - struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; - - tile->status = LP_TILE_STATUS_UNDEFINED; - - if(!tile->color) - tile->color = align_malloc( TILE_SIZE*TILE_SIZE*NUM_CHANNELS, 16 ); - } - } - } -} - - -/** - * Return the transfer being cached. - */ -struct pipe_surface * -lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc) -{ - return tc->surface; -} - - -void -lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc) -{ - if (tc->transfer && !tc->transfer_map) - tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); -} - - -void -lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc) -{ - if (tc->transfer_map) { - tc->screen->transfer_unmap(tc->screen, tc->transfer); - tc->transfer_map = NULL; - } -} - - -/** - * Set a tile to a solid color. - */ -static void -clear_tile(struct llvmpipe_cached_tile *tile, - uint8_t clear_color[4]) -{ - if (clear_color[0] == clear_color[1] && - clear_color[1] == clear_color[2] && - clear_color[2] == clear_color[3]) { - memset(tile->color, clear_color[0], TILE_SIZE * TILE_SIZE * 4); - } - else { - uint x, y, chan; - for (y = 0; y < TILE_SIZE; y++) - for (x = 0; x < TILE_SIZE; x++) - for (chan = 0; chan < 4; ++chan) - TILE_PIXEL(tile->color, x, y, chan) = clear_color[chan]; - } -} - - -/** - * Flush the tile cache: write all dirty tiles back to the transfer. - * any tiles "flagged" as cleared will be "really" cleared. - */ -void -lp_flush_tile_cache(struct llvmpipe_tile_cache *tc) -{ - struct pipe_transfer *pt = tc->transfer; - unsigned x, y; - - if(!pt) - return; - - assert(tc->transfer_map); - - /* push the tile to all positions marked as clear */ - for (y = 0; y < pt->height; y += TILE_SIZE) { - for (x = 0; x < pt->width; x += TILE_SIZE) { - struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; - - if(tile->status != LP_TILE_STATUS_UNDEFINED) { - unsigned w = TILE_SIZE; - unsigned h = TILE_SIZE; - - if (!pipe_clip_tile(x, y, &w, &h, pt)) { - switch(tile->status) { - case LP_TILE_STATUS_CLEAR: - /* Actually clear the tiles which were flagged as being in a - * clear state. */ - util_fill_rect(tc->transfer_map, pt->texture->format, pt->stride, - x, y, w, h, - tc->clear_val); - break; - - case LP_TILE_STATUS_DEFINED: - lp_tile_write_4ub(pt->texture->format, - tile->color, - tc->transfer_map, pt->stride, - x, y, w, h); - break; - - default: - assert(0); - break; - } - } - - tile->status = LP_TILE_STATUS_UNDEFINED; - } - } - } -} - - -/** - * Get a tile from the cache. - * \param x, y position of tile, in pixels - */ -void * -lp_get_cached_tile(struct llvmpipe_tile_cache *tc, - unsigned x, unsigned y ) -{ - struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; - struct pipe_transfer *pt = tc->transfer; - - assert(tc->surface); - assert(tc->transfer); - - if(!tc->transfer_map) - lp_tile_cache_map_transfers(tc); - - assert(tc->transfer_map); - - switch(tile->status) { - case LP_TILE_STATUS_CLEAR: - /* don't get tile from framebuffer, just clear it */ - clear_tile(tile, tc->clear_color); - tile->status = LP_TILE_STATUS_DEFINED; - break; - - case LP_TILE_STATUS_UNDEFINED: { - unsigned w = TILE_SIZE; - unsigned h = TILE_SIZE; - - x &= ~(TILE_SIZE - 1); - y &= ~(TILE_SIZE - 1); - - if (!pipe_clip_tile(x, y, &w, &h, tc->transfer)) - lp_tile_read_4ub(pt->texture->format, - tile->color, - tc->transfer_map, tc->transfer->stride, - x, y, w, h); - - tile->status = LP_TILE_STATUS_DEFINED; - break; - } - - case LP_TILE_STATUS_DEFINED: - /* nothing to do */ - break; - } - - return tile->color; -} - - -/** - * When a whole surface is being cleared to a value we can avoid - * fetching tiles above. - * Save the color and set a 'clearflag' for each tile of the screen. - */ -void -lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba, - uint clearValue) -{ - struct pipe_transfer *pt = tc->transfer; - const unsigned w = pt->width; - const unsigned h = pt->height; - unsigned x, y, chan; - - for(chan = 0; chan < 4; ++chan) - tc->clear_color[chan] = float_to_ubyte(rgba[chan]); - - tc->clear_val = clearValue; - - /* push the tile to all positions marked as clear */ - for (y = 0; y < h; y += TILE_SIZE) { - for (x = 0; x < w; x += TILE_SIZE) { - struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE]; - tile->status = LP_TILE_STATUS_CLEAR; - } - } -} diff --git a/src/mesa/state_tracker/st_api.c b/src/gallium/drivers/llvmpipe/lp_tile_size.h index fc0e9a2316..f0b983c063 100644 --- a/src/mesa/state_tracker/st_api.c +++ b/src/gallium/drivers/llvmpipe/lp_tile_size.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,16 +18,22 @@ * 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 + * IN NO EVENT SHALL THE AUTHORS 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. * **************************************************************************/ +#ifndef LP_TILE_SIZE_H +#define LP_TILE_SIZE_H + /** - * Just a global symbol for EGL to look for to identify the supported - * graphics API. + * Tile size (width and height). This needs to be a power of two. */ -int st_api_OpenGL = 1; +#define TILE_ORDER 6 +#define TILE_SIZE (1 << TILE_ORDER) + + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.h b/src/gallium/drivers/llvmpipe/lp_tile_soa.h index 19d00b58d3..eea3ab8499 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.h @@ -30,7 +30,7 @@ #include "pipe/p_compiler.h" #include "tgsi/tgsi_exec.h" /* for NUM_CHANNELS */ - +#include "lp_tile_size.h" #ifdef __cplusplus extern "C" { @@ -40,26 +40,20 @@ extern "C" { struct pipe_transfer; -/** - * Cache tile size (width and height). This needs to be a power of two. - */ -#define TILE_SIZE 64 - - -#define TILE_VECTOR_HEIGHT 2 -#define TILE_VECTOR_WIDTH 8 +#define TILE_VECTOR_HEIGHT 4 +#define TILE_VECTOR_WIDTH 4 extern const unsigned char tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH]; -#define TILE_C_STRIDE (TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH) -#define TILE_X_STRIDE (NUM_CHANNELS*TILE_C_STRIDE) -#define TILE_Y_STRIDE (TILE_VECTOR_HEIGHT*TILE_SIZE*NUM_CHANNELS) +#define TILE_C_STRIDE (TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH) //16 +#define TILE_X_STRIDE (NUM_CHANNELS * TILE_C_STRIDE) //64 +#define TILE_Y_STRIDE (TILE_VECTOR_HEIGHT * TILE_SIZE * NUM_CHANNELS) //1024 #define TILE_PIXEL(_p, _x, _y, _c) \ - ((_p)[((_y)/TILE_VECTOR_HEIGHT)*TILE_Y_STRIDE + \ - ((_x)/TILE_VECTOR_WIDTH)*TILE_X_STRIDE + \ - (_c)*TILE_C_STRIDE + \ + ((_p)[((_y) / TILE_VECTOR_HEIGHT) * TILE_Y_STRIDE + \ + ((_x) / TILE_VECTOR_WIDTH) * TILE_X_STRIDE + \ + (_c) * TILE_C_STRIDE + \ tile_offset[(_y) % TILE_VECTOR_HEIGHT][(_x) % TILE_VECTOR_WIDTH]]) diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py index 004c5c979e..5d53689a3d 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py @@ -129,22 +129,8 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix): print -def generate_format_write(format, src_type, src_native_type, src_suffix): - '''Generate the function to write pixels to a particular format''' - - name = short_name(format) - - dst_native_type = native_type(format) - - print 'static void' - print 'lp_tile_%s_write_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type) - print '{' - print ' unsigned x, y;' - print ' uint8_t *dst_row = dst + y0*dst_stride;' - print ' for (y = 0; y < h; ++y) {' - print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride()) - print ' for (x = 0; x < w; ++x) {' - +def compute_inverse_swizzle(format): + '''Return an array[4] of inverse swizzle terms''' inv_swizzle = [None]*4 if format.colorspace == 'rgb': for i in range(4): @@ -155,8 +141,86 @@ def generate_format_write(format, src_type, src_native_type, src_suffix): swizzle = format.out_swizzle[0] if swizzle < 4: inv_swizzle[swizzle] = 0 - else: - assert False + return inv_swizzle + + +def pack_rgba(format, src_type, r, g, b, a): + """Return an expression for packing r, g, b, a into a pixel of the + given format. Ex: '(b << 24) | (g << 16) | (r << 8) | (a << 0)' + """ + assert format.colorspace == 'rgb' + inv_swizzle = compute_inverse_swizzle(format) + shift = 0 + expr = None + for i in range(4): + # choose r, g, b, or a depending on the inverse swizzle term + if inv_swizzle[i] == 0: + value = r + elif inv_swizzle[i] == 1: + value = g + elif inv_swizzle[i] == 2: + value = b + elif inv_swizzle[i] == 3: + value = a + else: + value = None + + if value: + dst_type = format.in_types[i] + dst_native_type = native_type(format) + value = conversion_expr(src_type, dst_type, dst_native_type, value) + term = "((%s) << %d)" % (value, shift) + if expr: + expr = expr + " | " + term + else: + expr = term + + width = format.in_types[i].size + shift = shift + width + return expr + + +def emit_unrolled_write_code(format, src_type): + '''Emit code for writing a block based on unrolled loops. + This is considerably faster than the TILE_PIXEL-based code below. + ''' + dst_native_type = native_type(format) + print ' const unsigned dstpix_stride = dst_stride / %d;' % format.stride() + print ' %s *dstpix = (%s *) dst;' % (dst_native_type, dst_native_type) + print ' unsigned int qx, qy, i;' + print + print ' for (qy = 0; qy < h; qy += TILE_VECTOR_HEIGHT) {' + print ' const unsigned py = y0 + qy;' + print ' for (qx = 0; qx < w; qx += TILE_VECTOR_WIDTH) {' + print ' const unsigned px = x0 + qx;' + print ' const uint8_t *r = src + 0 * TILE_C_STRIDE;' + print ' const uint8_t *g = src + 1 * TILE_C_STRIDE;' + print ' const uint8_t *b = src + 2 * TILE_C_STRIDE;' + print ' const uint8_t *a = src + 3 * TILE_C_STRIDE;' + print ' (void) r; (void) g; (void) b; (void) a; /* silence warnings */' + print ' for (i = 0; i < TILE_C_STRIDE; i += 2) {' + print ' const uint32_t pixel0 = %s;' % pack_rgba(format, src_type, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]") + print ' const uint32_t pixel1 = %s;' % pack_rgba(format, src_type, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]") + print ' const unsigned offset = (py + tile_y_offset[i]) * dstpix_stride + (px + tile_x_offset[i]);' + print ' dstpix[offset + 0] = pixel0;' + print ' dstpix[offset + 1] = pixel1;' + print ' }' + print ' src += TILE_X_STRIDE;' + print ' }' + print ' }' + + +def emit_tile_pixel_write_code(format, src_type): + '''Emit code for writing a block based on the TILE_PIXEL macro.''' + dst_native_type = native_type(format) + + inv_swizzle = compute_inverse_swizzle(format) + + print ' unsigned x, y;' + print ' uint8_t *dst_row = dst + y0*dst_stride;' + print ' for (y = 0; y < h; ++y) {' + print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride()) + print ' for (x = 0; x < w; ++x) {' if format.layout == ARITH: print ' %s pixel = 0;' % dst_native_type @@ -185,6 +249,20 @@ def generate_format_write(format, src_type, src_native_type, src_suffix): print ' }' print ' dst_row += dst_stride;' print ' }' + + +def generate_format_write(format, src_type, src_native_type, src_suffix): + '''Generate the function to write pixels to a particular format''' + + name = short_name(format) + + print 'static void' + print 'lp_tile_%s_write_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type) + print '{' + if format.layout == ARITH and format.colorspace == 'rgb': + emit_unrolled_write_code(format, src_type) + else: + emit_tile_pixel_write_code(format, src_type) print '}' print @@ -259,8 +337,23 @@ def main(): print print 'const unsigned char' print 'tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH] = {' - print ' { 0, 1, 4, 5, 8, 9, 12, 13},' - print ' { 2, 3, 6, 7, 10, 11, 14, 15}' + print ' { 0, 1, 4, 5},' + print ' { 2, 3, 6, 7},' + print ' { 8, 9, 12, 13},' + print ' { 10, 11, 14, 15}' + print '};' + print + print '/* Note: these lookup tables could be replaced with some' + print ' * bit-twiddling code, but this is a little faster.' + print ' */' + print 'static unsigned tile_x_offset[TILE_VECTOR_WIDTH * TILE_VECTOR_HEIGHT] = {' + print ' 0, 1, 0, 1, 2, 3, 2, 3,' + print ' 0, 1, 0, 1, 2, 3, 2, 3' + print '};' + print + print 'static unsigned tile_y_offset[TILE_VECTOR_WIDTH * TILE_VECTOR_HEIGHT] = {' + print ' 0, 0, 1, 1, 0, 0, 1, 1,' + print ' 2, 2, 3, 3, 2, 2, 3, 3' print '};' print diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h index 74b472b653..ce11fa9304 100644 --- a/src/gallium/drivers/llvmpipe/lp_winsys.h +++ b/src/gallium/drivers/llvmpipe/lp_winsys.h @@ -113,9 +113,6 @@ struct llvmpipe_winsys }; -struct pipe_context * -llvmpipe_create( struct pipe_screen * ); - struct pipe_screen * llvmpipe_create_screen( struct llvmpipe_winsys * ); diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index 0cb66041d5..0e02680bc6 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = nouveau C_SOURCES = nouveau_screen.c \ - nouveau_context.c + nouveau_context.c \ + nv04_surface_2d.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 7ebc94ed6c..156cb2d229 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -3,7 +3,9 @@ #include <pipe/p_state.h> #include <util/u_memory.h> +#include <util/u_inlines.h> +#include <stdio.h> #include <errno.h> #include "nouveau/nouveau_bo.h" @@ -260,6 +262,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) void nouveau_screen_fini(struct nouveau_screen *screen) { + struct pipe_winsys *ws = screen->base.winsys; nouveau_channel_free(&screen->channel); + ws->destroy(ws); } diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 4c3e08a43f..af9ddd558c 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -2,7 +2,7 @@ #define NOUVEAU_WINSYS_H #include <stdint.h> -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "nouveau/nouveau_bo.h" @@ -27,39 +27,12 @@ #define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19) extern struct pipe_screen * -nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *); - -extern struct pipe_context * -nv04_create(struct pipe_screen *, unsigned pctx_id); - -extern struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *); - -extern struct pipe_context * -nv10_create(struct pipe_screen *, unsigned pctx_id); - -extern struct pipe_screen * -nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *); - -extern struct pipe_context * -nv20_create(struct pipe_screen *, unsigned pctx_id); - -extern struct pipe_screen * nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *); -extern struct pipe_context * -nv30_create(struct pipe_screen *, unsigned pctx_id); - extern struct pipe_screen * nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *); -extern struct pipe_context * -nv40_create(struct pipe_screen *, unsigned pctx_id); - extern struct pipe_screen * nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *); -extern struct pipe_context * -nv50_create(struct pipe_screen *, unsigned pctx_id); - #endif diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nouveau/nv04_surface_2d.c index b24a9cee5a..42c2ca932d 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nouveau/nv04_surface_2d.c @@ -60,17 +60,17 @@ nv04_scaled_image_format(enum pipe_format format) case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_I8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8; + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8; case PIPE_FORMAT_A1R5G5B5_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; case PIPE_FORMAT_A8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_A8L8_UNORM: - return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; default: return -1; } @@ -155,7 +155,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, log2i(dst->width) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | log2i(dst->height) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); - BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + BEGIN_RING(chan, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); OUT_RELOCo(chan, src_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); @@ -173,22 +173,22 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + BEGIN_RING(chan, sifm, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); OUT_RING (chan, nv04_scaled_image_format(src->format)); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, (x + dx) | ((y + dy) << NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT)); - OUT_RING (chan, sub_h << NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT | sub_w); - OUT_RING (chan, (x + dx) | ((y + dy) << NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_SHIFT)); - OUT_RING (chan, sub_h << NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT | sub_w); + OUT_RING (chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, (x + dx) | ((y + dy) << NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT)); + OUT_RING (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT | sub_w); + OUT_RING (chan, (x + dx) | ((y + dy) << NV03_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_SHIFT)); + OUT_RING (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT | sub_w); OUT_RING (chan, 1 << 20); OUT_RING (chan, 1 << 20); - BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); - OUT_RING (chan, sub_h << NV04_SCALED_IMAGE_FROM_MEMORY_SIZE_H_SHIFT | sub_w); + BEGIN_RING(chan, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_SIZE_H_SHIFT | sub_w); OUT_RING (chan, src_pitch | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * util_format_get_blocksize(src->texture->format), NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, 0); @@ -421,12 +421,12 @@ nv04_surface_2d_init(struct nouveau_screen *screen) return NULL; } - BEGIN_RING(chan, ctx->blit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1); + BEGIN_RING(chan, ctx->blit, NV01_IMAGE_BLIT_DMA_NOTIFY, 1); OUT_RING (chan, ctx->ntfy->handle); BEGIN_RING(chan, ctx->blit, NV04_IMAGE_BLIT_SURFACE, 1); OUT_RING (chan, ctx->surf2d->handle); - BEGIN_RING(chan, ctx->blit, NV04_IMAGE_BLIT_OPERATION, 1); - OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_SRCCOPY); + BEGIN_RING(chan, ctx->blit, NV01_IMAGE_BLIT_OPERATION, 1); + OUT_RING (chan, NV01_IMAGE_BLIT_OPERATION_SRCCOPY); ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT, &ctx->rect); diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.h b/src/gallium/drivers/nouveau/nv04_surface_2d.h index ce696a11a3..ce696a11a3 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.h +++ b/src/gallium/drivers/nouveau/nv04_surface_2d.h diff --git a/src/gallium/drivers/nv04/Makefile b/src/gallium/drivers/nv04/Makefile deleted file mode 100644 index 7c14bacb1d..0000000000 --- a/src/gallium/drivers/nv04/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv04 - -C_SOURCES = \ - nv04_surface_2d.c \ - nv04_clear.c \ - nv04_context.c \ - nv04_fragprog.c \ - nv04_fragtex.c \ - nv04_miptree.c \ - nv04_prim_vbuf.c \ - nv04_screen.c \ - nv04_state.c \ - nv04_state_emit.c \ - nv04_surface.c \ - nv04_transfer.c \ - nv04_vbo.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv04/nv04_clear.c b/src/gallium/drivers/nv04/nv04_clear.c deleted file mode 100644 index 01cacd36fe..0000000000 --- a/src/gallium/drivers/nv04/nv04_clear.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "nv04_context.h" - -void -nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) -{ - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); -} diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c deleted file mode 100644 index edd96859cf..0000000000 --- a/src/gallium/drivers/nv04/nv04_context.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" - -#include "nv04_context.h" -#include "nv04_screen.h" - -static void -nv04_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv04->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -static void -nv04_destroy(struct pipe_context *pipe) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - if (nv04->draw) - draw_destroy(nv04->draw); - - FREE(nv04); -} - -static boolean -nv04_init_hwctx(struct nv04_context *nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - // requires a valid handle -// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOTIFY, 1); -// OUT_RING(0); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOP, 1); - OUT_RING(chan, 0); - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, 0x40182800); -// OUT_RING(1<<20/*no cull*/); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); -// OUT_RING(0x24|(1<<6)|(1<<8)); - OUT_RING(chan, 0x120001a4); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FORMAT, 1); - OUT_RING(chan, 0x332213a1); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); - OUT_RING(chan, 0x11001010); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); - OUT_RING(chan, 0x0); -// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 1); -// OUT_RING(SCREEN_OFFSET); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1); - OUT_RING(chan, 0xff000000); - - - - FIRE_RING (chan); - return TRUE; -} - -struct pipe_context * -nv04_create(struct pipe_screen *pscreen, unsigned pctx_id) -{ - struct nv04_screen *screen = nv04_screen(pscreen); - struct pipe_winsys *ws = pscreen->winsys; - struct nv04_context *nv04; - struct nouveau_winsys *nvws = screen->nvws; - - nv04 = CALLOC(1, sizeof(struct nv04_context)); - if (!nv04) - return NULL; - nv04->screen = screen; - nv04->pctx_id = pctx_id; - - nv04->nvws = nvws; - - nv04->pipe.winsys = ws; - nv04->pipe.screen = pscreen; - nv04->pipe.destroy = nv04_destroy; - nv04->pipe.draw_arrays = nv04_draw_arrays; - nv04->pipe.draw_elements = nv04_draw_elements; - nv04->pipe.clear = nv04_clear; - nv04->pipe.flush = nv04_flush; - - nv04->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv04->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - - nv04_init_surface_functions(nv04); - nv04_init_state_functions(nv04); - - nv04->draw = draw_create(); - assert(nv04->draw); - draw_wide_point_threshold(nv04->draw, 0.0); - draw_wide_line_threshold(nv04->draw, 0.0); - draw_enable_line_stipple(nv04->draw, FALSE); - draw_enable_point_sprites(nv04->draw, FALSE); - draw_set_rasterize_stage(nv04->draw, nv04_draw_vbuf_stage(nv04)); - - nv04_init_hwctx(nv04); - - return &nv04->pipe; -} - diff --git a/src/gallium/drivers/nv04/nv04_context.h b/src/gallium/drivers/nv04/nv04_context.h deleted file mode 100644 index fe3b527423..0000000000 --- a/src/gallium/drivers/nv04/nv04_context.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef __NV04_CONTEXT_H__ -#define __NV04_CONTEXT_H__ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.h" - -#include "nv04_state.h" - -#define NOUVEAU_ERR(fmt, args...) \ - fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); -#define NOUVEAU_MSG(fmt, args...) \ - fprintf(stderr, "nouveau: "fmt, ##args); - -#include "nv04_screen.h" - -#define NV04_NEW_VERTPROG (1 << 1) -#define NV04_NEW_FRAGPROG (1 << 2) -#define NV04_NEW_BLEND (1 << 3) -#define NV04_NEW_RAST (1 << 4) -#define NV04_NEW_CONTROL (1 << 5) -#define NV04_NEW_VIEWPORT (1 << 6) -#define NV04_NEW_SAMPLER (1 << 7) -#define NV04_NEW_FRAMEBUFFER (1 << 8) -#define NV04_NEW_VTXARRAYS (1 << 9) - -struct nv04_context { - struct pipe_context pipe; - - struct nouveau_winsys *nvws; - struct nv04_screen *screen; - unsigned pctx_id; - - struct draw_context *draw; - - int chipset; - struct nouveau_notifier *sync; - - uint32_t dirty; - - struct nv04_blend_state *blend; - struct nv04_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - struct nv04_fragtex_state fragtex; - struct nv04_rasterizer_state *rast; - struct nv04_depth_stencil_alpha_state *dsa; - - struct nv04_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; - unsigned dirty_samplers; - unsigned fp_samplers; - unsigned vp_samplers; - - uint32_t rt_enable; - struct pipe_framebuffer_state *framebuffer; - struct pipe_surface *rt; - struct pipe_surface *zeta; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[16]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - struct vertex_info vertex_info; - struct { - - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - - struct nv04_vertex_program *active; - - struct nv04_vertex_program *current; - struct pipe_buffer *constant_buf; - } vertprog; - - struct { - struct nv04_fragment_program *active; - - struct nv04_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; - - struct pipe_viewport_state viewport; -}; - -static INLINE struct nv04_context * -nv04_context(struct pipe_context *pipe) -{ - return (struct nv04_context *)pipe; -} - -extern void nv04_init_state_functions(struct nv04_context *nv04); -extern void nv04_init_surface_functions(struct nv04_context *nv04); -extern void nv04_screen_init_miptree_functions(struct pipe_screen *screen); - -/* nv04_clear.c */ -extern void nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); - -/* nv04_draw.c */ -extern struct draw_stage *nv04_draw_render_stage(struct nv04_context *nv04); - -/* nv04_fragprog.c */ -extern void nv04_fragprog_bind(struct nv04_context *, - struct nv04_fragment_program *); -extern void nv04_fragprog_destroy(struct nv04_context *, - struct nv04_fragment_program *); - -/* nv04_fragtex.c */ -extern void nv04_fragtex_bind(struct nv04_context *); - -/* nv04_prim_vbuf.c */ -struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ); - -/* nv04_state.c and friends */ -extern void nv04_emit_hw_state(struct nv04_context *nv04); -extern void nv04_state_tex_update(struct nv04_context *nv04); - -/* nv04_vbo.c */ -extern void nv04_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv04_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count); - - -#endif diff --git a/src/gallium/drivers/nv04/nv04_fragprog.c b/src/gallium/drivers/nv04/nv04_fragprog.c deleted file mode 100644 index 8a2af41fe0..0000000000 --- a/src/gallium/drivers/nv04/nv04_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_util.h" - -#include "nv04_context.h" - -void -nv04_fragprog_bind(struct nv04_context *nv04, struct nv04_fragment_program *fp) -{ -} - -void -nv04_fragprog_destroy(struct nv04_context *nv04, - struct nv04_fragment_program *fp) -{ -} - diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c deleted file mode 100644 index c152b52119..0000000000 --- a/src/gallium/drivers/nv04/nv04_fragtex.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "nv04_context.h" -#include "nouveau/nouveau_util.h" - -#define _(m,tf) \ -{ \ - PIPE_FORMAT_##m, \ - NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf, \ -} - -struct nv04_texture_format { - uint pipe; - int format; -}; - -static struct nv04_texture_format -nv04_texture_formats[] = { - _(A8R8G8B8_UNORM, A8R8G8B8), - _(X8R8G8B8_UNORM, X8R8G8B8), - _(A1R5G5B5_UNORM, A1R5G5B5), - _(A4R4G4B4_UNORM, A4R4G4B4), - _(L8_UNORM, Y8 ), - _(A8_UNORM, Y8 ), -}; - -static uint32_t -nv04_fragtex_format(uint pipe_format) -{ - struct nv04_texture_format *tf = nv04_texture_formats; - int i; - - for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) { - if (tf->pipe == pipe_format) - return tf->format; - tf++; - } - - NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); - return 0; -} - - -static void -nv04_fragtex_build(struct nv04_context *nv04, int unit) -{ - struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; - struct pipe_texture *pt = &nv04mt->base; - - switch (pt->target) { - case PIPE_TEXTURE_2D: - break; - default: - NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; - } - - nv04->fragtex.format = NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER - | NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER - | nv04_fragtex_format(pt->format) - | ( (pt->last_level + 1) << NV04_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT ) - | ( log2i(pt->width0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) - | ( log2i(pt->height0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) - | NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE - | NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE - ; -} - - -void -nv04_fragtex_bind(struct nv04_context *nv04) -{ - nv04_fragtex_build(nv04, 0); -} - diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c deleted file mode 100644 index e0a6948aeb..0000000000 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_math.h" - -#include "nv04_context.h" -#include "nv04_screen.h" - -static void -nv04_miptree_layout(struct nv04_miptree *nv04mt) -{ - struct pipe_texture *pt = &nv04mt->base; - uint offset = 0; - int nr_faces, l; - - nr_faces = 1; - - for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].pitch = pt->width0; - nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; - } - - for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - /* XXX guess was obviously missing */ - nv04mt->level[l].image_offset[0] = offset; - offset += nv04mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv04mt->total_size = offset; -} - -static struct pipe_texture * -nv04_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) -{ - struct nv04_miptree *mt; - - mt = MALLOC(sizeof(struct nv04_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - - //mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - - nv04_miptree_layout(mt); - - mt->buffer = pscreen->buffer_create(pscreen, 256, PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE, - mt->total_size); - if (!mt->buffer) { - printf("failed %d byte alloc\n",mt->total_size); - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv04_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv04_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static void -nv04_miptree_destroy(struct pipe_texture *pt) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)pt; - int l; - - pipe_buffer_reference(&mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (mt->level[l].image_offset) - FREE(mt->level[l].image_offset); - } - - FREE(mt); -} - -static struct pipe_surface * -nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct nv04_miptree *nv04mt = (struct nv04_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv04mt->level[level].pitch; - - ns->base.offset = nv04mt->level[level].image_offset[0]; - - return &ns->base; -} - -static void -nv04_miptree_surface_del(struct pipe_surface *ps) -{ - pipe_texture_reference(&ps->texture, NULL); - FREE(ps); -} - -void -nv04_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv04_miptree_create; - pscreen->texture_blanket = nv04_miptree_blanket; - pscreen->texture_destroy = nv04_miptree_destroy; - pscreen->get_tex_surface = nv04_miptree_surface_new; - pscreen->tex_surface_destroy = nv04_miptree_surface_del; -} - diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c deleted file mode 100644 index 0b795ea243..0000000000 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ /dev/null @@ -1,339 +0,0 @@ - -#include "util/u_debug.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_compiler.h" - -#include "draw/draw_vbuf.h" - -#include "nv04_context.h" -#include "nv04_state.h" - -#define VERTEX_SIZE 40 -#define VERTEX_BUFFER_SIZE (4096*VERTEX_SIZE) // 4096 vertices of 40 bytes each - -/** - * Primitive renderer for nv04. - */ -struct nv04_vbuf_render { - struct vbuf_render base; - - struct nv04_context *nv04; - - /** Vertex buffer */ - unsigned char* buffer; - - /** Vertex size in bytes */ - unsigned vertex_size; - - /** Current primitive */ - unsigned prim; -}; - - -/** - * Basically a cast wrapper. - */ -static INLINE struct nv04_vbuf_render * -nv04_vbuf_render( struct vbuf_render *render ) -{ - assert(render); - return (struct nv04_vbuf_render *)render; -} - - -static const struct vertex_info * -nv04_vbuf_render_get_vertex_info( struct vbuf_render *render ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - struct nv04_context *nv04 = nv04_render->nv04; - return &nv04->vertex_info; -} - - -static boolean -nv04_vbuf_render_allocate_vertices( struct vbuf_render *render, - ushort vertex_size, - ushort nr_vertices ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - - nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE); - assert(!nv04_render->buffer); - - return nv04_render->buffer ? TRUE : FALSE; -} - -static void * -nv04_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - return nv04_render->buffer; -} - -static void -nv04_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ -} - -static boolean -nv04_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - - if (prim <= PIPE_PRIM_LINE_STRIP) - return FALSE; - - nv04_render->prim = prim; - return TRUE; -} - -static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA), 49); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v4,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v5,8); - OUT_RING(chan, 0xFEDCBA); -} - -static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD), 25); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RING(chan, 0xFED); -} - -static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC), 33); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8); - OUT_RING(chan, 0xFECEDC); -} - -static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices) -{ - unsigned char* buffer = render->buffer; - struct nv04_context* nv04 = render->nv04; - int i; - - for( i=0; i< nr_indices-5; i+=6) - nv04_2triangles(nv04, - buffer, - indices[i+0], - indices[i+1], - indices[i+2], - indices[i+3], - indices[i+4], - indices[i+5] - ); - if (i != nr_indices) - { - nv04_1triangle(nv04, - buffer, - indices[i+0], - indices[i+1], - indices[i+2] - ); - i+=3; - } - if (i != nr_indices) - NOUVEAU_ERR("Houston, we have lost some vertices\n"); -} - -static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) -{ - const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; - unsigned char* buffer = render->buffer; - struct nv04_context *nv04 = render->nv04; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - int i,j; - - for(i = 0; i<nr_indices; i+=14) - { - int numvert = MIN2(16, nr_indices - i); - int numtri = numvert - 2; - if (numvert<3) - break; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8); - for(j = 0; j<numvert; j++) - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices [i+j], 8 ); - - BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2 ); - for(j = 0; j<numtri/2; j++ ) - OUT_RING(chan, striptbl[j]); - if (numtri%2) - OUT_RING(chan, striptbl[numtri/2]&0xFFF); - } -} - -static void nv04_vbuf_render_tri_fan_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) -{ - const uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; - unsigned char* buffer = render->buffer; - struct nv04_context *nv04 = render->nv04; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - int i,j; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[0], 8); - - for(i = 1; i<nr_indices; i+=14) - { - int numvert=MIN2(15, nr_indices - i); - int numtri=numvert-2; - if (numvert < 3) - break; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8); - - for(j=0;j<numvert;j++) - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[ i+j ], 8 ); - - BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2); - for(j = 0; j<numtri/2; j++) - OUT_RING(chan, fantbl[j]); - if (numtri%2) - OUT_RING(chan, fantbl[numtri/2]&0xFFF); - } -} - -static void nv04_vbuf_render_quads_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) -{ - unsigned char* buffer = render->buffer; - struct nv04_context* nv04 = render->nv04; - int i; - - for(i = 0; i < nr_indices; i += 4) - nv04_1quad(nv04, - buffer, - indices[i+0], - indices[i+1], - indices[i+2], - indices[i+3] - ); -} - - -static void -nv04_vbuf_render_draw( struct vbuf_render *render, - const ushort *indices, - uint nr_indices) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - - // emit the indices - switch( nv04_render->prim ) - { - case PIPE_PRIM_TRIANGLES: - nv04_vbuf_render_triangles_elts(nv04_render, indices, nr_indices); - break; - case PIPE_PRIM_QUAD_STRIP: - case PIPE_PRIM_TRIANGLE_STRIP: - nv04_vbuf_render_tri_strip_elts(nv04_render, indices, nr_indices); - break; - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - nv04_vbuf_render_tri_fan_elts(nv04_render, indices, nr_indices); - break; - case PIPE_PRIM_QUADS: - nv04_vbuf_render_quads_elts(nv04_render, indices, nr_indices); - break; - default: - NOUVEAU_ERR("You have to implement primitive %d, young padawan\n", nv04_render->prim); - break; - } -} - - -static void -nv04_vbuf_render_release_vertices( struct vbuf_render *render ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - - free(nv04_render->buffer); - nv04_render->buffer = NULL; -} - - -static void -nv04_vbuf_render_destroy( struct vbuf_render *render ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - FREE(nv04_render); -} - - -/** - * Create a new primitive render. - */ -static struct vbuf_render * -nv04_vbuf_render_create( struct nv04_context *nv04 ) -{ - struct nv04_vbuf_render *nv04_render = CALLOC_STRUCT(nv04_vbuf_render); - - nv04_render->nv04 = nv04; - - nv04_render->base.max_vertex_buffer_bytes = VERTEX_BUFFER_SIZE; - nv04_render->base.max_indices = 65536; - nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info; - nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices; - nv04_render->base.map_vertices = nv04_vbuf_render_map_vertices; - nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_vertices; - nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive; - nv04_render->base.draw = nv04_vbuf_render_draw; - nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices; - nv04_render->base.destroy = nv04_vbuf_render_destroy; - - return &nv04_render->base; -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ) -{ - struct vbuf_render *render; - struct draw_stage *stage; - - render = nv04_vbuf_render_create(nv04); - if(!render) - return NULL; - - stage = draw_vbuf_stage( nv04->draw, render ); - if(!stage) { - render->destroy(render); - return NULL; - } - - return stage; -} diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c deleted file mode 100644 index 7c5b6e8229..0000000000 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ /dev/null @@ -1,212 +0,0 @@ -#include "pipe/p_screen.h" -#include "pipe/p_inlines.h" - -#include "nv04_context.h" -#include "nv04_screen.h" - -static int -nv04_screen_get_param(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 1; - case PIPE_CAP_NPOT_TEXTURES: - return 0; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 0; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; - case PIPE_CAP_POINT_SPRITE: - return 0; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 0; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 10; - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 0; - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 0; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - return 0; - case PIPE_CAP_TEXTURE_MIRROR_REPEAT: - return 1; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv04_screen_get_paramf(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 0.0; - case PIPE_CAP_MAX_POINT_WIDTH: - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 0.0; - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 0.0; - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 0.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - -static boolean -nv04_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -nv04_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv04_screen *screen = nv04_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->fahrenheit); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv04_surface_buffer(struct pipe_surface *surf) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned fahrenheit_class = 0, sub3d_class = 0; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv04_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv04_screen_destroy; - pscreen->get_param = nv04_screen_get_param; - pscreen->get_paramf = nv04_screen_get_paramf; - pscreen->is_format_supported = nv04_screen_is_format_supported; - - nv04_screen_init_miptree_functions(pscreen); - nv04_screen_init_transfer_functions(pscreen); - - if (dev->chipset >= 0x20) { - fahrenheit_class = 0; - sub3d_class = 0; - } else if (dev->chipset >= 0x10) { - fahrenheit_class = NV10_TEXTURED_TRIANGLE; - sub3d_class = NV10_CONTEXT_SURFACES_3D; - } else { - fahrenheit_class=NV04_TEXTURED_TRIANGLE; - sub3d_class = NV04_CONTEXT_SURFACES_3D; - } - - if (!fahrenheit_class) { - NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", dev->chipset); - return NULL; - } - - /* 3D object */ - ret = nouveau_grobj_alloc(chan, 0xbeef0001, fahrenheit_class, - &screen->fahrenheit); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return NULL; - } - BIND_RING(chan, screen->fahrenheit, 7); - - /* 3D surface object */ - ret = nouveau_grobj_alloc(chan, 0xbeef0002, sub3d_class, - &screen->context_surfaces_3d); - if (ret) { - NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret); - return NULL; - } - BIND_RING(chan, screen->context_surfaces_3d, 6); - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv04_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv04_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv04/nv04_screen.h b/src/gallium/drivers/nv04/nv04_screen.h deleted file mode 100644 index 11466b9442..0000000000 --- a/src/gallium/drivers/nv04/nv04_screen.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __NV04_SCREEN_H__ -#define __NV04_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04_surface_2d.h" - -struct nv04_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - unsigned chipset; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - struct nouveau_grobj *fahrenheit; - struct nouveau_grobj *context_surfaces_3d; - struct nouveau_notifier *sync; - -}; - -static INLINE struct nv04_screen * -nv04_screen(struct pipe_screen *screen) -{ - return (struct nv04_screen *)screen; -} - -void -nv04_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c deleted file mode 100644 index e3dc4c5bf4..0000000000 --- a/src/gallium/drivers/nv04/nv04_state.c +++ /dev/null @@ -1,459 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_inlines.h" - -#include "tgsi/tgsi_parse.h" - -#include "nv04_context.h" -#include "nv04_state.h" - -static void * -nv04_blend_state_create(struct pipe_context *pipe, - const struct pipe_blend_state *cso) -{ - struct nv04_blend_state *cb; - - cb = MALLOC(sizeof(struct nv04_blend_state)); - - cb->b_enable = cso->blend_enable ? 1 : 0; - cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rgb_src_factor))); - cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rgb_dst_factor))); - - - return (void *)cb; -} - -static void -nv04_blend_state_bind(struct pipe_context *pipe, void *blend) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->blend = (struct nv04_blend_state*)blend; - - nv04->dirty |= NV04_NEW_BLEND; -} - -static void -nv04_blend_state_delete(struct pipe_context *pipe, void *hwcso) -{ - free(hwcso); -} - - -static INLINE unsigned -wrap_mode(unsigned wrap) { - unsigned ret; - - switch (wrap) { - case PIPE_TEX_WRAP_REPEAT: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT; - break; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT; - break; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE; - break; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER; - break; - case PIPE_TEX_WRAP_CLAMP: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; - break; - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: - case PIPE_TEX_WRAP_MIRROR_CLAMP: - default: - NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; - } - return ret >> NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT; -} - -static void * -nv04_sampler_state_create(struct pipe_context *pipe, - const struct pipe_sampler_state *cso) -{ - - struct nv04_sampler_state *ss; - uint32_t filter = 0; - - ss = MALLOC(sizeof(struct nv04_sampler_state)); - - ss->format = ((wrap_mode(cso->wrap_s) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) | - (wrap_mode(cso->wrap_t) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT)); - - if (cso->max_anisotropy > 1.0) { - filter |= NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE; - } - - switch (cso->mag_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR; - break; - case PIPE_TEX_FILTER_NEAREST: - default: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; - break; - } - - switch (cso->min_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - switch (cso->min_mip_filter) { - case PIPE_TEX_MIPFILTER_NEAREST: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR; - break; - } - break; - case PIPE_TEX_FILTER_NEAREST: - default: - switch (cso->min_mip_filter) { - case PIPE_TEX_MIPFILTER_NEAREST: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST; - break; - } - break; - } - - ss->filter = filter; - - return (void *)ss; -} - -static void -nv04_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) -{ - struct nv04_context *nv04 = nv04_context(pipe); - unsigned unit; - - for (unit = 0; unit < nr; unit++) { - nv04->sampler[unit] = sampler[unit]; - nv04->dirty_samplers |= (1 << unit); - } -} - -static void -nv04_sampler_state_delete(struct pipe_context *pipe, void *hwcso) -{ - free(hwcso); -} - -static void -nv04_set_sampler_texture(struct pipe_context *pipe, unsigned nr, - struct pipe_texture **miptree) -{ - struct nv04_context *nv04 = nv04_context(pipe); - unsigned unit; - - for (unit = 0; unit < nr; unit++) { - nv04->tex_miptree[unit] = (struct nv04_miptree *)miptree[unit]; - nv04->dirty_samplers |= (1 << unit); - } -} - -static void * -nv04_rasterizer_state_create(struct pipe_context *pipe, - const struct pipe_rasterizer_state *cso) -{ - struct nv04_rasterizer_state *rs; - - /*XXX: ignored: - * scissor - * points/lines (no hw support, emulated with tris in gallium) - */ - rs = MALLOC(sizeof(struct nv04_rasterizer_state)); - - rs->blend = cso->flatshade ? NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; - - return (void *)rs; -} - -static void -nv04_rasterizer_state_bind(struct pipe_context *pipe, void *rast) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->rast = (struct nv04_rasterizer_state*)rast; - - draw_set_rasterizer_state(nv04->draw, (nv04->rast ? nv04->rast->templ : NULL)); - - nv04->dirty |= NV04_NEW_RAST | NV04_NEW_BLEND; -} - -static void -nv04_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) -{ - free(hwcso); -} - -static INLINE uint32_t nv04_compare_func(uint32_t f) -{ - switch ( f ) { - case PIPE_FUNC_NEVER: return 1; - case PIPE_FUNC_LESS: return 2; - case PIPE_FUNC_EQUAL: return 3; - case PIPE_FUNC_LEQUAL: return 4; - case PIPE_FUNC_GREATER: return 5; - case PIPE_FUNC_NOTEQUAL: return 6; - case PIPE_FUNC_GEQUAL: return 7; - case PIPE_FUNC_ALWAYS: return 8; - } - NOUVEAU_MSG("Unable to find the function\n"); - return 0; -} - -static void * -nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *cso) -{ - struct nv04_depth_stencil_alpha_state *hw; - - hw = MALLOC(sizeof(struct nv04_depth_stencil_alpha_state)); - - hw->control = float_to_ubyte(cso->alpha.ref_value); - hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT ); - hw->control |= cso->alpha.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE : 0; - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN; - hw->control |= cso->depth.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE : 0; - hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT ); - hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE; - hw->control |= cso->depth.writemask ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE : 0; - hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format - - return (void *)hw; -} - -static void -nv04_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->dsa = hwcso; - nv04->dirty |= NV04_NEW_CONTROL; -} - -static void -nv04_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) -{ - free(hwcso); -} - -static void * -nv04_vp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - return draw_create_vertex_shader(nv04->draw, templ); -} - -static void -nv04_vp_state_bind(struct pipe_context *pipe, void *shader) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - draw_bind_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); - - nv04->dirty |= NV04_NEW_VERTPROG; -} - -static void -nv04_vp_state_delete(struct pipe_context *pipe, void *shader) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - draw_delete_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); -} - -static void * -nv04_fp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) -{ - struct nv04_fragment_program *fp; - - fp = CALLOC(1, sizeof(struct nv04_fragment_program)); - fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); - - return (void *)fp; -} - -static void -nv04_fp_state_bind(struct pipe_context *pipe, void *hwcso) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_fragment_program *fp = hwcso; - - nv04->fragprog.current = fp; - nv04->dirty |= NV04_NEW_FRAGPROG; -} - -static void -nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_fragment_program *fp = hwcso; - - nv04_fragprog_destroy(nv04, fp); - free((void*)fp->pipe.tokens); - free(fp); -} - -static void -nv04_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *bcol) -{ -} - -static void -nv04_set_clip_state(struct pipe_context *pipe, - const struct pipe_clip_state *clip) -{ -} - -static void -nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf ) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct pipe_screen *pscreen = pipe->screen; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - if (buf) { - void *mapped; - if (buf->buffer && buf->buffer->size && - (mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ))) - { - memcpy(nv04->constbuf[shader], mapped, buf->buffer->size); - nv04->constbuf_nr[shader] = - buf->buffer->size / (4 * sizeof(float)); - pipe_buffer_unmap(pscreen, buf->buffer); - } - } -} - -static void -nv04_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->framebuffer = (struct pipe_framebuffer_state*)fb; - - nv04->dirty |= NV04_NEW_FRAMEBUFFER; -} -static void -nv04_set_polygon_stipple(struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple) -{ - NOUVEAU_ERR("line stipple hahaha\n"); -} - -static void -nv04_set_scissor_state(struct pipe_context *pipe, - const struct pipe_scissor_state *s) -{ -/* struct nv04_context *nv04 = nv04_context(pipe); - - // XXX - BEGIN_RING(fahrenheit, NV04_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2); - OUT_RING (((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ -} - -static void -nv04_set_viewport_state(struct pipe_context *pipe, - const struct pipe_viewport_state *viewport) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->viewport = *viewport; - - draw_set_viewport_state(nv04->draw, &nv04->viewport); -} - -static void -nv04_set_vertex_buffers(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_buffer *buffers) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - memcpy(nv04->vtxbuf, buffers, count * sizeof(buffers[0])); - nv04->dirty |= NV04_NEW_VTXARRAYS; - - draw_set_vertex_buffers(nv04->draw, count, buffers); -} - -static void -nv04_set_vertex_elements(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_element *elements) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - memcpy(nv04->vtxelt, elements, sizeof(*elements) * count); - nv04->dirty |= NV04_NEW_VTXARRAYS; - - draw_set_vertex_elements(nv04->draw, count, elements); -} - -void -nv04_init_state_functions(struct nv04_context *nv04) -{ - nv04->pipe.create_blend_state = nv04_blend_state_create; - nv04->pipe.bind_blend_state = nv04_blend_state_bind; - nv04->pipe.delete_blend_state = nv04_blend_state_delete; - - nv04->pipe.create_sampler_state = nv04_sampler_state_create; - nv04->pipe.bind_fragment_sampler_states = nv04_sampler_state_bind; - nv04->pipe.delete_sampler_state = nv04_sampler_state_delete; - nv04->pipe.set_fragment_sampler_textures = nv04_set_sampler_texture; - - nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create; - nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind; - nv04->pipe.delete_rasterizer_state = nv04_rasterizer_state_delete; - - nv04->pipe.create_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_create; - nv04->pipe.bind_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_bind; - nv04->pipe.delete_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_delete; - - nv04->pipe.create_vs_state = nv04_vp_state_create; - nv04->pipe.bind_vs_state = nv04_vp_state_bind; - nv04->pipe.delete_vs_state = nv04_vp_state_delete; - - nv04->pipe.create_fs_state = nv04_fp_state_create; - nv04->pipe.bind_fs_state = nv04_fp_state_bind; - nv04->pipe.delete_fs_state = nv04_fp_state_delete; - - nv04->pipe.set_blend_color = nv04_set_blend_color; - nv04->pipe.set_clip_state = nv04_set_clip_state; - nv04->pipe.set_constant_buffer = nv04_set_constant_buffer; - nv04->pipe.set_framebuffer_state = nv04_set_framebuffer_state; - nv04->pipe.set_polygon_stipple = nv04_set_polygon_stipple; - nv04->pipe.set_scissor_state = nv04_set_scissor_state; - nv04->pipe.set_viewport_state = nv04_set_viewport_state; - - nv04->pipe.set_vertex_buffers = nv04_set_vertex_buffers; - nv04->pipe.set_vertex_elements = nv04_set_vertex_elements; -} - diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h deleted file mode 100644 index 81d1d2ebaa..0000000000 --- a/src/gallium/drivers/nv04/nv04_state.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __NV04_STATE_H__ -#define __NV04_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/tgsi_scan.h" - -struct nv04_blend_state { - uint32_t b_enable; - uint32_t b_src; - uint32_t b_dst; -}; - -struct nv04_fragtex_state { - uint32_t format; -}; - -struct nv04_sampler_state { - uint32_t filter; - uint32_t format; -}; - -struct nv04_depth_stencil_alpha_state { - uint32_t control; -}; - -struct nv04_rasterizer_state { - uint32_t blend; - - const struct pipe_rasterizer_state *templ; -}; - -struct nv04_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; - - struct pipe_buffer *buffer; - uint total_size; - - struct { - uint pitch; - uint *image_offset; - } level[PIPE_MAX_TEXTURE_LEVELS]; -}; - -struct nv04_fragment_program_data { - unsigned offset; - unsigned index; -}; - -struct nv04_fragment_program { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - - boolean translated; - boolean on_hw; - unsigned samplers; - - uint32_t *insn; - int insn_len; - - struct nv04_fragment_program_data *consts; - unsigned nr_consts; - - struct pipe_buffer *buffer; - - uint32_t fp_control; - uint32_t fp_reg_control; -}; - - - -#endif diff --git a/src/gallium/drivers/nv04/nv04_state_emit.c b/src/gallium/drivers/nv04/nv04_state_emit.c deleted file mode 100644 index b8d6dc560f..0000000000 --- a/src/gallium/drivers/nv04/nv04_state_emit.c +++ /dev/null @@ -1,246 +0,0 @@ -#include "nv04_context.h" -#include "nv04_state.h" - -static void nv04_vertex_layout(struct pipe_context* pipe) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_fragment_program *fp = nv04->fragprog.current; - uint32_t src = 0; - int i; - struct vertex_info vinfo; - - memset(&vinfo, 0, sizeof(vinfo)); - - for (i = 0; i < fp->info.num_inputs; i++) { - int isn = fp->info.input_semantic_name[i]; - int isi = fp->info.input_semantic_index[i]; - switch (isn) { - case TGSI_SEMANTIC_POSITION: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); - break; - case TGSI_SEMANTIC_COLOR: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); - break; - default: - case TGSI_SEMANTIC_GENERIC: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); - break; - case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); - break; - } - } - - printf("%d vertex input\n",fp->info.num_inputs); - draw_compute_vertex_size(&vinfo); -} - -static uint32_t nv04_blend_func(uint32_t f) -{ - switch ( f ) { - case PIPE_BLENDFACTOR_ZERO: return 0x1; - case PIPE_BLENDFACTOR_ONE: return 0x2; - case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4; - case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6; - case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8; - case PIPE_BLENDFACTOR_DST_COLOR: return 0x9; - case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB; - } - NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f); - return 0; -} - -static void nv04_emit_control(struct nv04_context* nv04) -{ - uint32_t control = nv04->dsa->control; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, control); -} - -static void nv04_emit_blend(struct nv04_context* nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - uint32_t blend; - - blend=0x4; // texture MODULATE_ALPHA - blend|=0x20; // alpha is MSB - blend|=(2<<6); // flat shading - blend|=(1<<8); // persp correct - blend|=(0<<16); // no fog - blend|=(nv04->blend->b_enable<<20); - blend|=(nv04_blend_func(nv04->blend->b_src)<<24); - blend|=(nv04_blend_func(nv04->blend->b_dst)<<28); - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); - OUT_RING(chan, blend); -} - -static void nv04_emit_sampler(struct nv04_context *nv04, int unit) -{ - struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; - struct pipe_texture *pt = &nv04mt->base; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer); - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 3); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING(chan, nv04->sampler[unit]->filter); -} - -static void nv04_state_emit_framebuffer(struct nv04_context* nv04) -{ - struct pipe_framebuffer_state* fb = nv04->framebuffer; - struct nv04_surface *rt, *zeta; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv04_miptree *nv04mt = 0; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d; - struct nouveau_bo *bo; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)fb->cbufs[0]; - - if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - - zeta_format = fb->zsbuf->format; - zeta = (struct nv04_surface *)fb->zsbuf; - } - - switch (colour_format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format = 0x108; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format = 0x103; - break; - default: - assert(0); - } - - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); - OUT_RING(chan, rt_format); - - nv04mt = (struct nv04_miptree *)rt->base.texture; - bo = nouveau_bo(nv04mt->buffer); - /* FIXME pitches have to be aligned ! */ - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(chan, rt->pitch|(zeta->pitch<<16)); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - if (fb->zsbuf) { - nv04mt = (struct nv04_miptree *)zeta->base.texture; - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - } -} - -void -nv04_emit_hw_state(struct nv04_context *nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d; - int i; - - if (nv04->dirty & NV04_NEW_VERTPROG) { - //nv04_vertprog_bind(nv04, nv04->vertprog.current); - nv04->dirty &= ~NV04_NEW_VERTPROG; - } - - if (nv04->dirty & NV04_NEW_FRAGPROG) { - nv04_fragprog_bind(nv04, nv04->fragprog.current); - nv04->dirty &= ~NV04_NEW_FRAGPROG; - nv04->dirty_samplers |= (1<<10); - nv04->dirty_samplers = 0; - } - - if (nv04->dirty & NV04_NEW_CONTROL) { - nv04->dirty &= ~NV04_NEW_CONTROL; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, nv04->dsa->control); - } - - if (nv04->dirty & NV04_NEW_BLEND) { - nv04->dirty &= ~NV04_NEW_BLEND; - - nv04_emit_blend(nv04); - } - - if (nv04->dirty & NV04_NEW_VTXARRAYS) { - nv04->dirty &= ~NV04_NEW_VTXARRAYS; - nv04_vertex_layout(nv04); - } - - if (nv04->dirty & NV04_NEW_SAMPLER) { - nv04->dirty &= ~NV04_NEW_SAMPLER; - - nv04_emit_sampler(nv04, 0); - } - - if (nv04->dirty & NV04_NEW_VIEWPORT) { - nv04->dirty &= ~NV04_NEW_VIEWPORT; -// nv04_state_emit_viewport(nv04); - } - - if (nv04->dirty & NV04_NEW_FRAMEBUFFER) { - nv04->dirty &= ~NV04_NEW_FRAMEBUFFER; - nv04_state_emit_framebuffer(nv04); - } - - /* Emit relocs for every referenced buffer. - * This is to ensure the bufmgr has an accurate idea of how - * the buffer is used. This isn't very efficient, but we don't - * seem to take a significant performance hit. Will be improved - * at some point. Vertex arrays are emitted by nv04_vbo.c - */ - - /* Render target */ - unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch; - unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch; - - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(chan, rt_pitch|(zeta_pitch<<16)); - OUT_RELOCl(chan, nouveau_bo(nv04->rt), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - if (nv04->zeta) { - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); - OUT_RELOCl(chan, nouveau_bo(nv04->zeta), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - } - - /* Texture images */ - for (i = 0; i < 1; i++) { - if (!(nv04->fp_samplers & (1 << i))) - continue; - struct nv04_miptree *nv04mt = nv04->tex_miptree[i]; - struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 2); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - } -} - diff --git a/src/gallium/drivers/nv04/nv04_surface.c b/src/gallium/drivers/nv04/nv04_surface.c deleted file mode 100644 index 0387ff4e78..0000000000 --- a/src/gallium/drivers/nv04/nv04_surface.c +++ /dev/null @@ -1,63 +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 "nv04_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" -#include "util/u_tile.h" - -static void -nv04_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_surface_2d *eng2d = nv04->screen->eng2d; - - eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); -} - -static void -nv04_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct nv04_surface_2d *eng2d = nv04->screen->eng2d; - - eng2d->fill(eng2d, dest, destx, desty, width, height, value); -} - -void -nv04_init_surface_functions(struct nv04_context *nv04) -{ - nv04->pipe.surface_copy = nv04_surface_copy; - nv04->pipe.surface_fill = nv04_surface_fill; -} diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c deleted file mode 100644 index 2dd2e146a8..0000000000 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <pipe/p_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv04_context.h" -#include "nv04_screen.h" -#include "nv04_state.h" - -struct nv04_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)pt; - struct nv04_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv04_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv04_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv04_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv04_screen *nvscreen = nv04_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv04_transfer_del(struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - - if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv04_screen *nvscreen = nv04_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv04_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv04_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv04_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv04_transfer_new; - pscreen->tex_transfer_destroy = nv04_transfer_del; - pscreen->transfer_map = nv04_transfer_map; - pscreen->transfer_unmap = nv04_transfer_unmap; -} diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c deleted file mode 100644 index 3484771814..0000000000 --- a/src/gallium/drivers/nv04/nv04_vbo.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_inlines.h" - -#include "nv04_context.h" -#include "nv04_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void nv04_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) -{ - struct pipe_screen *pscreen = pipe->screen; - struct nv04_context *nv04 = nv04_context( pipe ); - struct draw_context *draw = nv04->draw; - unsigned i; - - nv04_emit_hw_state(nv04); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv04->vtxbuf[i].buffer) { - void *buf - = pipe_buffer_map(pscreen, - nv04->vtxbuf[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_vertex_buffer(draw, i, buf); - } - } - /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes - = pipe_buffer_map(pscreen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, NULL); - } - - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, - nv04->constbuf[PIPE_SHADER_VERTEX], - nv04->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv04->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv04->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv04->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } -} - -void nv04_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - printf("coucou in draw arrays\n"); - nv04_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv10/Makefile b/src/gallium/drivers/nv10/Makefile deleted file mode 100644 index 62677f5194..0000000000 --- a/src/gallium/drivers/nv10/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv10 - -C_SOURCES = \ - nv10_clear.c \ - nv10_context.c \ - nv10_fragprog.c \ - nv10_fragtex.c \ - nv10_miptree.c \ - nv10_prim_vbuf.c \ - nv10_screen.c \ - nv10_state.c \ - nv10_state_emit.c \ - nv10_surface.c \ - nv10_transfer.c \ - nv10_vbo.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c deleted file mode 100644 index a39a2b5f52..0000000000 --- a/src/gallium/drivers/nv10/nv10_clear.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "util/u_clear.h" - -#include "nv10_context.h" - -void -nv10_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil) -{ - util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth, - stencil); -} diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c deleted file mode 100644 index 1ecb73d06e..0000000000 --- a/src/gallium/drivers/nv10/nv10_context.c +++ /dev/null @@ -1,298 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" - -#include "nv10_context.h" -#include "nv10_screen.h" - -static void -nv10_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) -{ - struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv10->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -static void -nv10_destroy(struct pipe_context *pipe) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - if (nv10->draw) - draw_destroy(nv10->draw); - - FREE(nv10); -} - -static void nv10_init_hwctx(struct nv10_context *nv10) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int i; - float projectionmatrix[16]; - - BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1); - OUT_RING (chan, screen->sync->handle); - BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 2); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->gart->handle); - BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); - OUT_RING (chan, (0x7ff<<16)|0x800); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); - OUT_RING (chan, (0x7ff<<16)|0x800); - - for (i=1;i<8;i++) { - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); - OUT_RING (chan, 0); - } - - BEGIN_RING(chan, celsius, 0x290, 1); - OUT_RING (chan, (0x10<<16)|1); - BEGIN_RING(chan, celsius, 0x3f4, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - if (nv10->screen->celsius->grclass != NV10TCL) { - /* For nv11, nv17 */ - BEGIN_RING(chan, celsius, 0x120, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - } - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - /* Set state */ - BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(0), 12); - OUT_RING (chan, 0x30141010); - OUT_RING (chan, 0); - OUT_RING (chan, 0x20040000); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0x18000000); - OUT_RING (chan, 0x300e0300); - OUT_RING (chan, 0x0c091c80); - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x8006); - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1d01); - BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_CONTROL, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); - OUT_RING (chan, 0x201); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (chan, 8); - BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); - OUT_RING (chan, 8); - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, 0x1b02); - OUT_RING (chan, 0x1b02); - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (chan, 0x405); - OUT_RING (chan, 0x901); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8); - for (i=0;i<8;i++) { - OUT_RING (chan, 0); - } - BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); - OUT_RING (chan, 0x3fc00000); /* -1.50 */ - OUT_RING (chan, 0xbdb8aa0a); /* -0.09 */ - OUT_RING (chan, 0); /* 0.00 */ - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2); - OUT_RING (chan, 0x802); - OUT_RING (chan, 2); - /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when - * using texturing, except when using the texture matrix - */ - BEGIN_RING(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); - OUT_RING (chan, 6); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (chan, 0x01010101); - - /* Set vertex component */ - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1); - OUT_RINGf (chan, 0.0); - BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, 1); - - memset(projectionmatrix, 0, sizeof(projectionmatrix)); - BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16); - projectionmatrix[0*4+0] = 1.0; - projectionmatrix[1*4+1] = 1.0; - projectionmatrix[2*4+2] = 1.0; - projectionmatrix[3*4+3] = 1.0; - for (i=0;i<16;i++) { - OUT_RINGf (chan, projectionmatrix[i]); - } - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); - OUT_RING (chan, 0.0); - OUT_RINGf (chan, 16777216.0); - - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, 16777215.0 * 0.5); - OUT_RING (chan, 0); - - FIRE_RING (chan); -} - -struct pipe_context * -nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) -{ - struct nv10_screen *screen = nv10_screen(pscreen); - struct pipe_winsys *ws = pscreen->winsys; - struct nv10_context *nv10; - struct nouveau_winsys *nvws = screen->nvws; - - nv10 = CALLOC(1, sizeof(struct nv10_context)); - if (!nv10) - return NULL; - nv10->screen = screen; - nv10->pctx_id = pctx_id; - - nv10->nvws = nvws; - - nv10->pipe.winsys = ws; - nv10->pipe.screen = pscreen; - nv10->pipe.destroy = nv10_destroy; - nv10->pipe.draw_arrays = nv10_draw_arrays; - nv10->pipe.draw_elements = nv10_draw_elements; - nv10->pipe.clear = nv10_clear; - nv10->pipe.flush = nv10_flush; - - nv10->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv10->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - - nv10_init_surface_functions(nv10); - nv10_init_state_functions(nv10); - - nv10->draw = draw_create(); - assert(nv10->draw); - draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); - - nv10_init_hwctx(nv10); - - return &nv10->pipe; -} - diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h deleted file mode 100644 index ab4b825487..0000000000 --- a/src/gallium/drivers/nv10/nv10_context.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __NV10_CONTEXT_H__ -#define __NV10_CONTEXT_H__ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.h" - -#include "nv10_state.h" - -#define NOUVEAU_ERR(fmt, args...) \ - fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); -#define NOUVEAU_MSG(fmt, args...) \ - fprintf(stderr, "nouveau: "fmt, ##args); - -#define NV10_NEW_VERTPROG (1 << 0) -#define NV10_NEW_FRAGPROG (1 << 1) -#define NV10_NEW_VTXARRAYS (1 << 2) -#define NV10_NEW_BLEND (1 << 3) -#define NV10_NEW_BLENDCOL (1 << 4) -#define NV10_NEW_RAST (1 << 5) -#define NV10_NEW_DSA (1 << 6) -#define NV10_NEW_VIEWPORT (1 << 7) -#define NV10_NEW_SCISSOR (1 << 8) -#define NV10_NEW_FRAMEBUFFER (1 << 9) - -#include "nv10_screen.h" - -struct nv10_context { - struct pipe_context pipe; - - struct nouveau_winsys *nvws; - struct nv10_screen *screen; - unsigned pctx_id; - - struct draw_context *draw; - - uint32_t dirty; - - struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; - struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; - unsigned dirty_samplers; - unsigned fp_samplers; - unsigned vp_samplers; - - uint32_t rt_enable; - struct pipe_buffer *rt[4]; - struct pipe_buffer *zeta; - uint32_t lma_offset; - - struct nv10_blend_state *blend; - struct pipe_blend_color *blend_color; - struct nv10_rasterizer_state *rast; - struct nv10_depth_stencil_alpha_state *dsa; - struct pipe_viewport_state *viewport; - struct pipe_scissor_state *scissor; - struct pipe_framebuffer_state *framebuffer; - - //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - struct vertex_info vertex_info; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[2]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - -/* struct { - - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - - struct nv10_vertex_program *active; - - struct nv10_vertex_program *current; - } vertprog; -*/ - struct { - struct nv10_fragment_program *active; - - struct nv10_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; -}; - -static INLINE struct nv10_context * -nv10_context(struct pipe_context *pipe) -{ - return (struct nv10_context *)pipe; -} - -extern void nv10_init_state_functions(struct nv10_context *nv10); -extern void nv10_init_surface_functions(struct nv10_context *nv10); - -extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); - -/* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); - - -/* nv10_draw.c */ -extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); - -/* nv10_fragprog.c */ -extern void nv10_fragprog_bind(struct nv10_context *, - struct nv10_fragment_program *); -extern void nv10_fragprog_destroy(struct nv10_context *, - struct nv10_fragment_program *); - -/* nv10_fragtex.c */ -extern void nv10_fragtex_bind(struct nv10_context *); - -/* nv10_prim_vbuf.c */ -struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ); -extern void nv10_vtxbuf_bind(struct nv10_context* nv10); - -/* nv10_state.c and friends */ -extern void nv10_emit_hw_state(struct nv10_context *nv10); -extern void nv10_state_tex_update(struct nv10_context *nv10); - -/* nv10_vbo.c */ -extern void nv10_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv10_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count); - - -#endif diff --git a/src/gallium/drivers/nv10/nv10_fragprog.c b/src/gallium/drivers/nv10/nv10_fragprog.c deleted file mode 100644 index 698db5a16a..0000000000 --- a/src/gallium/drivers/nv10/nv10_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_util.h" - -#include "nv10_context.h" - -void -nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp) -{ -} - -void -nv10_fragprog_destroy(struct nv10_context *nv10, - struct nv10_fragment_program *fp) -{ -} - diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c deleted file mode 100644 index c1f7ccb9ab..0000000000 --- a/src/gallium/drivers/nv10/nv10_fragtex.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "nv10_context.h" -#include "nouveau/nouveau_util.h" - -#define _(m,tf) \ -{ \ - TRUE, \ - PIPE_FORMAT_##m, \ - NV10TCL_TX_FORMAT_FORMAT_##tf, \ -} - -struct nv10_texture_format { - boolean defined; - uint pipe; - int format; -}; - -static struct nv10_texture_format -nv10_texture_formats[] = { - _(A8R8G8B8_UNORM, A8R8G8B8), - _(A1R5G5B5_UNORM, A1R5G5B5), - _(A4R4G4B4_UNORM, A4R4G4B4), - _(L8_UNORM , L8 ), - _(A8_UNORM , A8 ), - _(A8L8_UNORM , A8L8 ), -// _(RGB_DXT1 , DXT1, ), -// _(RGBA_DXT1 , DXT1, ), -// _(RGBA_DXT3 , DXT3, ), -// _(RGBA_DXT5 , DXT5, ), - {}, -}; - -static struct nv10_texture_format * -nv10_fragtex_format(uint pipe_format) -{ - struct nv10_texture_format *tf = nv10_texture_formats; - - while (tf->defined) { - if (tf->pipe == pipe_format) - return tf; - tf++; - } - - return NULL; -} - - -static void -nv10_fragtex_build(struct nv10_context *nv10, int unit) -{ -#if 0 - struct nv10_sampler_state *ps = nv10->tex_sampler[unit]; - struct nv10_miptree *nv10mt = nv10->tex_miptree[unit]; - struct pipe_texture *pt = &nv10mt->base; - struct nv10_texture_format *tf; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - uint32_t txf, txs, txp; - - tf = nv10_fragtex_format(pt->format); - if (!tf || !tf->defined) { - NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); - return; - } - - txf = tf->format << 8; - txf |= (pt->last_level + 1) << 16; - txf |= log2i(pt->width0) << 20; - txf |= log2i(pt->height0) << 24; - txf |= log2i(pt->depth0) << 28; - txf |= 8; - - switch (pt->target) { - case PIPE_TEXTURE_CUBE: - txf |= NV10TCL_TX_FORMAT_CUBE_MAP; - /* fall-through */ - case PIPE_TEXTURE_2D: - txf |= (2<<4); - break; - case PIPE_TEXTURE_1D: - txf |= (1<<4); - break; - default: - NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; - } - - BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(unit), 8); - OUT_RELOCl(chan, nouveau_bo(nv10mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, nouveau_bo(nv10mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING (chan, ps->wrap); - OUT_RING (chan, 0x40000000); /* enable */ - OUT_RING (chan, txs); - OUT_RING (chan, ps->filt | 0x2000 /* magic */); - OUT_RING (chan, (pt->width0 << 16) | pt->height0); - OUT_RING (chan, ps->bcol); -#endif -} - -void -nv10_fragtex_bind(struct nv10_context *nv10) -{ -#if 0 - struct nv10_fragment_program *fp = nv10->fragprog.active; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - unsigned samplers, unit; - - samplers = nv10->fp_samplers & ~fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(unit), 1); - OUT_RING (chan, 0); - } - - samplers = nv10->dirty_samplers & fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - nv10_fragtex_build(nv10, unit); - } - - nv10->fp_samplers = fp->samplers; -#endif -} - diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c deleted file mode 100644 index 908482ad85..0000000000 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" - -#include "nv10_context.h" -#include "nv10_screen.h" - -static void -nv10_miptree_layout(struct nv10_miptree *nv10mt) -{ - struct pipe_texture *pt = &nv10mt->base; - boolean swizzled = FALSE; - uint width = pt->width0; - uint offset = 0; - int nr_faces, l, f; - - if (pt->target == PIPE_TEXTURE_CUBE) { - nr_faces = 6; - } else { - nr_faces = 1; - } - - for (l = 0; l <= pt->last_level; l++) { - if (swizzled) - nv10mt->level[l].pitch = util_format_get_stride(pt->format, width); - else - nv10mt->level[l].pitch = util_format_get_stride(pt->format, pt->width0); - nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; - - nv10mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - - width = u_minify(width, 1); - - } - - for (f = 0; f < nr_faces; f++) { - for (l = 0; l <= pt->last_level; l++) { - nv10mt->level[l].image_offset[f] = offset; - offset += nv10mt->level[l].pitch * u_minify(pt->height0, l); - } - } - - nv10mt->total_size = offset; -} - -static struct pipe_texture * -nv10_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv10_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv10_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) -{ - struct nv10_miptree *mt; - - mt = MALLOC(sizeof(struct nv10_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = screen; - - nv10_miptree_layout(mt); - - mt->buffer = screen->buffer_create(screen, 256, PIPE_BUFFER_USAGE_PIXEL, - mt->total_size); - if (!mt->buffer) { - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - - return &mt->base; -} - -static void -nv10_miptree_destroy(struct pipe_texture *pt) -{ - struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; - int l; - - pipe_buffer_reference(&nv10mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (nv10mt->level[l].image_offset) - FREE(nv10mt->level[l].image_offset); - } - FREE(nv10mt); -} - -static void -nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - - -static struct pipe_surface * -nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv10mt->level[level].pitch; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ns->base.offset = nv10mt->level[level].image_offset[face]; - } else { - ns->base.offset = nv10mt->level[level].image_offset[0]; - } - - return &ns->base; -} - -static void -nv10_miptree_surface_destroy(struct pipe_surface *surface) -{ -} - -void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv10_miptree_create; - pscreen->texture_blanket = nv10_miptree_blanket; - pscreen->texture_destroy = nv10_miptree_destroy; - pscreen->get_tex_surface = nv10_miptree_surface_get; - pscreen->tex_surface_destroy = nv10_miptree_surface_destroy; -} - diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c deleted file mode 100644 index c5dbe43dbc..0000000000 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ /dev/null @@ -1,267 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * \file - * Build post-transformation, post-clipping vertex buffers and element - * lists by hooking into the end of the primitive pipeline and - * manipulating the vertex_id field in the vertex headers. - * - * XXX: work in progress - * - * \author José Fonseca <jrfonseca@tungstengraphics.com> - * \author Keith Whitwell <keith@tungstengraphics.com> - */ - - -#include "util/u_debug.h" -#include "pipe/p_inlines.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -#include "draw/draw_vbuf.h" - -/** - * Primitive renderer for nv10. - */ -struct nv10_vbuf_render { - struct vbuf_render base; - - struct nv10_context *nv10; - - /** Vertex buffer */ - struct pipe_buffer* buffer; - - /** Vertex size in bytes */ - unsigned vertex_size; - - /** Hardware primitive */ - unsigned hwprim; -}; - - -void nv10_vtxbuf_bind( struct nv10_context* nv10 ) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int i; - for(i = 0; i < 8; i++) { - BEGIN_RING(chan, celsius, NV10TCL_VTXBUF_ADDRESS(i), 1); - OUT_RING(chan, 0/*nv10->vtxbuf*/); - BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1); - OUT_RING(chan, 0/*XXX*/); - } -} - -/** - * Basically a cast wrapper. - */ -static INLINE struct nv10_vbuf_render * -nv10_vbuf_render( struct vbuf_render *render ) -{ - assert(render); - return (struct nv10_vbuf_render *)render; -} - - -static const struct vertex_info * -nv10_vbuf_render_get_vertex_info( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - - nv10_emit_hw_state(nv10); - - return &nv10->vertex_info; -} - -static boolean -nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, - ushort vertex_size, - ushort nr_vertices ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct pipe_screen *screen = nv10->pipe.screen; - size_t size = (size_t)vertex_size * (size_t)nr_vertices; - - assert(!nv10_render->buffer); - nv10_render->buffer = screen->buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, size); - - nv10->dirty |= NV10_NEW_VTXARRAYS; - - if (nv10_render->buffer) - return FALSE; - return TRUE; -} - -static void * -nv10_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct pipe_screen *pscreen = nv10->pipe.screen; - - return pipe_buffer_map(pscreen, nv10_render->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE); -} - -static void -nv10_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct pipe_screen *pscreen = nv10->pipe.screen; - - assert(!nv10_render->buffer); - pipe_buffer_unmap(pscreen, nv10_render->buffer); -} - -static boolean -nv10_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - unsigned hwp = nvgl_primitive(prim); - if (hwp == 0) - return FALSE; - - nv10_render->hwprim = hwp; - return TRUE; -} - - -static void -nv10_vbuf_render_draw( struct vbuf_render *render, - const ushort *indices, - uint nr_indices) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int push, i; - - nv10_emit_hw_state(nv10); - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); - OUT_RELOCl(chan, nouveau_bo(nv10_render->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING(chan, nv10_render->hwprim); - - if (nr_indices & 1) { - BEGIN_RING(chan, celsius, NV10TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, indices[0]); - indices++; nr_indices--; - } - - while (nr_indices) { - // XXX too big/small ? check the size - push = MIN2(nr_indices, 1200 * 2); - - BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING(chan, (indices[i+1] << 16) | indices[i]); - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING (chan, 0); -} - - -static void -nv10_vbuf_render_release_vertices( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - - assert(nv10_render->buffer); - pipe_buffer_reference(&nv10_render->buffer, NULL); -} - - -static void -nv10_vbuf_render_destroy( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - FREE(nv10_render); -} - - -/** - * Create a new primitive render. - */ -static struct vbuf_render * -nv10_vbuf_render_create( struct nv10_context *nv10 ) -{ - struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render); - - nv10_render->nv10 = nv10; - - nv10_render->base.max_vertex_buffer_bytes = 16*1024; - nv10_render->base.max_indices = 1024; - nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info; - nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices; - nv10_render->base.map_vertices = nv10_vbuf_render_map_vertices; - nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_vertices; - nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive; - nv10_render->base.draw = nv10_vbuf_render_draw; - nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices; - nv10_render->base.destroy = nv10_vbuf_render_destroy; - - return &nv10_render->base; -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ) -{ - struct vbuf_render *render; - struct draw_stage *stage; - - render = nv10_vbuf_render_create(nv10); - if(!render) - return NULL; - - stage = draw_vbuf_stage( nv10->draw, render ); - if(!stage) { - render->destroy(render); - return NULL; - } - - return stage; -} diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c deleted file mode 100644 index 69a6dab866..0000000000 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ /dev/null @@ -1,198 +0,0 @@ -#include "pipe/p_screen.h" - -#include "nv10_context.h" -#include "nv10_screen.h" - -static int -nv10_screen_get_param(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 2; - case PIPE_CAP_NPOT_TEXTURES: - return 0; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 0; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; - case PIPE_CAP_POINT_SPRITE: - return 0; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 0; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 12; - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 0; - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 12; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv10_screen_get_paramf(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 10.0; - case PIPE_CAP_MAX_POINT_WIDTH: - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 64.0; - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 2.0; - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 4.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - -static boolean -nv10_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -nv10_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv10_screen *screen = nv10_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->celsius); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv10_surface_buffer(struct pipe_surface *surf) -{ - struct nv10_miptree *mt = (struct nv10_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned celsius_class; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv10_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv10_screen_destroy; - pscreen->get_param = nv10_screen_get_param; - pscreen->get_paramf = nv10_screen_get_paramf; - pscreen->is_format_supported = nv10_screen_is_format_supported; - - nv10_screen_init_miptree_functions(pscreen); - nv10_screen_init_transfer_functions(pscreen); - - /* 3D object */ - if (dev->chipset >= 0x20) - celsius_class = NV11TCL; - else if (dev->chipset >= 0x17) - celsius_class = NV17TCL; - else if (dev->chipset >= 0x11) - celsius_class = NV11TCL; - else - celsius_class = NV10TCL; - - if (!celsius_class) { - NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset); - return NULL; - } - - ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class, - &screen->celsius); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv10_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv10_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h deleted file mode 100644 index 86b6d8def5..0000000000 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NV10_SCREEN_H__ -#define __NV10_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" - -struct nv10_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - struct nouveau_grobj *celsius; - struct nouveau_notifier *sync; -}; - -static INLINE struct nv10_screen * -nv10_screen(struct pipe_screen *screen) -{ - return (struct nv10_screen *)screen; -} - - -void -nv10_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h deleted file mode 100644 index 2524ac02e2..0000000000 --- a/src/gallium/drivers/nv10/nv10_state.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __NV10_STATE_H__ -#define __NV10_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/tgsi_scan.h" - -struct nv10_blend_state { - uint32_t b_enable; - uint32_t b_srcfunc; - uint32_t b_dstfunc; - - uint32_t c_mask; - - uint32_t d_enable; -}; - -struct nv10_sampler_state { - uint32_t wrap; - uint32_t en; - uint32_t filt; - uint32_t bcol; -}; - -struct nv10_rasterizer_state { - uint32_t shade_model; - - uint32_t line_width; - uint32_t line_smooth_en; - - uint32_t point_size; - - uint32_t poly_smooth_en; - - uint32_t poly_mode_front; - uint32_t poly_mode_back; - - uint32_t front_face; - uint32_t cull_face; - uint32_t cull_face_en; - - uint32_t point_sprite; - - const struct pipe_rasterizer_state *templ; -}; - -struct nv10_vertex_program_exec { - uint32_t data[4]; - boolean has_branch_offset; - int const_index; -}; - -struct nv10_vertex_program_data { - int index; /* immediates == -1 */ - float value[4]; -}; - -struct nv10_vertex_program { - const struct pipe_shader_state *pipe; - - boolean translated; - struct nv10_vertex_program_exec *insns; - unsigned nr_insns; - struct nv10_vertex_program_data *consts; - unsigned nr_consts; - - struct nouveau_resource *exec; - unsigned exec_start; - struct nouveau_resource *data; - unsigned data_start; - unsigned data_start_min; - - uint32_t ir; - uint32_t or; -}; - -struct nv10_fragment_program_data { - unsigned offset; - unsigned index; -}; - -struct nv10_fragment_program { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - - boolean translated; - boolean on_hw; - unsigned samplers; - - uint32_t *insn; - int insn_len; - - struct nv10_fragment_program_data *consts; - unsigned nr_consts; - - struct pipe_buffer *buffer; - - uint32_t fp_control; - uint32_t fp_reg_control; -}; - - -struct nv10_depth_stencil_alpha_state { - struct { - uint32_t func; - uint32_t write_enable; - uint32_t test_enable; - } depth; - - struct { - uint32_t enable; - uint32_t wmask; - uint32_t func; - uint32_t ref; - uint32_t vmask; - uint32_t fail; - uint32_t zfail; - uint32_t zpass; - } stencil; - - struct { - uint32_t enabled; - uint32_t func; - uint32_t ref; - } alpha; -}; - -struct nv10_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; - - struct pipe_buffer *buffer; - uint total_size; - - struct { - uint pitch; - uint *image_offset; - } level[PIPE_MAX_TEXTURE_LEVELS]; -}; - -#endif diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c deleted file mode 100644 index 30a596ca60..0000000000 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ /dev/null @@ -1,333 +0,0 @@ -#include "nv10_context.h" -#include "nv10_state.h" - -static void nv10_state_emit_blend(struct nv10_context* nv10) -{ - struct nv10_blend_state *b = nv10->blend; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1); - OUT_RING (chan, b->d_enable); - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); - OUT_RING (chan, b->b_enable); - OUT_RING (chan, b->b_srcfunc); - OUT_RING (chan, b->b_dstfunc); - - BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (chan, b->c_mask); -} - -static void nv10_state_emit_blend_color(struct nv10_context* nv10) -{ - struct pipe_blend_color *c = nv10->blend_color; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1); - OUT_RING (chan, - (float_to_ubyte(c->color[3]) << 24)| - (float_to_ubyte(c->color[0]) << 16)| - (float_to_ubyte(c->color[1]) << 8) | - (float_to_ubyte(c->color[2]) << 0)); -} - -static void nv10_state_emit_rast(struct nv10_context* nv10) -{ - struct nv10_rasterizer_state *r = nv10->rast; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 2); - OUT_RING (chan, r->shade_model); - OUT_RING (chan, r->line_width); - - - BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (chan, r->point_size); - - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, r->poly_mode_front); - OUT_RING (chan, r->poly_mode_back); - - - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (chan, r->cull_face); - OUT_RING (chan, r->front_face); - - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (chan, r->line_smooth_en); - OUT_RING (chan, r->poly_smooth_en); - - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, r->cull_face_en); -} - -static void nv10_state_emit_dsa(struct nv10_context* nv10) -{ - struct nv10_depth_stencil_alpha_state *d = nv10->dsa; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); - OUT_RING (chan, d->depth.func); - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, d->depth.write_enable); - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, d->depth.test_enable); - -#if 0 - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1); - OUT_RING (chan, d->stencil.enable); - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 7); - OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7); -#endif - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, d->alpha.enabled); - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 1); - OUT_RING (chan, d->alpha.func); - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_REF, 1); - OUT_RING (chan, d->alpha.ref); -} - -static void nv10_state_emit_viewport(struct nv10_context* nv10) -{ -} - -static void nv10_state_emit_scissor(struct nv10_context* nv10) -{ - // XXX this is so not working -/* struct pipe_scissor_state *s = nv10->scissor; - BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); - OUT_RING (((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ -} - -static void nv10_state_emit_framebuffer(struct nv10_context* nv10) -{ - struct pipe_framebuffer_state* fb = nv10->framebuffer; - struct nv04_surface *rt, *zeta = NULL; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv10_miptree *nv10mt = 0; - - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)fb->cbufs[0]; - - if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - - zeta_format = fb->zsbuf->format; - zeta = (struct nv04_surface *)fb->zsbuf; - } - - rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; - - switch (colour_format) { - case PIPE_FORMAT_X8R8G8B8_UNORM: - rt_format |= NV10TCL_RT_FORMAT_COLOR_X8R8G8B8; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5; - break; - default: - assert(0); - } - - if (zeta) { - BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (zeta->pitch << 16)); - } else { - BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (rt->pitch << 16)); - } - - nv10mt = (struct nv10_miptree *)rt->base.texture; - nv10->rt[0] = nv10mt->buffer; - - if (zeta_format) - { - nv10mt = (struct nv10_miptree *)zeta->base.texture; - nv10->zeta = nv10mt->buffer; - } - - BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 3); - OUT_RING (chan, (w << 16) | 0); - OUT_RING (chan, (h << 16) | 0); - OUT_RING (chan, rt_format); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (chan, ((w - 1) << 16) | 0 | 0x08000800); - OUT_RING (chan, ((h - 1) << 16) | 0 | 0x08000800); -} - -static void nv10_vertex_layout(struct nv10_context *nv10) -{ - struct nv10_fragment_program *fp = nv10->fragprog.current; - uint32_t src = 0; - int i; - struct vertex_info vinfo; - - memset(&vinfo, 0, sizeof(vinfo)); - - for (i = 0; i < fp->info.num_inputs; i++) { - switch (fp->info.input_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); - break; - case TGSI_SEMANTIC_COLOR: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); - break; - default: - case TGSI_SEMANTIC_GENERIC: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); - break; - case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); - break; - } - } - draw_compute_vertex_size(&vinfo); -} - -void -nv10_emit_hw_state(struct nv10_context *nv10) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - struct nouveau_bo *rt_bo; - int i; - - if (nv10->dirty & NV10_NEW_VERTPROG) { - //nv10_vertprog_bind(nv10, nv10->vertprog.current); - nv10->dirty &= ~NV10_NEW_VERTPROG; - } - - if (nv10->dirty & NV10_NEW_FRAGPROG) { - nv10_fragprog_bind(nv10, nv10->fragprog.current); - /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ - nv10->dirty_samplers |= (1<<10); - nv10->dirty_samplers = 0; - } - - if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { - nv10_fragtex_bind(nv10); - nv10->dirty &= ~NV10_NEW_FRAGPROG; - } - - if (nv10->dirty & NV10_NEW_VTXARRAYS) { - nv10->dirty &= ~NV10_NEW_VTXARRAYS; - nv10_vertex_layout(nv10); - nv10_vtxbuf_bind(nv10); - } - - if (nv10->dirty & NV10_NEW_BLEND) { - nv10->dirty &= ~NV10_NEW_BLEND; - nv10_state_emit_blend(nv10); - } - - if (nv10->dirty & NV10_NEW_BLENDCOL) { - nv10->dirty &= ~NV10_NEW_BLENDCOL; - nv10_state_emit_blend_color(nv10); - } - - if (nv10->dirty & NV10_NEW_RAST) { - nv10->dirty &= ~NV10_NEW_RAST; - nv10_state_emit_rast(nv10); - } - - if (nv10->dirty & NV10_NEW_DSA) { - nv10->dirty &= ~NV10_NEW_DSA; - nv10_state_emit_dsa(nv10); - } - - if (nv10->dirty & NV10_NEW_VIEWPORT) { - nv10->dirty &= ~NV10_NEW_VIEWPORT; - nv10_state_emit_viewport(nv10); - } - - if (nv10->dirty & NV10_NEW_SCISSOR) { - nv10->dirty &= ~NV10_NEW_SCISSOR; - nv10_state_emit_scissor(nv10); - } - - if (nv10->dirty & NV10_NEW_FRAMEBUFFER) { - nv10->dirty &= ~NV10_NEW_FRAMEBUFFER; - nv10_state_emit_framebuffer(nv10); - } - - /* Emit relocs for every referenced buffer. - * This is to ensure the bufmgr has an accurate idea of how - * the buffer is used. This isn't very efficient, but we don't - * seem to take a significant performance hit. Will be improved - * at some point. Vertex arrays are emitted by nv10_vbo.c - */ - - /* Render target */ - rt_bo = nouveau_bo(nv10->rt[0]); -// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly -// BEGIN_RING(chan, celsius, NV10TCL_DMA_COLOR0, 1); -// OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - if (nv10->zeta) { - struct nouveau_bo *zeta_bo = nouveau_bo(nv10->zeta); -// XXX -// BEGIN_RING(chan, celsius, NV10TCL_DMA_ZETA, 1); -// OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_ZETA_OFFSET, 1); - OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - /* XXX for when we allocate LMA on nv17 */ -/* BEGIN_RING(chan, celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); - OUT_RELOCl(chan, nouveau_bo(nv10->zeta + lma_offset));*/ - } - - /* Vertex buffer */ - BEGIN_RING(chan, celsius, NV10TCL_DMA_VTXBUF0, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - /* Texture images */ - for (i = 0; i < 2; i++) { - if (!(nv10->fp_samplers & (1 << i))) - continue; - struct nouveau_bo *bo = nouveau_bo(nv10->tex[i].buffer); - BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(i), 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(i), 1); - OUT_RELOCd(chan, bo, nv10->tex[i].format, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | - NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0, - NV10TCL_TX_FORMAT_DMA1); - } -} - diff --git a/src/gallium/drivers/nv10/nv10_surface.c b/src/gallium/drivers/nv10/nv10_surface.c deleted file mode 100644 index 5b52246a9c..0000000000 --- a/src/gallium/drivers/nv10/nv10_surface.c +++ /dev/null @@ -1,63 +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 "nv10_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" -#include "util/u_tile.h" - -static void -nv10_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - struct nv10_context *nv10 = nv10_context(pipe); - struct nv04_surface_2d *eng2d = nv10->screen->eng2d; - - eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); -} - -static void -nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) -{ - struct nv10_context *nv10 = nv10_context(pipe); - struct nv04_surface_2d *eng2d = nv10->screen->eng2d; - - eng2d->fill(eng2d, dest, destx, desty, width, height, value); -} - -void -nv10_init_surface_functions(struct nv10_context *nv10) -{ - nv10->pipe.surface_copy = nv10_surface_copy; - nv10->pipe.surface_fill = nv10_surface_fill; -} diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c deleted file mode 100644 index eb04af9782..0000000000 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <pipe/p_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv10_context.h" -#include "nv10_screen.h" -#include "nv10_state.h" - -struct nv10_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv10_miptree *mt = (struct nv10_miptree *)pt; - struct nv10_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv10_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv10_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv10_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv10_screen *nvscreen = nv10_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv10_transfer_del(struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - - if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv10_screen *nvscreen = nv10_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv10_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv10_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv10_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv10_transfer_new; - pscreen->tex_transfer_destroy = nv10_transfer_del; - pscreen->transfer_map = nv10_transfer_map; - pscreen->transfer_unmap = nv10_transfer_unmap; -} diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c deleted file mode 100644 index 9180c72c9b..0000000000 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_inlines.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void nv10_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) -{ - struct nv10_context *nv10 = nv10_context( pipe ); - struct draw_context *draw = nv10->draw; - struct pipe_screen *pscreen = pipe->screen; - unsigned i; - - nv10_emit_hw_state(nv10); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv10->vtxbuf[i].buffer) { - void *buf = - pipe_buffer_map(pscreen, nv10->vtxbuf[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_vertex_buffer(draw, i, buf); - } - } - /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes - = pipe_buffer_map(pscreen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, NULL); - } - - draw_set_mapped_constant_buffer(draw, - PIPE_SHADER_VERTEX, - nv10->constbuf[PIPE_SHADER_VERTEX], - nv10->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv10->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv10->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv10->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } -} - -void nv10_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - nv10_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv20/Makefile b/src/gallium/drivers/nv20/Makefile deleted file mode 100644 index 1305f26c59..0000000000 --- a/src/gallium/drivers/nv20/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv20 - -C_SOURCES = \ - nv20_clear.c \ - nv20_context.c \ - nv20_fragprog.c \ - nv20_fragtex.c \ - nv20_miptree.c \ - nv20_prim_vbuf.c \ - nv20_screen.c \ - nv20_state.c \ - nv20_state_emit.c \ - nv20_surface.c \ - nv20_transfer.c \ - nv20_vbo.c -# nv20_vertprog.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c deleted file mode 100644 index 2b4490fa5e..0000000000 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "util/u_clear.h" - -#include "nv20_context.h" - -void -nv20_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil) -{ - util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth, - stencil); -} diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h deleted file mode 100644 index c7dfadaa31..0000000000 --- a/src/gallium/drivers/nv20/nv20_context.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __NV20_CONTEXT_H__ -#define __NV20_CONTEXT_H__ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.h" - -#include "nv20_state.h" - -#define NOUVEAU_ERR(fmt, args...) \ - fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); -#define NOUVEAU_MSG(fmt, args...) \ - fprintf(stderr, "nouveau: "fmt, ##args); - -#define NV20_NEW_VERTPROG (1 << 0) -#define NV20_NEW_FRAGPROG (1 << 1) -#define NV20_NEW_VTXARRAYS (1 << 2) -#define NV20_NEW_BLEND (1 << 3) -#define NV20_NEW_BLENDCOL (1 << 4) -#define NV20_NEW_RAST (1 << 5) -#define NV20_NEW_DSA (1 << 6) -#define NV20_NEW_VIEWPORT (1 << 7) -#define NV20_NEW_SCISSOR (1 << 8) -#define NV20_NEW_FRAMEBUFFER (1 << 9) - -#include "nv20_screen.h" - -struct nv20_context { - struct pipe_context pipe; - - struct nouveau_winsys *nvws; - struct nv20_screen *screen; - unsigned pctx_id; - - struct draw_context *draw; - - uint32_t dirty; - - struct nv20_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; - struct nv20_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; - unsigned dirty_samplers; - unsigned fp_samplers; - unsigned vp_samplers; - - uint32_t rt_enable; - struct pipe_buffer *rt[4]; - struct pipe_buffer *zeta; - uint32_t lma_offset; - - struct nv20_blend_state *blend; - struct pipe_blend_color *blend_color; - struct nv20_rasterizer_state *rast; - struct nv20_depth_stencil_alpha_state *dsa; - struct pipe_viewport_state *viewport; - struct pipe_scissor_state *scissor; - struct pipe_framebuffer_state *framebuffer; - - //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - struct vertex_info vertex_info; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[2]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - -/* struct { - - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - - struct nv20_vertex_program *active; - - struct nv20_vertex_program *current; - } vertprog; -*/ - struct { - struct nv20_fragment_program *active; - - struct nv20_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; -}; - -static INLINE struct nv20_context * -nv20_context(struct pipe_context *pipe) -{ - return (struct nv20_context *)pipe; -} - -extern void nv20_init_state_functions(struct nv20_context *nv20); -extern void nv20_init_surface_functions(struct nv20_context *nv20); - -extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); - -/* nv20_clear.c */ -extern void nv20_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); - -/* nv20_draw.c */ -extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); - -/* nv20_fragprog.c */ -extern void nv20_fragprog_bind(struct nv20_context *, - struct nv20_fragment_program *); -extern void nv20_fragprog_destroy(struct nv20_context *, - struct nv20_fragment_program *); - -/* nv20_fragtex.c */ -extern void nv20_fragtex_bind(struct nv20_context *); - -/* nv20_prim_vbuf.c */ -struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ); -extern void nv20_vtxbuf_bind(struct nv20_context* nv20); - -/* nv20_state.c and friends */ -extern void nv20_emit_hw_state(struct nv20_context *nv20); -extern void nv20_state_tex_update(struct nv20_context *nv20); - -/* nv20_vbo.c */ -extern void nv20_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv20_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count); - - -#endif diff --git a/src/gallium/drivers/nv20/nv20_fragprog.c b/src/gallium/drivers/nv20/nv20_fragprog.c deleted file mode 100644 index 4f496369dd..0000000000 --- a/src/gallium/drivers/nv20/nv20_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_util.h" - -#include "nv20_context.h" - -void -nv20_fragprog_bind(struct nv20_context *nv20, struct nv20_fragment_program *fp) -{ -} - -void -nv20_fragprog_destroy(struct nv20_context *nv20, - struct nv20_fragment_program *fp) -{ -} - diff --git a/src/gallium/drivers/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c deleted file mode 100644 index dedbec73f3..0000000000 --- a/src/gallium/drivers/nv20/nv20_fragtex.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "nv20_context.h" -#include "nouveau/nouveau_util.h" - -#define _(m,tf) \ -{ \ - TRUE, \ - PIPE_FORMAT_##m, \ - NV20TCL_TX_FORMAT_FORMAT_##tf, \ -} - -struct nv20_texture_format { - boolean defined; - uint pipe; - int format; -}; - -static struct nv20_texture_format -nv20_texture_formats[] = { - _(A8R8G8B8_UNORM, A8R8G8B8), - _(A1R5G5B5_UNORM, A1R5G5B5), - _(A4R4G4B4_UNORM, A4R4G4B4), - _(L8_UNORM , L8 ), - _(A8_UNORM , A8 ), - _(A8L8_UNORM , A8L8 ), -/* _(RGB_DXT1 , DXT1, ), */ -/* _(RGBA_DXT1 , DXT1, ), */ -/* _(RGBA_DXT3 , DXT3, ), */ -/* _(RGBA_DXT5 , DXT5, ), */ - {}, -}; - -static struct nv20_texture_format * -nv20_fragtex_format(uint pipe_format) -{ - struct nv20_texture_format *tf = nv20_texture_formats; - - while (tf->defined) { - if (tf->pipe == pipe_format) - return tf; - tf++; - } - - return NULL; -} - - -static void -nv20_fragtex_build(struct nv20_context *nv20, int unit) -{ -#if 0 - struct nv20_sampler_state *ps = nv20->tex_sampler[unit]; - struct nv20_miptree *nv20mt = nv20->tex_miptree[unit]; - struct pipe_texture *pt = &nv20mt->base; - struct nv20_texture_format *tf; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - uint32_t txf, txs, txp; - - tf = nv20_fragtex_format(pt->format); - if (!tf || !tf->defined) { - NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); - return; - } - - txf = tf->format << 8; - txf |= (pt->last_level + 1) << 16; - txf |= log2i(pt->width0) << 20; - txf |= log2i(pt->height0) << 24; - txf |= log2i(pt->depth0) << 28; - txf |= 8; - - switch (pt->target) { - case PIPE_TEXTURE_CUBE: - txf |= NV10TCL_TX_FORMAT_CUBE_MAP; - /* fall-through */ - case PIPE_TEXTURE_2D: - txf |= (2<<4); - break; - case PIPE_TEXTURE_1D: - txf |= (1<<4); - break; - default: - NOUVEAU_ERR("Unknown target %d\n", pt->target); - return; - } - - BEGIN_RING(chan, kelvin, NV10TCL_TX_OFFSET(unit), 8); - OUT_RELOCl(chan, nouveau_bo(nv20mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, nouveau_bo(nv20mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING (chan, ps->wrap); - OUT_RING (chan, 0x40000000); /* enable */ - OUT_RING (chan, txs); - OUT_RING (chan, ps->filt | 0x2000 /* magic */); - OUT_RING (chan, (pt->width0 << 16) | pt->height0); - OUT_RING (chan, ps->bcol); -#endif -} - -void -nv20_fragtex_bind(struct nv20_context *nv20) -{ -#if 0 - struct nv20_fragment_program *fp = nv20->fragprog.active; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - unsigned samplers, unit; - - samplers = nv20->fp_samplers & ~fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - BEGIN_RING(chan, kelvin, NV10TCL_TX_ENABLE(unit), 1); - OUT_RING (chan, 0); - } - - samplers = nv20->dirty_samplers & fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - nv20_fragtex_build(nv20, unit); - } - - nv20->fp_samplers = fp->samplers; -#endif -} - diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c deleted file mode 100644 index 8f7538e7f5..0000000000 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ /dev/null @@ -1,226 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" - -#include "nv20_context.h" -#include "nv20_screen.h" -#include "../nv04/nv04_surface_2d.h" - -static void -nv20_miptree_layout(struct nv20_miptree *nv20mt) -{ - struct pipe_texture *pt = &nv20mt->base; - uint width = pt->width0; - uint offset = 0; - int nr_faces, l, f; - uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY); - - if (pt->target == PIPE_TEXTURE_CUBE) { - nr_faces = 6; - } else { - nr_faces = 1; - } - - for (l = 0; l <= pt->last_level; l++) { - if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) - nv20mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64); - else - nv20mt->level[l].pitch = util_format_get_stride(pt->format, width); - - nv20mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - - width = u_minify(width, 1); - } - - for (f = 0; f < nr_faces; f++) { - for (l = 0; l < pt->last_level; l++) { - nv20mt->level[l].image_offset[f] = offset; - - if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && - u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) - offset += align(nv20mt->level[l].pitch * u_minify(pt->height0, l), 64); - else - offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv20mt->level[l].image_offset[f] = offset; - offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv20mt->total_size = offset; -} - -static struct pipe_texture * -nv20_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv20_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv20_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) -{ - struct nv20_miptree *mt; - unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE; - - mt = MALLOC(sizeof(struct nv20_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = screen; - - /* Swizzled textures must be POT */ - if (pt->width0 & (pt->width0 - 1) || - pt->height0 & (pt->height0 - 1)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else - if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else { - switch (pt->format) { - /* TODO: Figure out which formats can be swizzled */ - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_R16_SNORM: - { - if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - break; - } - default: - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - } - } - - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - - /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear. - * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy. - * This also happens for small mipmaps of large textures. */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - - nv20_miptree_layout(mt); - - mt->buffer = screen->buffer_create(screen, 256, buf_usage, mt->total_size); - if (!mt->buffer) { - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - - return &mt->base; -} - -static void -nv20_miptree_destroy(struct pipe_texture *pt) -{ - struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt; - int l; - - pipe_buffer_reference(&nv20mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (nv20mt->level[l].image_offset) - FREE(nv20mt->level[l].image_offset); - } -} - -static struct pipe_surface * -nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv20mt->level[level].pitch; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ns->base.offset = nv20mt->level[level].image_offset[face]; - } else - if (pt->target == PIPE_TEXTURE_3D) { - ns->base.offset = nv20mt->level[level].image_offset[zslice]; - } else { - ns->base.offset = nv20mt->level[level].image_offset[0]; - } - - /* create a linear temporary that we can render into if necessary. - * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so - * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/ - if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE) - return &nv04_surface_wrap_for_render(screen, ((struct nv20_screen*)screen)->eng2d, ns)->base; - - return &ns->base; -} - -static void -nv20_miptree_surface_destroy(struct pipe_surface *ps) -{ - struct nv04_surface* ns = (struct nv04_surface*)ps; - if(ns->backing) - { - struct nv20_screen* screen = (struct nv20_screen*)ps->texture->screen; - if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE) - screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); - nv20_miptree_surface_destroy(&ns->backing->base); - } - - pipe_texture_reference(&ps->texture, NULL); - FREE(ps); -} - -void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv20_miptree_create; - pscreen->texture_blanket = nv20_miptree_blanket; - pscreen->texture_destroy = nv20_miptree_destroy; - pscreen->get_tex_surface = nv20_miptree_surface_get; - pscreen->tex_surface_destroy = nv20_miptree_surface_destroy; -} - diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c deleted file mode 100644 index 2e145672da..0000000000 --- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c +++ /dev/null @@ -1,440 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * \file - * Build post-transformation, post-clipping vertex buffers and element - * lists by hooking into the end of the primitive pipeline and - * manipulating the vertex_id field in the vertex headers. - * - * XXX: work in progress - * - * \author José Fonseca <jrfonseca@tungstengraphics.com> - * \author Keith Whitwell <keith@tungstengraphics.com> - */ - - -#include "util/u_debug.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -#include "draw/draw_vbuf.h" - -/** - * Primitive renderer for nv20. - */ -struct nv20_vbuf_render { - struct vbuf_render base; - - struct nv20_context *nv20; - - /** Vertex buffer in VRAM */ - struct pipe_buffer *pbuffer; - - /** Vertex buffer in normal memory */ - void *mbuffer; - - /** Vertex size in bytes */ - /*unsigned vertex_size;*/ - - /** Hardware primitive */ - unsigned hwprim; -}; - -/** - * Basically a cast wrapper. - */ -static INLINE struct nv20_vbuf_render * -nv20_vbuf_render(struct vbuf_render *render) -{ - assert(render); - return (struct nv20_vbuf_render *)render; -} - -void nv20_vtxbuf_bind( struct nv20_context* nv20 ) -{ -#if 0 - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - int i; - for(i = 0; i < NV20TCL_VTXBUF_ADDRESS__SIZE; i++) { - BEGIN_RING(chan, kelvin, NV20TCL_VTXBUF_ADDRESS(i), 1); - OUT_RING(chan, 0/*nv20->vtxbuf*/); - BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i) ,1); - OUT_RING(chan, 0/*XXX*/); - } -#endif -} - -static const struct vertex_info * -nv20_vbuf_render_get_vertex_info( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct nv20_context *nv20 = nv20_render->nv20; - - nv20_emit_hw_state(nv20); - - return &nv20->vertex_info; -} - -static void * -nv20__allocate_mbuffer(struct nv20_vbuf_render *nv20_render, size_t size) -{ - nv20_render->mbuffer = MALLOC(size); - return nv20_render->mbuffer; -} - -static void -nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size) -{ - struct pipe_screen *screen = nv20_render->nv20->pipe.screen; - nv20_render->pbuffer = screen->buffer_create(screen, 64, - PIPE_BUFFER_USAGE_VERTEX, size); -} - -static boolean -nv20_vbuf_render_allocate_vertices( struct vbuf_render *render, - ushort vertex_size, - ushort nr_vertices ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - size_t size = (size_t)vertex_size * (size_t)nr_vertices; - void *buf; - - assert(!nv20_render->pbuffer); - assert(!nv20_render->mbuffer); - - /* - * For small amount of vertices, don't bother with pipe vertex - * buffer, the data will be passed directly via the fifo. - */ - /* XXX: Pipe vertex buffers don't work. */ - if (0 && size > 16 * 1024) { - nv20__allocate_pbuffer(nv20_render, size); - /* umm yeah so this is ugly */ - buf = nv20_render->pbuffer; - } else { - buf = nv20__allocate_mbuffer(nv20_render, size); - } - - if (buf) - nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS; - - return buf ? TRUE : FALSE; -} - -static void * -nv20_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen; - - if (nv20_render->pbuffer) { - return pipe_buffer_map(pscreen, nv20_render->pbuffer, - PIPE_BUFFER_USAGE_CPU_WRITE); - } else if (nv20_render->mbuffer) { - return nv20_render->mbuffer; - } else - assert(0); - - /* warnings be gone */ - return NULL; -} - -static void -nv20_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen; - - if (nv20_render->pbuffer) - pipe_buffer_unmap(pscreen, nv20_render->pbuffer); -} - -static boolean -nv20_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - unsigned hwp = nvgl_primitive(prim); - if (hwp == 0) - return FALSE; - - nv20_render->hwprim = hwp; - return TRUE; -} - -static uint32_t -nv20__vtxhwformat(unsigned stride, unsigned fields, unsigned type) -{ - return (stride << NV20TCL_VTXFMT_STRIDE_SHIFT) | - (fields << NV20TCL_VTXFMT_SIZE_SHIFT) | - (type << NV20TCL_VTXFMT_TYPE_SHIFT); -} - -static unsigned -nv20__emit_format(struct nv20_context *nv20, enum attrib_emit type, int hwattr) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - uint32_t hwfmt = 0; - unsigned fields; - - switch (type) { - case EMIT_OMIT: - hwfmt = nv20__vtxhwformat(0, 0, 2); - fields = 0; - break; - case EMIT_1F: - hwfmt = nv20__vtxhwformat(4, 1, 2); - fields = 1; - break; - case EMIT_2F: - hwfmt = nv20__vtxhwformat(8, 2, 2); - fields = 2; - break; - case EMIT_3F: - hwfmt = nv20__vtxhwformat(12, 3, 2); - fields = 3; - break; - case EMIT_4F: - hwfmt = nv20__vtxhwformat(16, 4, 2); - fields = 4; - break; - default: - NOUVEAU_ERR("unhandled attrib_emit %d\n", type); - return 0; - } - - BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(hwattr), 1); - OUT_RING(chan, hwfmt); - return fields; -} - -static unsigned -nv20__emit_vertex_array_format(struct nv20_context *nv20) -{ - struct vertex_info *vinfo = &nv20->vertex_info; - int hwattr = NV20TCL_VTXFMT__SIZE; - int attr = 0; - unsigned nr_fields = 0; - - while (hwattr-- > 0) { - if (vinfo->hwfmt[0] & (1 << hwattr)) { - nr_fields += nv20__emit_format(nv20, - vinfo->attrib[attr].emit, hwattr); - attr++; - } else - nv20__emit_format(nv20, EMIT_OMIT, hwattr); - } - - return nr_fields; -} - -static void -nv20__draw_mbuffer(struct nv20_vbuf_render *nv20_render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_context *nv20 = nv20_render->nv20; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - struct vertex_info *vinfo = &nv20->vertex_info; - unsigned nr_fields; - int max_push; - ubyte *data = nv20_render->mbuffer; - int vsz = 4 * vinfo->size; - - nr_fields = nv20__emit_vertex_array_format(nv20); - - BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); - OUT_RING(chan, nv20_render->hwprim); - - max_push = 1200 / nr_fields; - while (nr_indices) { - int i; - int push = MIN2(nr_indices, max_push); - - BEGIN_RING_NI(chan, kelvin, NV20TCL_VERTEX_DATA, push * nr_fields); - for (i = 0; i < push; i++) { - /* XXX: fixme to handle other than floats? */ - int f = nr_fields; - float *attrv = (float*)&data[indices[i] * vsz]; - while (f-- > 0) - OUT_RINGf(chan, *attrv++); - } - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); - OUT_RING(chan, NV20TCL_VERTEX_BEGIN_END_STOP); -} - -static void -nv20__draw_pbuffer(struct nv20_vbuf_render *nv20_render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_context *nv20 = nv20_render->nv20; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - int push, i; - - NOUVEAU_ERR("nv20__draw_pbuffer: this path is broken.\n"); - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); - OUT_RELOCl(chan, nouveau_bo(nv20_render->pbuffer), 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING(chan, nv20_render->hwprim); - - if (nr_indices & 1) { - BEGIN_RING(chan, kelvin, NV10TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, indices[0]); - indices++; nr_indices--; - } - - while (nr_indices) { - // XXX too big/small ? check the size - push = MIN2(nr_indices, 1200 * 2); - - BEGIN_RING_NI(chan, kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING(chan, (indices[i+1] << 16) | indices[i]); - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING (chan, 0); -} - -static void -nv20_vbuf_render_draw( struct vbuf_render *render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - - nv20_emit_hw_state(nv20_render->nv20); - - if (nv20_render->pbuffer) - nv20__draw_pbuffer(nv20_render, indices, nr_indices); - else if (nv20_render->mbuffer) - nv20__draw_mbuffer(nv20_render, indices, nr_indices); - else - assert(0); -} - - -static void -nv20_vbuf_render_release_vertices( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct nv20_context *nv20 = nv20_render->nv20; - - if (nv20_render->pbuffer) { - pipe_buffer_reference(&nv20_render->pbuffer, NULL); - } else if (nv20_render->mbuffer) { - FREE(nv20_render->mbuffer); - nv20_render->mbuffer = NULL; - } else - assert(0); -} - - -static void -nv20_vbuf_render_destroy( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - - assert(!nv20_render->pbuffer); - assert(!nv20_render->mbuffer); - - FREE(nv20_render); -} - - -/** - * Create a new primitive render. - */ -static struct vbuf_render * -nv20_vbuf_render_create( struct nv20_context *nv20 ) -{ - struct nv20_vbuf_render *nv20_render = CALLOC_STRUCT(nv20_vbuf_render); - - nv20_render->nv20 = nv20; - - nv20_render->base.max_vertex_buffer_bytes = 16*1024; - nv20_render->base.max_indices = 1024; - nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info; - nv20_render->base.allocate_vertices = - nv20_vbuf_render_allocate_vertices; - nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices; - nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices; - nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive; - nv20_render->base.draw = nv20_vbuf_render_draw; - nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices; - nv20_render->base.destroy = nv20_vbuf_render_destroy; - - return &nv20_render->base; -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ) -{ - struct vbuf_render *render; - struct draw_stage *stage; - - render = nv20_vbuf_render_create(nv20); - if(!render) - return NULL; - - stage = draw_vbuf_stage( nv20->draw, render ); - if(!stage) { - render->destroy(render); - return NULL; - } - - return stage; -} diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c deleted file mode 100644 index d091335063..0000000000 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "pipe/p_screen.h" - -#include "nv20_context.h" -#include "nv20_screen.h" - -static int -nv20_screen_get_param(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 2; - case PIPE_CAP_NPOT_TEXTURES: - return 0; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 0; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; - case PIPE_CAP_POINT_SPRITE: - return 0; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 0; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 12; - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 0; - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 12; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv20_screen_get_paramf(struct pipe_screen *screen, int param) -{ - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 10.0; - case PIPE_CAP_MAX_POINT_WIDTH: - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 64.0; - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 2.0; - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 4.0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - -static boolean -nv20_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -nv20_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv20_screen *screen = nv20_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->kelvin); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv20_surface_buffer(struct pipe_surface *surf) -{ - struct nv20_miptree *mt = (struct nv20_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned kelvin_class = 0; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv20_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv20_screen_destroy; - pscreen->get_param = nv20_screen_get_param; - pscreen->get_paramf = nv20_screen_get_paramf; - pscreen->is_format_supported = nv20_screen_is_format_supported; - - nv20_screen_init_miptree_functions(pscreen); - nv20_screen_init_transfer_functions(pscreen); - - /* 3D object */ - if (dev->chipset >= 0x25) - kelvin_class = NV25TCL; - else if (dev->chipset >= 0x20) - kelvin_class = NV20TCL; - - if (!kelvin_class || dev->chipset >= 0x30) { - NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", dev->chipset); - return NULL; - } - - ret = nouveau_grobj_alloc(chan, 0xbeef0097, kelvin_class, - &screen->kelvin); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv20_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv20_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv20/nv20_screen.h b/src/gallium/drivers/nv20/nv20_screen.h deleted file mode 100644 index fc7bb05033..0000000000 --- a/src/gallium/drivers/nv20/nv20_screen.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NV20_SCREEN_H__ -#define __NV20_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" - -struct nv20_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - struct nouveau_grobj *kelvin; - struct nouveau_notifier *sync; -}; - -static INLINE struct nv20_screen * -nv20_screen(struct pipe_screen *screen) -{ - return (struct nv20_screen *)screen; -} - - -void -nv20_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv20/nv20_state.h b/src/gallium/drivers/nv20/nv20_state.h deleted file mode 100644 index dde4106568..0000000000 --- a/src/gallium/drivers/nv20/nv20_state.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __NV20_STATE_H__ -#define __NV20_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/tgsi_scan.h" - -struct nv20_blend_state { - uint32_t b_enable; - uint32_t b_srcfunc; - uint32_t b_dstfunc; - - uint32_t c_mask; - - uint32_t d_enable; -}; - -struct nv20_sampler_state { - uint32_t wrap; - uint32_t en; - uint32_t filt; - uint32_t bcol; -}; - -struct nv20_rasterizer_state { - uint32_t shade_model; - - uint32_t line_width; - uint32_t line_smooth_en; - - uint32_t point_size; - - uint32_t poly_smooth_en; - - uint32_t poly_mode_front; - uint32_t poly_mode_back; - - uint32_t front_face; - uint32_t cull_face; - uint32_t cull_face_en; - - uint32_t point_sprite; - - const struct pipe_rasterizer_state *templ; -}; - -struct nv20_vertex_program_exec { - uint32_t data[4]; - boolean has_branch_offset; - int const_index; -}; - -struct nv20_vertex_program_data { - int index; /* immediates == -1 */ - float value[4]; -}; - -struct nv20_vertex_program { - const struct pipe_shader_state *pipe; - - boolean translated; - struct nv20_vertex_program_exec *insns; - unsigned nr_insns; - struct nv20_vertex_program_data *consts; - unsigned nr_consts; - - struct nouveau_resource *exec; - unsigned exec_start; - struct nouveau_resource *data; - unsigned data_start; - unsigned data_start_min; - - uint32_t ir; - uint32_t or; -}; - -struct nv20_fragment_program_data { - unsigned offset; - unsigned index; -}; - -struct nv20_fragment_program { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - - boolean translated; - boolean on_hw; - unsigned samplers; - - uint32_t *insn; - int insn_len; - - struct nv20_fragment_program_data *consts; - unsigned nr_consts; - - struct pipe_buffer *buffer; - - uint32_t fp_control; - uint32_t fp_reg_control; -}; - - -struct nv20_depth_stencil_alpha_state { - struct { - uint32_t func; - uint32_t write_enable; - uint32_t test_enable; - } depth; - - struct { - uint32_t enable; - uint32_t wmask; - uint32_t func; - uint32_t ref; - uint32_t vmask; - uint32_t fail; - uint32_t zfail; - uint32_t zpass; - } stencil; - - struct { - uint32_t enabled; - uint32_t func; - uint32_t ref; - } alpha; -}; - -struct nv20_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; - - struct pipe_buffer *buffer; - uint total_size; - - struct { - uint pitch; - uint *image_offset; - } level[PIPE_MAX_TEXTURE_LEVELS]; -}; - -#endif diff --git a/src/gallium/drivers/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c deleted file mode 100644 index 6bbd1fdae9..0000000000 --- a/src/gallium/drivers/nv20/nv20_state_emit.c +++ /dev/null @@ -1,426 +0,0 @@ -#include "nv20_context.h" -#include "nv20_state.h" -#include "draw/draw_context.h" - -static void nv20_state_emit_blend(struct nv20_context* nv20) -{ - struct nv20_blend_state *b = nv20->blend; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1); - OUT_RING (chan, b->d_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1); - OUT_RING (chan, b->b_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 2); - OUT_RING (chan, b->b_srcfunc); - OUT_RING (chan, b->b_dstfunc); - - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1); - OUT_RING (chan, b->c_mask); -} - -static void nv20_state_emit_blend_color(struct nv20_context* nv20) -{ - struct pipe_blend_color *c = nv20->blend_color; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_COLOR, 1); - OUT_RING (chan, - (float_to_ubyte(c->color[3]) << 24)| - (float_to_ubyte(c->color[0]) << 16)| - (float_to_ubyte(c->color[1]) << 8) | - (float_to_ubyte(c->color[2]) << 0)); -} - -static void nv20_state_emit_rast(struct nv20_context* nv20) -{ - struct nv20_rasterizer_state *r = nv20->rast; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 2); - OUT_RING (chan, r->shade_model); - OUT_RING (chan, r->line_width); - - - BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); - OUT_RING (chan, r->point_size); - - BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, r->poly_mode_front); - OUT_RING (chan, r->poly_mode_back); - - - BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2); - OUT_RING (chan, r->cull_face); - OUT_RING (chan, r->front_face); - - BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (chan, r->line_smooth_en); - OUT_RING (chan, r->poly_smooth_en); - - BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, r->cull_face_en); -} - -static void nv20_state_emit_dsa(struct nv20_context* nv20) -{ - struct nv20_depth_stencil_alpha_state *d = nv20->dsa; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1); - OUT_RING (chan, d->depth.func); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, d->depth.write_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, d->depth.test_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1); - OUT_RING (chan, 1); - -#if 0 - BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1); - OUT_RING (chan, d->stencil.enable); - BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7); - OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7); -#endif - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, d->alpha.enabled); - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1); - OUT_RING (chan, d->alpha.func); - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_REF, 1); - OUT_RING (chan, d->alpha.ref); -} - -static void nv20_state_emit_viewport(struct nv20_context* nv20) -{ -} - -static void nv20_state_emit_scissor(struct nv20_context* nv20) -{ - /* NV20TCL_SCISSOR_* is probably a software method */ -/* struct pipe_scissor_state *s = nv20->scissor; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2); - OUT_RING (chan, ((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (chan, ((s->maxy - s->miny) << 16) | s->miny);*/ -} - -static void nv20_state_emit_framebuffer(struct nv20_context* nv20) -{ - struct pipe_framebuffer_state* fb = nv20->framebuffer; - struct nv04_surface *rt, *zeta = NULL; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv20_miptree *nv20mt = 0; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)fb->cbufs[0]; - - if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - - zeta_format = fb->zsbuf->format; - zeta = (struct nv04_surface *)fb->zsbuf; - } - - rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR | 0x20; - - switch (colour_format) { - case PIPE_FORMAT_X8R8G8B8_UNORM: - rt_format |= NV20TCL_RT_FORMAT_COLOR_X8R8G8B8; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format |= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format |= NV20TCL_RT_FORMAT_COLOR_R5G6B5; - break; - default: - assert(0); - } - - if (zeta) { - BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (zeta->pitch << 16)); - } else { - BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (rt->pitch << 16)); - } - - nv20mt = (struct nv20_miptree *)rt->base.texture; - nv20->rt[0] = nv20mt->buffer; - - if (zeta_format) - { - nv20mt = (struct nv20_miptree *)zeta->base.texture; - nv20->zeta = nv20mt->buffer; - } - - BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 3); - OUT_RING (chan, (w << 16) | 0); - OUT_RING (chan, (h << 16) | 0); /*NV20TCL_RT_VERT */ - OUT_RING (chan, rt_format); /* NV20TCL_RT_FORMAT */ - BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (chan, ((w - 1) << 16) | 0); - OUT_RING (chan, ((h - 1) << 16) | 0); -} - -static void nv20_vertex_layout(struct nv20_context *nv20) -{ - struct nv20_fragment_program *fp = nv20->fragprog.current; - struct draw_context *dc = nv20->draw; - int src; - int i; - struct vertex_info *vinfo = &nv20->vertex_info; - const enum interp_mode colorInterp = INTERP_LINEAR; - boolean colors[2] = { FALSE }; - boolean generics[12] = { FALSE }; - boolean fog = FALSE; - - memset(vinfo, 0, sizeof(*vinfo)); - - /* - * Assumed NV20 hardware vertex attribute order: - * 0 position, 1 ?, 2 ?, 3 col0, - * 4 col1?, 5 ?, 6 ?, 7 ?, - * 8 ?, 9 tex0, 10 tex1, 11 tex2, - * 12 tex3, 13 ?, 14 ?, 15 ? - * unaccounted: wgh, nor, fog - * There are total 16 attrs. - * vinfo->hwfmt[0] has a used-bit corresponding to each of these. - * relation to TGSI_SEMANTIC_*: - * - POSITION: position (always used) - * - COLOR: col1, col0 - * - GENERIC: tex3, tex2, tex1, tex0, normal, weight - * - FOG: fog - */ - - for (i = 0; i < fp->info.num_inputs; i++) { - int isn = fp->info.input_semantic_name[i]; - int isi = fp->info.input_semantic_index[i]; - switch (isn) { - case TGSI_SEMANTIC_POSITION: - break; - case TGSI_SEMANTIC_COLOR: - assert(isi < 2); - colors[isi] = TRUE; - break; - case TGSI_SEMANTIC_GENERIC: - assert(isi < 12); - generics[isi] = TRUE; - break; - case TGSI_SEMANTIC_FOG: - fog = TRUE; - break; - default: - assert(0 && "unknown input_semantic_name"); - } - } - - /* always do position */ { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src); - vinfo->hwfmt[0] |= (1 << 0); - } - - /* two unnamed generics */ - for (i = 4; i < 6; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i - 3)); - } - - if (colors[0]) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - vinfo->hwfmt[0] |= (1 << 3); - } - - if (colors[1]) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - vinfo->hwfmt[0] |= (1 << 4); - } - - /* four unnamed generics */ - for (i = 6; i < 10; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i - 1)); - } - - /* tex0, tex1, tex2, tex3 */ - for (i = 0; i < 4; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i + 9)); - } - - /* two unnamed generics */ - for (i = 10; i < 12; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i + 3)); - } - - if (fog) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0); - draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << 15); - } - - draw_compute_vertex_size(vinfo); -} - -void -nv20_emit_hw_state(struct nv20_context *nv20) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - struct nouveau_bo *rt_bo; - int i; - - if (nv20->dirty & NV20_NEW_VERTPROG) { - //nv20_vertprog_bind(nv20, nv20->vertprog.current); - nv20->dirty &= ~NV20_NEW_VERTPROG; - } - - if (nv20->dirty & NV20_NEW_FRAGPROG) { - nv20_fragprog_bind(nv20, nv20->fragprog.current); - /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */ - nv20->dirty_samplers |= (1<<10); - nv20->dirty_samplers = 0; - } - - if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) { - nv20_fragtex_bind(nv20); - nv20->dirty &= ~NV20_NEW_FRAGPROG; - } - - if (nv20->dirty & NV20_NEW_VTXARRAYS) { - nv20->dirty &= ~NV20_NEW_VTXARRAYS; - nv20_vertex_layout(nv20); - nv20_vtxbuf_bind(nv20); - } - - if (nv20->dirty & NV20_NEW_BLEND) { - nv20->dirty &= ~NV20_NEW_BLEND; - nv20_state_emit_blend(nv20); - } - - if (nv20->dirty & NV20_NEW_BLENDCOL) { - nv20->dirty &= ~NV20_NEW_BLENDCOL; - nv20_state_emit_blend_color(nv20); - } - - if (nv20->dirty & NV20_NEW_RAST) { - nv20->dirty &= ~NV20_NEW_RAST; - nv20_state_emit_rast(nv20); - } - - if (nv20->dirty & NV20_NEW_DSA) { - nv20->dirty &= ~NV20_NEW_DSA; - nv20_state_emit_dsa(nv20); - } - - if (nv20->dirty & NV20_NEW_VIEWPORT) { - nv20->dirty &= ~NV20_NEW_VIEWPORT; - nv20_state_emit_viewport(nv20); - } - - if (nv20->dirty & NV20_NEW_SCISSOR) { - nv20->dirty &= ~NV20_NEW_SCISSOR; - nv20_state_emit_scissor(nv20); - } - - if (nv20->dirty & NV20_NEW_FRAMEBUFFER) { - nv20->dirty &= ~NV20_NEW_FRAMEBUFFER; - nv20_state_emit_framebuffer(nv20); - } - - /* Emit relocs for every referenced buffer. - * This is to ensure the bufmgr has an accurate idea of how - * the buffer is used. This isn't very efficient, but we don't - * seem to take a significant performance hit. Will be improved - * at some point. Vertex arrays are emitted by nv20_vbo.c - */ - - /* Render target */ - rt_bo = nouveau_bo(nv20->rt[0]); - BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - if (nv20->zeta) { - struct nouveau_bo *zeta_bo = nouveau_bo(nv20->zeta); - BEGIN_RING(chan, kelvin, NV20TCL_DMA_ZETA, 1); - OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_ZETA_OFFSET, 1); - OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - /* XXX for when we allocate LMA on nv17 */ -/* BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); - OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/ - } - - /* Vertex buffer */ - BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - /* Texture images */ - for (i = 0; i < 2; i++) { - if (!(nv20->fp_samplers & (1 << i))) - continue; - struct nouveau_bo *bo = nouveau_bo(nv20->tex[i].buffer); - BEGIN_RING(chan, kelvin, NV20TCL_TX_OFFSET(i), 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - BEGIN_RING(chan, kelvin, NV20TCL_TX_FORMAT(i), 1); - OUT_RELOCd(chan, bo, nv20->tex[i].format, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | - NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0, - NV20TCL_TX_FORMAT_DMA1); - } -} - diff --git a/src/gallium/drivers/nv20/nv20_surface.c b/src/gallium/drivers/nv20/nv20_surface.c deleted file mode 100644 index 4224bdd6af..0000000000 --- a/src/gallium/drivers/nv20/nv20_surface.c +++ /dev/null @@ -1,63 +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 "nv20_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" -#include "util/u_tile.h" - -static void -nv20_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv04_surface_2d *eng2d = nv20->screen->eng2d; - - eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); -} - -static void -nv20_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv04_surface_2d *eng2d = nv20->screen->eng2d; - - eng2d->fill(eng2d, dest, destx, desty, width, height, value); -} - -void -nv20_init_surface_functions(struct nv20_context *nv20) -{ - nv20->pipe.surface_copy = nv20_surface_copy; - nv20->pipe.surface_fill = nv20_surface_fill; -} diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c deleted file mode 100644 index 699773e8e6..0000000000 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <pipe/p_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv20_context.h" -#include "nv20_screen.h" -#include "nv20_state.h" - -struct nv20_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv20_miptree *mt = (struct nv20_miptree *)pt; - struct nv20_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv20_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv20_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv20_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv20_screen *nvscreen = nv20_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv20_transfer_del(struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - - if (!tx->direct && (ptx->usage = PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv20_screen *nvscreen = nv20_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv20_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv20_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv20_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv20_transfer_new; - pscreen->tex_transfer_destroy = nv20_transfer_del; - pscreen->transfer_map = nv20_transfer_map; - pscreen->transfer_unmap = nv20_transfer_unmap; -} diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c deleted file mode 100644 index 52991a0d85..0000000000 --- a/src/gallium/drivers/nv20/nv20_vbo.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_inlines.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void nv20_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) -{ - struct pipe_screen *pscreen = pipe->screen; - struct nv20_context *nv20 = nv20_context( pipe ); - struct draw_context *draw = nv20->draw; - unsigned i; - - nv20_emit_hw_state(nv20); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv20->vtxbuf[i].buffer) { - void *buf - = pipe_buffer_map(pscreen, - nv20->vtxbuf[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_vertex_buffer(draw, i, buf); - } - } - /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes - = pipe_buffer_map(pscreen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, NULL); - } - - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, - nv20->constbuf[PIPE_SHADER_VERTEX], - nv20->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv20->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv20->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv20->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } - - draw_flush(nv20->draw); -} - -void nv20_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - nv20_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c deleted file mode 100644 index 7886c2af7e..0000000000 --- a/src/gallium/drivers/nv20/nv20_vertprog.c +++ /dev/null @@ -1,841 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_inlines.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_dump.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -/* TODO (at least...): - * 1. Indexed consts + ARL - * 2. Arb. swz/negation - * 3. NV_vp11, NV_vp2, NV_vp3 features - * - extra arith opcodes - * - branching - * - texture sampling - * - indexed attribs - * - indexed results - * 4. bugs - */ - -#define SWZ_X 0 -#define SWZ_Y 1 -#define SWZ_Z 2 -#define SWZ_W 3 -#define MASK_X 8 -#define MASK_Y 4 -#define MASK_Z 2 -#define MASK_W 1 -#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) -#define DEF_SCALE 0 -#define DEF_CTEST 0 -#include "nv20_shader.h" - -#define swz(s,x,y,z,w) nv20_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) -#define neg(s) nv20_sr_neg((s)) -#define abs(s) nv20_sr_abs((s)) - -struct nv20_vpc { - struct nv20_vertex_program *vp; - - struct nv20_vertex_program_exec *vpi; - - unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; - - int high_temp; - int temp_temp_count; - - struct nv20_sreg *imm; - unsigned nr_imm; -}; - -static struct nv20_sreg -temp(struct nv20_vpc *vpc) -{ - int idx; - - idx = vpc->temp_temp_count++; - idx += vpc->high_temp + 1; - return nv20_sr(NV30SR_TEMP, idx); -} - -static struct nv20_sreg -constant(struct nv20_vpc *vpc, int pipe, float x, float y, float z, float w) -{ - struct nv20_vertex_program *vp = vpc->vp; - struct nv20_vertex_program_data *vpd; - int idx; - - if (pipe >= 0) { - for (idx = 0; idx < vp->nr_consts; idx++) { - if (vp->consts[idx].index == pipe) - return nv20_sr(NV30SR_CONST, idx); - } - } - - idx = vp->nr_consts++; - vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts); - vpd = &vp->consts[idx]; - - vpd->index = pipe; - vpd->value[0] = x; - vpd->value[1] = y; - vpd->value[2] = z; - vpd->value[3] = w; - return nv20_sr(NV30SR_CONST, idx); -} - -#define arith(cc,s,o,d,m,s0,s1,s2) \ - nv20_vp_arith((cc), (s), NV30_VP_INST_##o, (d), (m), (s0), (s1), (s2)) - -static void -emit_src(struct nv20_vpc *vpc, uint32_t *hw, int pos, struct nv20_sreg src) -{ - struct nv20_vertex_program *vp = vpc->vp; - uint32_t sr = 0; - - switch (src.type) { - case NV30SR_TEMP: - sr |= (NV30_VP_SRC_REG_TYPE_TEMP << NV30_VP_SRC_REG_TYPE_SHIFT); - sr |= (src.index << NV30_VP_SRC_TEMP_SRC_SHIFT); - break; - case NV30SR_INPUT: - sr |= (NV30_VP_SRC_REG_TYPE_INPUT << - NV30_VP_SRC_REG_TYPE_SHIFT); - vp->ir |= (1 << src.index); - hw[1] |= (src.index << NV30_VP_INST_INPUT_SRC_SHIFT); - break; - case NV30SR_CONST: - sr |= (NV30_VP_SRC_REG_TYPE_CONST << - NV30_VP_SRC_REG_TYPE_SHIFT); - assert(vpc->vpi->const_index == -1 || - vpc->vpi->const_index == src.index); - vpc->vpi->const_index = src.index; - break; - case NV30SR_NONE: - sr |= (NV30_VP_SRC_REG_TYPE_INPUT << - NV30_VP_SRC_REG_TYPE_SHIFT); - break; - default: - assert(0); - } - - if (src.negate) - sr |= NV30_VP_SRC_NEGATE; - - if (src.abs) - hw[0] |= (1 << (21 + pos)); - - sr |= ((src.swz[0] << NV30_VP_SRC_SWZ_X_SHIFT) | - (src.swz[1] << NV30_VP_SRC_SWZ_Y_SHIFT) | - (src.swz[2] << NV30_VP_SRC_SWZ_Z_SHIFT) | - (src.swz[3] << NV30_VP_SRC_SWZ_W_SHIFT)); - -/* - * |VVV| - * d�.�b - * \u/ - * - */ - - switch (pos) { - case 0: - hw[1] |= ((sr & NV30_VP_SRC0_HIGH_MASK) >> - NV30_VP_SRC0_HIGH_SHIFT) << NV30_VP_INST_SRC0H_SHIFT; - hw[2] |= (sr & NV30_VP_SRC0_LOW_MASK) << - NV30_VP_INST_SRC0L_SHIFT; - break; - case 1: - hw[2] |= sr << NV30_VP_INST_SRC1_SHIFT; - break; - case 2: - hw[2] |= ((sr & NV30_VP_SRC2_HIGH_MASK) >> - NV30_VP_SRC2_HIGH_SHIFT) << NV30_VP_INST_SRC2H_SHIFT; - hw[3] |= (sr & NV30_VP_SRC2_LOW_MASK) << - NV30_VP_INST_SRC2L_SHIFT; - break; - default: - assert(0); - } -} - -static void -emit_dst(struct nv20_vpc *vpc, uint32_t *hw, int slot, struct nv20_sreg dst) -{ - struct nv20_vertex_program *vp = vpc->vp; - - switch (dst.type) { - case NV30SR_TEMP: - hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT); - break; - case NV30SR_OUTPUT: - switch (dst.index) { - case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break; - case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break; - case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break; - case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break; - case NV30_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break; - case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break; - case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break; - case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break; - case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break; - case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break; - case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break; - case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; - case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; - case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; - default: - break; - } - - hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT); - hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); - - /*XXX: no way this is entirely correct, someone needs to - * figure out what exactly it is. - */ - hw[3] |= 0x800; - break; - default: - assert(0); - } -} - -static void -nv20_vp_arith(struct nv20_vpc *vpc, int slot, int op, - struct nv20_sreg dst, int mask, - struct nv20_sreg s0, struct nv20_sreg s1, - struct nv20_sreg s2) -{ - struct nv20_vertex_program *vp = vpc->vp; - uint32_t *hw; - - vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); - vpc->vpi = &vp->insns[vp->nr_insns - 1]; - memset(vpc->vpi, 0, sizeof(*vpc->vpi)); - vpc->vpi->const_index = -1; - - hw = vpc->vpi->data; - - hw[0] |= (NV30_VP_INST_COND_TR << NV30_VP_INST_COND_SHIFT); - hw[0] |= ((0 << NV30_VP_INST_COND_SWZ_X_SHIFT) | - (1 << NV30_VP_INST_COND_SWZ_Y_SHIFT) | - (2 << NV30_VP_INST_COND_SWZ_Z_SHIFT) | - (3 << NV30_VP_INST_COND_SWZ_W_SHIFT)); - - hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); -// hw[3] |= NV30_VP_INST_SCA_DEST_TEMP_MASK; -// hw[3] |= (mask << NV30_VP_INST_VEC_WRITEMASK_SHIFT); - - if (dst.type == NV30SR_OUTPUT) { - if (slot) - hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT); - else - hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT); - } else { - if (slot) - hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT); - else - hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT); - } - - emit_dst(vpc, hw, slot, dst); - emit_src(vpc, hw, 0, s0); - emit_src(vpc, hw, 1, s1); - emit_src(vpc, hw, 2, s2); -} - -static INLINE struct nv20_sreg -tgsi_src(struct nv20_vpc *vpc, const struct tgsi_full_src_register *fsrc) { - struct nv20_sreg src; - - switch (fsrc->Register.File) { - case TGSI_FILE_INPUT: - src = nv20_sr(NV30SR_INPUT, fsrc->Register.Index); - break; - case TGSI_FILE_CONSTANT: - src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0); - break; - case TGSI_FILE_IMMEDIATE: - src = vpc->imm[fsrc->Register.Index]; - break; - case TGSI_FILE_TEMPORARY: - if (vpc->high_temp < fsrc->Register.Index) - vpc->high_temp = fsrc->Register.Index; - src = nv20_sr(NV30SR_TEMP, fsrc->Register.Index); - break; - default: - NOUVEAU_ERR("bad src file\n"); - break; - } - - src.abs = fsrc->Register.Absolute; - src.negate = fsrc->Register.Negate; - src.swz[0] = fsrc->Register.SwizzleX; - src.swz[1] = fsrc->Register.SwizzleY; - src.swz[2] = fsrc->Register.SwizzleZ; - src.swz[3] = fsrc->Register.SwizzleW; - return src; -} - -static INLINE struct nv20_sreg -tgsi_dst(struct nv20_vpc *vpc, const struct tgsi_full_dst_register *fdst) { - struct nv20_sreg dst; - - switch (fdst->Register.File) { - case TGSI_FILE_OUTPUT: - dst = nv20_sr(NV30SR_OUTPUT, - vpc->output_map[fdst->Register.Index]); - - break; - case TGSI_FILE_TEMPORARY: - dst = nv20_sr(NV30SR_TEMP, fdst->Register.Index); - if (vpc->high_temp < dst.index) - vpc->high_temp = dst.index; - break; - default: - NOUVEAU_ERR("bad dst file\n"); - break; - } - - return dst; -} - -static INLINE int -tgsi_mask(uint tgsi) -{ - int mask = 0; - - if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; - if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; - if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; - if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; - return mask; -} - -static boolean -nv20_vertprog_parse_instruction(struct nv20_vpc *vpc, - const struct tgsi_full_instruction *finst) -{ - struct nv20_sreg src[3], dst, tmp; - struct nv20_sreg none = nv20_sr(NV30SR_NONE, 0); - int mask; - int ai = -1, ci = -1; - int i; - - if (finst->Instruction.Opcode == TGSI_OPCODE_END) - return TRUE; - - vpc->temp_temp_count = 0; - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - const struct tgsi_full_src_register *fsrc; - - fsrc = &finst->Src[i]; - if (fsrc->Register.File == TGSI_FILE_TEMPORARY) { - src[i] = tgsi_src(vpc, fsrc); - } - } - - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - const struct tgsi_full_src_register *fsrc; - - fsrc = &finst->Src[i]; - switch (fsrc->Register.File) { - case TGSI_FILE_INPUT: - if (ai == -1 || ai == fsrc->Register.Index) { - ai = fsrc->Register.Index; - src[i] = tgsi_src(vpc, fsrc); - } else { - src[i] = temp(vpc); - arith(vpc, 0, OP_MOV, src[i], MASK_ALL, - tgsi_src(vpc, fsrc), none, none); - } - break; - /*XXX: index comparison is broken now that consts come from - * two different register files. - */ - case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - if (ci == -1 || ci == fsrc->Register.Index) { - ci = fsrc->Register.Index; - src[i] = tgsi_src(vpc, fsrc); - } else { - src[i] = temp(vpc); - arith(vpc, 0, OP_MOV, src[i], MASK_ALL, - tgsi_src(vpc, fsrc), none, none); - } - break; - case TGSI_FILE_TEMPORARY: - /* handled above */ - break; - default: - NOUVEAU_ERR("bad src file\n"); - return FALSE; - } - } - - dst = tgsi_dst(vpc, &finst->Dst[0]); - mask = tgsi_mask(finst->Dst[0].Register.WriteMask); - - switch (finst->Instruction.Opcode) { - case TGSI_OPCODE_ABS: - arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); - break; - case TGSI_OPCODE_ADD: - arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]); - break; - case TGSI_OPCODE_ARL: - arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_DP3: - arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DP4: - arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DPH: - arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DST: - arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_EX2: - arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_EXP: - arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_FLR: - arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_FRC: - arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_LG2: - arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_LIT: - arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_LOG: - arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_MAD: - arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]); - break; - case TGSI_OPCODE_MAX: - arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_MIN: - arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_MOV: - arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_MUL: - arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_POW: - tmp = temp(vpc); - arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none, - swz(src[0], X, X, X, X)); - arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X), - swz(src[1], X, X, X, X), none); - arith(vpc, 1, OP_EX2, dst, mask, none, none, - swz(tmp, X, X, X, X)); - break; - case TGSI_OPCODE_RCP: - arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_RET: - break; - case TGSI_OPCODE_RSQ: - arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_SGE: - arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SGT: - arith(vpc, 0, OP_SGT, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SLT: - arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SUB: - arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1])); - break; - case TGSI_OPCODE_XPD: - tmp = temp(vpc); - arith(vpc, 0, OP_MUL, tmp, mask, - swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); - arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W), - swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), - neg(tmp)); - break; - default: - NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); - return FALSE; - } - - return TRUE; -} - -static boolean -nv20_vertprog_parse_decl_output(struct nv20_vpc *vpc, - const struct tgsi_full_declaration *fdec) -{ - int hw; - - switch (fdec->Semantic.Name) { - case TGSI_SEMANTIC_POSITION: - hw = NV30_VP_INST_DEST_POS; - break; - case TGSI_SEMANTIC_COLOR: - if (fdec->Semantic.Index == 0) { - hw = NV30_VP_INST_DEST_COL0; - } else - if (fdec->Semantic.Index == 1) { - hw = NV30_VP_INST_DEST_COL1; - } else { - NOUVEAU_ERR("bad colour semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_BCOLOR: - if (fdec->Semantic.Index == 0) { - hw = NV30_VP_INST_DEST_BFC0; - } else - if (fdec->Semantic.Index == 1) { - hw = NV30_VP_INST_DEST_BFC1; - } else { - NOUVEAU_ERR("bad bcolour semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_FOG: - hw = NV30_VP_INST_DEST_FOGC; - break; - case TGSI_SEMANTIC_PSIZE: - hw = NV30_VP_INST_DEST_PSZ; - break; - case TGSI_SEMANTIC_GENERIC: - if (fdec->Semantic.Index <= 7) { - hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index); - } else { - NOUVEAU_ERR("bad generic semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_EDGEFLAG: - NOUVEAU_ERR("cannot handle edgeflag output\n"); - return FALSE; - default: - NOUVEAU_ERR("bad output semantic\n"); - return FALSE; - } - - vpc->output_map[fdec->Range.First] = hw; - return TRUE; -} - -static boolean -nv20_vertprog_prepare(struct nv20_vpc *vpc) -{ - struct tgsi_parse_context p; - int nr_imm = 0; - - tgsi_parse_init(&p, vpc->vp->pipe.tokens); - while (!tgsi_parse_end_of_tokens(&p)) { - const union tgsi_full_token *tok = &p.FullToken; - - tgsi_parse_token(&p); - switch(tok->Token.Type) { - case TGSI_TOKEN_TYPE_IMMEDIATE: - nr_imm++; - break; - default: - break; - } - } - tgsi_parse_free(&p); - - if (nr_imm) { - vpc->imm = CALLOC(nr_imm, sizeof(struct nv20_sreg)); - assert(vpc->imm); - } - - return TRUE; -} - -static void -nv20_vertprog_translate(struct nv20_context *nv20, - struct nv20_vertex_program *vp) -{ - struct tgsi_parse_context parse; - struct nv20_vpc *vpc = NULL; - - tgsi_dump(vp->pipe.tokens,0); - - vpc = CALLOC(1, sizeof(struct nv20_vpc)); - if (!vpc) - return; - vpc->vp = vp; - vpc->high_temp = -1; - - if (!nv20_vertprog_prepare(vpc)) { - FREE(vpc); - return; - } - - tgsi_parse_init(&parse, vp->pipe.tokens); - - while (!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - { - const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; - switch (fdec->Declaration.File) { - case TGSI_FILE_OUTPUT: - if (!nv20_vertprog_parse_decl_output(vpc, fdec)) - goto out_err; - break; - default: - break; - } - } - break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - const struct tgsi_full_immediate *imm; - - imm = &parse.FullToken.FullImmediate; - assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); - assert(imm->Immediate.NrTokens == 4 + 1); - vpc->imm[vpc->nr_imm++] = - constant(vpc, -1, - imm->u[0].Float, - imm->u[1].Float, - imm->u[2].Float, - imm->u[3].Float); - } - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - const struct tgsi_full_instruction *finst; - finst = &parse.FullToken.FullInstruction; - if (!nv20_vertprog_parse_instruction(vpc, finst)) - goto out_err; - } - break; - default: - break; - } - } - - vp->insns[vp->nr_insns - 1].data[3] |= NV30_VP_INST_LAST; - vp->translated = TRUE; -out_err: - tgsi_parse_free(&parse); - FREE(vpc); -} - -static boolean -nv20_vertprog_validate(struct nv20_context *nv20) -{ - struct pipe_screen *pscreen = nv20->pipe.screen; - struct nouveau_winsys *nvws = nv20->nvws; - struct nouveau_grobj *rankine = nv20->screen->rankine; - struct nv20_vertex_program *vp; - struct pipe_buffer *constbuf; - boolean upload_code = FALSE, upload_data = FALSE; - int i; - - vp = nv20->vertprog; - constbuf = nv20->constbuf[PIPE_SHADER_VERTEX]; - - /* Translate TGSI shader into hw bytecode */ - if (!vp->translated) { - nv20_vertprog_translate(nv20, vp); - if (!vp->translated) - return FALSE; - } - - /* Allocate hw vtxprog exec slots */ - if (!vp->exec) { - struct nouveau_resource *heap = nv20->screen->vp_exec_heap; - struct nouveau_stateobj *so; - uint vplen = vp->nr_insns; - - if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { - while (heap->next && heap->size < vplen) { - struct nv20_vertex_program *evict; - - evict = heap->next->priv; - nvws->res_free(&evict->exec); - } - - if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) - assert(0); - } - - so = so_new(2, 0); - so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); - so_data (so, vp->exec->start); - so_ref(so, &vp->so); - - upload_code = TRUE; - } - - /* Allocate hw vtxprog const slots */ - if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv20->screen->vp_data_heap; - - if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { - while (heap->next && heap->size < vp->nr_consts) { - struct nv20_vertex_program *evict; - - evict = heap->next->priv; - nvws->res_free(&evict->data); - } - - if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) - assert(0); - } - - /*XXX: handle this some day */ - assert(vp->data->start >= vp->data_start_min); - - upload_data = TRUE; - if (vp->data_start != vp->data->start) - upload_code = TRUE; - } - - /* If exec or data segments moved we need to patch the program to - * fixup offsets and register IDs. - */ - if (vp->exec_start != vp->exec->start) { - for (i = 0; i < vp->nr_insns; i++) { - struct nv20_vertex_program_exec *vpi = &vp->insns[i]; - - if (vpi->has_branch_offset) { - assert(0); - } - } - - vp->exec_start = vp->exec->start; - } - - if (vp->nr_consts && vp->data_start != vp->data->start) { - for (i = 0; i < vp->nr_insns; i++) { - struct nv20_vertex_program_exec *vpi = &vp->insns[i]; - - if (vpi->const_index >= 0) { - vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK; - vpi->data[1] |= - (vpi->const_index + vp->data->start) << - NV30_VP_INST_CONST_SRC_SHIFT; - - } - } - - vp->data_start = vp->data->start; - } - - /* Update + Upload constant values */ - if (vp->nr_consts) { - float *map = NULL; - - if (constbuf) { - map = pipe_buffer_map(pscreen, constbuf, - PIPE_BUFFER_USAGE_CPU_READ); - } - - for (i = 0; i < vp->nr_consts; i++) { - struct nv20_vertex_program_data *vpd = &vp->consts[i]; - - if (vpd->index >= 0) { - if (!upload_data && - !memcmp(vpd->value, &map[vpd->index * 4], - 4 * sizeof(float))) - continue; - memcpy(vpd->value, &map[vpd->index * 4], - 4 * sizeof(float)); - } - - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5); - OUT_RING (i + vp->data->start); - OUT_RINGp ((uint32_t *)vpd->value, 4); - } - - if (constbuf) - pipe_buffer_unmap(pscreen, constbuf); - } - - /* Upload vtxprog */ - if (upload_code) { -#if 0 - for (i = 0; i < vp->nr_insns; i++) { - NOUVEAU_MSG("VP inst %d: 0x%08x 0x%08x 0x%08x 0x%08x\n", - i, vp->insns[i].data[0], vp->insns[i].data[1], - vp->insns[i].data[2], vp->insns[i].data[3]); - } -#endif - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1); - OUT_RING (vp->exec->start); - for (i = 0; i < vp->nr_insns; i++) { - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_INST(0), 4); - OUT_RINGp (vp->insns[i].data, 4); - } - } - - if (vp->so != nv20->state.hw[NV30_STATE_VERTPROG]) { - so_ref(vp->so, &nv20->state.hw[NV30_STATE_VERTPROG]); - return TRUE; - } - - return FALSE; -} - -void -nv20_vertprog_destroy(struct nv20_context *nv20, struct nv20_vertex_program *vp) -{ - struct nouveau_winsys *nvws = nv20->screen->nvws; - - vp->translated = FALSE; - - if (vp->nr_insns) { - FREE(vp->insns); - vp->insns = NULL; - vp->nr_insns = 0; - } - - if (vp->nr_consts) { - FREE(vp->consts); - vp->consts = NULL; - vp->nr_consts = 0; - } - - nvws->res_free(&vp->exec); - vp->exec_start = 0; - nvws->res_free(&vp->data); - vp->data_start = 0; - vp->data_start_min = 0; - - vp->ir = vp->or = 0; - so_ref(NULL, &vp->so); -} - -struct nv20_state_entry nv20_state_vertprog = { - .validate = nv20_vertprog_validate, - .dirty = { - .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, - .hw = NV30_STATE_VERTPROG, - } -}; diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c index 54572e9ab3..8bfd7b2c90 100644 --- a/src/gallium/drivers/nv30/nv30_context.c +++ b/src/gallium/drivers/nv30/nv30_context.c @@ -1,6 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "nv30_context.h" #include "nv30_screen.h" @@ -43,7 +43,7 @@ nv30_destroy(struct pipe_context *pipe) } struct pipe_context * -nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) +nv30_create(struct pipe_screen *pscreen, void *priv) { struct nv30_screen *screen = nv30_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; @@ -54,12 +54,12 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id) if (!nv30) return NULL; nv30->screen = screen; - nv30->pctx_id = pctx_id; nv30->nvws = nvws; nv30->pipe.winsys = ws; nv30->pipe.screen = pscreen; + nv30->pipe.priv = priv; nv30->pipe.destroy = nv30_destroy; nv30->pipe.draw_arrays = nv30_draw_arrays; nv30->pipe.draw_elements = nv30_draw_elements; diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index e59449287b..b3b26f7f94 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -1,6 +1,8 @@ #ifndef __NV30_CONTEXT_H__ #define __NV30_CONTEXT_H__ +#include <stdio.h> + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" @@ -8,6 +10,7 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_inlines.h" #include "draw/draw_vertex.h" @@ -108,7 +111,6 @@ struct nv30_context { struct nouveau_winsys *nvws; struct nv30_screen *screen; - unsigned pctx_id; struct draw_context *draw; @@ -206,4 +208,8 @@ extern void nv30_draw_elements(struct pipe_context *pipe, extern void nv30_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil); +/* nv30_context.c */ +struct pipe_context * +nv30_create(struct pipe_screen *pscreen, void *priv); + #endif diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c index 2d565cb631..2c432c6dfa 100644 --- a/src/gallium/drivers/nv30/nv30_fragprog.c +++ b/src/gallium/drivers/nv30/nv30_fragprog.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 9893567891..0cc3172dcd 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -43,7 +43,6 @@ static struct nv30_texture_format * nv30_fragtex_format(uint pipe_format) { struct nv30_texture_format *tf = nv30_texture_formats; - char fs[128]; while (tf->defined) { if (tf->pipe == pipe_format) @@ -65,7 +64,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer); struct nv30_texture_format *tf; struct nouveau_stateobj *so; - uint32_t txf, txs , txp; + uint32_t txf, txs; unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; tf = nv30_fragtex_format(pt->format); @@ -97,13 +96,6 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit) return NULL; } - if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { - txp = 0; - } else { - txp = nv30mt->level[0].pitch; - txf |= (1<<13) /*FIXME: NV34TCL_TX_FORMAT_LINEAR ? */; - } - txs = tf->swizzle; so = so_new(1, 8, 2); diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index 8fbba38e78..c29c36e20a 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -1,11 +1,11 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "nv30_context.h" -#include "../nv04/nv04_surface_2d.h" +#include "../nouveau/nv04_surface_2d.h" static void nv30_miptree_layout(struct nv30_miptree *nv30mt) diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 9ed48178dc..8f9b26ea56 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -20,9 +20,6 @@ struct nouveau_winsys { struct pipe_screen *pscreen; - unsigned nr_pctx; - struct pipe_context **pctx; - struct pipe_surface *front; }; @@ -67,6 +64,16 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -163,9 +170,9 @@ nv30_screen_destroy(struct pipe_screen *pscreen) so_ref(NULL, &screen->state[i]); } - nouveau_resource_free(&screen->vp_exec_heap); - nouveau_resource_free(&screen->vp_data_heap); - nouveau_resource_free(&screen->query_heap); + nouveau_resource_destroy(&screen->vp_exec_heap); + nouveau_resource_destroy(&screen->vp_data_heap); + nouveau_resource_destroy(&screen->query_heap); nouveau_notifier_free(&screen->query); nouveau_notifier_free(&screen->sync); nouveau_grobj_free(&screen->rankine); @@ -202,6 +209,7 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->get_param = nv30_screen_get_param; pscreen->get_paramf = nv30_screen_get_paramf; pscreen->is_format_supported = nv30_screen_surface_format_supported; + pscreen->context_create = nv30_create; nv30_screen_init_miptree_functions(pscreen); nv30_screen_init_transfer_functions(pscreen); diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index 5fbd998b53..8591cd31ca 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -3,14 +3,14 @@ #include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" +#include "nouveau/nv04_surface_2d.h" struct nv30_screen { struct nouveau_screen base; struct nouveau_winsys *nvws; - unsigned cur_pctx; + struct nv30_context *cur_ctx; /* HW graphics objects */ struct nv04_surface_2d *eng2d; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 66096de61e..f775938ba7 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -1,6 +1,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi/tgsi_parse.h" @@ -16,27 +16,27 @@ nv30_blend_state_create(struct pipe_context *pipe, struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(5, 8, 0); - if (cso->blend_enable) { + if (cso->rt[0].blend_enable) { so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3); so_data (so, 1); - so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | - nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | - nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | + nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rt[0].rgb_dst_factor)); /* FIXME: Gallium assumes GL_EXT_blend_func_separate. It is not the case for NV30 */ so_method(so, rankine, NV34TCL_BLEND_EQUATION, 1); - so_data (so, nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); } else { so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1); so_data (so, 0); } so_method(so, rankine, NV34TCL_COLOR_MASK, 1); - so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); if (cso->logicop_enable) { so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); @@ -590,12 +590,12 @@ nv30_set_clip_state(struct pipe_context *pipe, static void nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf ) + struct pipe_buffer *buf ) { struct nv30_context *nv30 = nv30_context(pipe); - nv30->constbuf[shader] = buf->buffer; - nv30->constbuf_nr[shader] = buf->buffer->size / (4 * sizeof(float)); + nv30->constbuf[shader] = buf; + nv30->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); if (shader == PIPE_SHADER_VERTEX) { nv30->dirty |= NV30_NEW_VERTPROG; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index ac52d946f0..d9650f63eb 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -44,13 +44,15 @@ nv30_state_emit(struct nv30_context *nv30) unsigned i; uint64_t states; - if (nv30->pctx_id != screen->cur_pctx) { + /* XXX: racy! + */ + if (nv30 != screen->cur_ctx) { for (i = 0; i < NV30_STATE_MAX; i++) { if (state->hw[i] && screen->state[i] != state->hw[i]) state->dirty |= (1ULL << i); } - screen->cur_pctx = nv30->pctx_id; + screen->cur_ctx = nv30; } for (i = 0, states = state->dirty; states; i++) { diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c index 5e237e13eb..b48c5ab51a 100644 --- a/src/gallium/drivers/nv30/nv30_surface.c +++ b/src/gallium/drivers/nv30/nv30_surface.c @@ -28,8 +28,8 @@ #include "nv30_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" #include "util/u_tile.h" static void diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c index 65598991c6..554bcbbdd0 100644 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nv30/nv30_transfer.c @@ -1,6 +1,6 @@ #include <pipe/p_state.h> #include <pipe/p_defines.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_math.h> diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index 1c5db03ea2..a83ddf1154 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -1,6 +1,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "nv30_context.h" #include "nv30_state.h" @@ -223,7 +223,6 @@ nv30_draw_arrays(struct pipe_context *pipe, } pipe->flush(pipe, 0, NULL); - return TRUE; } static INLINE void @@ -382,7 +381,7 @@ nv30_draw_elements_inline(struct pipe_context *pipe, map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); - return FALSE; + return; } switch (ib_size) { @@ -424,7 +423,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, FIRE_RING(chan); continue; } - + BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1); OUT_RING (chan, nvgl_primitive(mode)); @@ -468,7 +467,7 @@ nv30_draw_elements(struct pipe_context *pipe, if (FORCE_SWTNL || !nv30_state_validate(nv30)) { /*return nv30_draw_elements_swtnl(pipe, NULL, 0, mode, start, count);*/ - return; + return; } if (idxbuf) { diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c index e77a5be3f2..809be3712d 100644 --- a/src/gallium/drivers/nv30/nv30_vertprog.c +++ b/src/gallium/drivers/nv30/nv30_vertprog.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index f79ae4db84..b0b90032de 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -1,6 +1,6 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "nv40_context.h" #include "nv40_screen.h" @@ -43,7 +43,7 @@ nv40_destroy(struct pipe_context *pipe) } struct pipe_context * -nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) +nv40_create(struct pipe_screen *pscreen, void *priv) { struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; @@ -54,11 +54,11 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) if (!nv40) return NULL; nv40->screen = screen; - nv40->pctx_id = pctx_id; nv40->nvws = nvws; nv40->pipe.winsys = ws; + nv40->pipe.priv = priv; nv40->pipe.screen = pscreen; nv40->pipe.destroy = nv40_destroy; nv40->pipe.draw_arrays = nv40_draw_arrays; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index e219bb537a..958a48f2a4 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -1,6 +1,8 @@ #ifndef __NV40_CONTEXT_H__ #define __NV40_CONTEXT_H__ +#include <stdio.h> + #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" @@ -8,6 +10,7 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_inlines.h" #include "draw/draw_vertex.h" @@ -108,7 +111,6 @@ struct nv40_context { struct nouveau_winsys *nvws; struct nv40_screen *screen; - unsigned pctx_id; struct draw_context *draw; @@ -227,4 +229,8 @@ extern void nv40_draw_elements(struct pipe_context *pipe, extern void nv40_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil); +/* nv40_context.c */ +struct pipe_context * +nv40_create(struct pipe_screen *pscreen, void *priv); + #endif diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index d826f8c2f5..60ab49fad1 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,5 +1,5 @@ #include "pipe/p_shader_tokens.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_pack_color.h" @@ -271,7 +271,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, map = pipe_buffer_map(pscreen, nv40->constbuf[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, 0, map, nr); } diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 1237066c39..dc24f9b08a 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 89bd155ff4..ad1a9a5195 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -1,11 +1,11 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "nv40_context.h" -#include "../nv04/nv04_surface_2d.h" +#include "../nouveau/nv04_surface_2d.h" diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 9e55e5a089..001147e752 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -52,6 +52,16 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) if (screen->curie->grclass == NV40TCL) return 1; return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -147,9 +157,9 @@ nv40_screen_destroy(struct pipe_screen *pscreen) so_ref(NULL, &screen->state[i]); } - nouveau_resource_free(&screen->vp_exec_heap); - nouveau_resource_free(&screen->vp_data_heap); - nouveau_resource_free(&screen->query_heap); + nouveau_resource_destroy(&screen->vp_exec_heap); + nouveau_resource_destroy(&screen->vp_data_heap); + nouveau_resource_destroy(&screen->query_heap); nouveau_notifier_free(&screen->query); nouveau_notifier_free(&screen->sync); nouveau_grobj_free(&screen->curie); @@ -186,6 +196,7 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->get_param = nv40_screen_get_param; pscreen->get_paramf = nv40_screen_get_paramf; pscreen->is_format_supported = nv40_screen_surface_format_supported; + pscreen->context_create = nv40_create; nv40_screen_init_miptree_functions(pscreen); nv40_screen_init_transfer_functions(pscreen); diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 57b4c8fc46..9437aa050d 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -2,14 +2,14 @@ #define __NV40_SCREEN_H__ #include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" +#include "nouveau/nv04_surface_2d.h" struct nv40_screen { struct nouveau_screen base; struct nouveau_winsys *nvws; - unsigned cur_pctx; + struct nv40_context *cur_ctx; /* HW graphics objects */ struct nv04_surface_2d *eng2d; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 5084c48eeb..51b40e51e4 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -1,6 +1,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" @@ -18,26 +18,26 @@ nv40_blend_state_create(struct pipe_context *pipe, struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(5, 8, 0); - if (cso->blend_enable) { + if (cso->rt[0].blend_enable) { so_method(so, curie, NV40TCL_BLEND_ENABLE, 3); so_data (so, 1); - so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | - nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | - nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | + nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rt[0].rgb_dst_factor)); so_method(so, curie, NV40TCL_BLEND_EQUATION, 1); - so_data (so, nvgl_blend_eqn(cso->alpha_func) << 16 | - nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 | + nvgl_blend_eqn(cso->rt[0].rgb_func)); } else { so_method(so, curie, NV40TCL_BLEND_ENABLE, 1); so_data (so, 0); } so_method(so, curie, NV40TCL_COLOR_MASK, 1); - so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); if (cso->logicop_enable) { so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2); @@ -605,12 +605,12 @@ nv40_set_clip_state(struct pipe_context *pipe, static void nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf ) + struct pipe_buffer *buf ) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->constbuf[shader] = buf->buffer; - nv40->constbuf_nr[shader] = buf->buffer->size / (4 * sizeof(float)); + nv40->constbuf[shader] = buf; + nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float)); if (shader == PIPE_SHADER_VERTEX) { nv40->dirty |= NV40_NEW_VERTPROG; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 13fe854915..1c4007a129 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -61,13 +61,15 @@ nv40_state_emit(struct nv40_context *nv40) unsigned i; uint64_t states; - if (nv40->pctx_id != screen->cur_pctx) { + /* XXX: race conditions + */ + if (nv40 != screen->cur_ctx) { for (i = 0; i < NV40_STATE_MAX; i++) { if (state->hw[i] && screen->state[i] != state->hw[i]) state->dirty |= (1ULL << i); } - screen->cur_pctx = nv40->pctx_id; + screen->cur_ctx = nv40; } for (i = 0, states = state->dirty; states; i++) { diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index a596547974..02ecfd7bbb 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -27,7 +27,7 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_tile.h" diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index 791ee6823d..ee266c6cfb 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -1,6 +1,6 @@ #include <pipe/p_state.h> #include <pipe/p_defines.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_math.h> diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index a777898f68..1e14edc56a 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -1,6 +1,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "nv40_context.h" #include "nv40_state.h" @@ -382,7 +382,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { NOUVEAU_ERR("failed mapping ib\n"); - return FALSE; + return; } switch (ib_size) { @@ -424,7 +424,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, FIRE_RING(chan); continue; } - + BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1); OUT_RING (chan, nvgl_primitive(mode)); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 8d80fcad38..b289eef0fc 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -1,7 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 5997456e4c..867bd03e69 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -22,7 +22,7 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "nv50_context.h" #include "nv50_screen.h" @@ -34,6 +34,11 @@ nv50_flush(struct pipe_context *pipe, unsigned flags, struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1); + OUT_RING (chan, 0x20); + } + if (flags & PIPE_FLUSH_FRAME) FIRE_RING(chan); } @@ -67,8 +72,12 @@ nv50_destroy(struct pipe_context *pipe) so_ref(NULL, &nv50->state.vertprog); if (nv50->state.fragprog) so_ref(NULL, &nv50->state.fragprog); - if (nv50->state.programs) - so_ref(NULL, &nv50->state.programs); + if (nv50->state.geomprog) + so_ref(NULL, &nv50->state.geomprog); + if (nv50->state.fp_linkage) + so_ref(NULL, &nv50->state.fp_linkage); + if (nv50->state.gp_linkage) + so_ref(NULL, &nv50->state.gp_linkage); if (nv50->state.vtxfmt) so_ref(NULL, &nv50->state.vtxfmt); if (nv50->state.vtxbuf) @@ -77,12 +86,16 @@ nv50_destroy(struct pipe_context *pipe) so_ref(NULL, &nv50->state.vtxattr); draw_destroy(nv50->draw); + + if (nv50->screen->cur_ctx == nv50) + nv50->screen->cur_ctx = NULL; + FREE(nv50); } struct pipe_context * -nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) +nv50_create(struct pipe_screen *pscreen, void *priv) { struct pipe_winsys *pipe_winsys = pscreen->winsys; struct nv50_screen *screen = nv50_screen(pscreen); @@ -92,15 +105,17 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) if (!nv50) return NULL; nv50->screen = screen; - nv50->pctx_id = pctx_id; nv50->pipe.winsys = pipe_winsys; nv50->pipe.screen = pscreen; + nv50->pipe.priv = priv; nv50->pipe.destroy = nv50_destroy; nv50->pipe.draw_arrays = nv50_draw_arrays; + nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced; nv50->pipe.draw_elements = nv50_draw_elements; + nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced; nv50->pipe.clear = nv50_clear; nv50->pipe.flush = nv50_flush; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index cbd4c3ff86..14cef4c0bf 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -1,6 +1,7 @@ #ifndef __NV50_CONTEXT_H__ #define __NV50_CONTEXT_H__ +#include <stdio.h> #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" @@ -8,6 +9,7 @@ #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_inlines.h" #include "draw/draw_vertex.h" @@ -29,9 +31,7 @@ #define NV50_CB_PVP 1 #define NV50_CB_PFP 2 #define NV50_CB_PGP 3 -#define NV50_CB_TIC 4 -#define NV50_CB_TSC 5 -#define NV50_CB_PUPLOAD 6 +#define NV50_CB_AUX 4 #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) @@ -45,9 +45,11 @@ #define NV50_NEW_VERTPROG_CB (1 << 9) #define NV50_NEW_FRAGPROG (1 << 10) #define NV50_NEW_FRAGPROG_CB (1 << 11) -#define NV50_NEW_ARRAYS (1 << 12) -#define NV50_NEW_SAMPLER (1 << 13) -#define NV50_NEW_TEXTURE (1 << 14) +#define NV50_NEW_GEOMPROG (1 << 12) +#define NV50_NEW_GEOMPROG_CB (1 << 13) +#define NV50_NEW_ARRAYS (1 << 14) +#define NV50_NEW_SAMPLER (1 << 15) +#define NV50_NEW_TEXTURE (1 << 16) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -129,10 +131,13 @@ struct nv50_state { unsigned miptree_nr[PIPE_SHADER_TYPES]; struct nouveau_stateobj *vertprog; struct nouveau_stateobj *fragprog; - struct nouveau_stateobj *programs; + struct nouveau_stateobj *geomprog; + struct nouveau_stateobj *fp_linkage; + struct nouveau_stateobj *gp_linkage; struct nouveau_stateobj *vtxfmt; struct nouveau_stateobj *vtxbuf; struct nouveau_stateobj *vtxattr; + struct nouveau_stateobj *instbuf; unsigned vtxelt_nr; }; @@ -140,7 +145,6 @@ struct nv50_context { struct pipe_context pipe; struct nv50_screen *screen; - unsigned pctx_id; struct draw_context *draw; @@ -157,6 +161,7 @@ struct nv50_context { struct pipe_framebuffer_state framebuffer; struct nv50_program *vertprog; struct nv50_program *fragprog; + struct nv50_program *geomprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; @@ -193,11 +198,22 @@ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); /* nv50_vbo.c */ extern void nv50_draw_arrays(struct pipe_context *, unsigned mode, unsigned start, unsigned count); +extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode, + unsigned start, unsigned count, + unsigned startInstance, + unsigned instanceCount); extern void nv50_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +extern void nv50_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ @@ -207,7 +223,9 @@ extern void nv50_clear(struct pipe_context *pipe, unsigned buffers, /* nv50_program.c */ extern void nv50_vertprog_validate(struct nv50_context *nv50); extern void nv50_fragprog_validate(struct nv50_context *nv50); -extern void nv50_linkage_validate(struct nv50_context *nv50); +extern void nv50_geomprog_validate(struct nv50_context *nv50); +extern void nv50_fp_linkage_validate(struct nv50_context *nv50); +extern void nv50_gp_linkage_validate(struct nv50_context *nv50); extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p); @@ -231,4 +249,8 @@ nv50_upload_sifc(struct nv50_context *nv50, void *src, unsigned src_format, int src_pitch, int x, int y, int w, int h, int cpp); +/* nv50_context.c */ +struct pipe_context * +nv50_create(struct pipe_screen *pscreen, void *priv); + #endif diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 3f1edf0a13..7297c74a83 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -22,7 +22,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "nv50_context.h" @@ -92,12 +92,23 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) case PIPE_FORMAT_Z24S8_UNORM: tile_flags = 0x1800; break; + case PIPE_FORMAT_Z16_UNORM: + tile_flags = 0x6c00; + break; case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8Z24_UNORM: tile_flags = 0x2800; break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + tile_flags = 0x7400; + break; default: - tile_flags = 0x7000; + if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) && + util_format_get_blocksizebits(pt->format) == 32) + tile_flags = 0x7a00; + else + tile_flags = 0x7000; break; } @@ -145,7 +156,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) mt->level[0].tile_mode, tile_flags, &mt->base.bo); if (ret) { - for (l = 0; l < pt->last_level; ++l) + for (l = 0; l <= pt->last_level; ++l) FREE(mt->level[l].image_offset); FREE(mt); return NULL; @@ -188,7 +199,7 @@ nv50_miptree_destroy(struct pipe_texture *pt) struct nv50_miptree *mt = nv50_miptree(pt); unsigned l; - for (l = 0; l < pt->last_level; ++l) + for (l = 0; l <= pt->last_level; ++l) FREE(mt->level[l].image_offset); nouveau_bo_ref(NULL, &mt->base.bo); diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 593d743603..2372cbbef6 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -23,7 +23,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" @@ -92,6 +92,11 @@ struct nv50_reg { int rhw; /* result hw for FP outputs, or interpolant index */ int acc; /* instruction where this reg is last read (first insn == 1) */ + + int vtx; /* vertex index, for GP inputs (TGSI Dimension.Index) */ + int indirect[2]; /* index into pc->addr, or -1 */ + + ubyte buf_index; /* c{0 .. 15}[] or g{0 .. 15}[] */ }; #define NV50_MOD_NEG 1 @@ -135,7 +140,8 @@ struct nv50_pc { int immd_nr; struct nv50_reg **addr; int addr_nr; - uint8_t addr_alloc; /* set bit indicates used for TGSI_FILE_ADDRESS */ + struct nv50_reg *sysval; + int sysval_nr; struct nv50_reg *temp_temp[16]; struct nv50_program_exec *temp_temp_exec[16]; @@ -171,6 +177,8 @@ struct nv50_pc { uint8_t edgeflag_out; }; +static struct nv50_reg *get_address_reg(struct nv50_pc *, struct nv50_reg *); + static INLINE void ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw) { @@ -179,7 +187,10 @@ ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw) reg->hw = hw; reg->mod = 0; reg->rhw = -1; + reg->vtx = -1; reg->acc = 0; + reg->indirect[0] = reg->indirect[1] = -1; + reg->buf_index = (type == P_CONST) ? 1 : 0; } static INLINE unsigned @@ -197,7 +208,8 @@ terminate_mbb(struct nv50_pc *pc) /* remove records of temporary address register values */ for (i = 0; i < NV50_SU_MAX_ADDR; ++i) - pc->r_addr[i].rhw = -1; + if (pc->r_addr[i].index < 0) + pc->r_addr[i].acc = 0; } static void @@ -260,6 +272,7 @@ reg_instance(struct nv50_pc *pc, struct nv50_reg *reg) if (reg) { alloc_reg(pc, reg); *ri = *reg; + reg->indirect[0] = reg->indirect[1] = -1; reg->mod = 0; } return ri; @@ -464,6 +477,12 @@ is_join(struct nv50_program_exec *e) return FALSE; } +static INLINE boolean +is_control_flow(struct nv50_program_exec *e) +{ + return (e->inst[0] & 2); +} + static INLINE void set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, struct nv50_program_exec *e) @@ -525,11 +544,33 @@ set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e) static INLINE void set_addr(struct nv50_program_exec *e, struct nv50_reg *a) { + assert(a->type == P_ADDR); + assert(!(e->inst[0] & 0x0c000000)); assert(!(e->inst[1] & 0x00000004)); e->inst[0] |= (a->hw & 3) << 26; - e->inst[1] |= (a->hw >> 2) << 2; + e->inst[1] |= a->hw & 4; +} + +static void +emit_arl(struct nv50_pc *, struct nv50_reg *, struct nv50_reg *, uint8_t); + +static void +emit_shl_imm(struct nv50_pc *, struct nv50_reg *, struct nv50_reg *, int); + +static void +emit_mov_from_addr(struct nv50_pc *pc, struct nv50_reg *dst, + struct nv50_reg *src) +{ + struct nv50_program_exec *e = exec(pc); + + e->inst[1] = 0x40000000; + set_long(pc, e); + set_dst(pc, dst, e); + set_addr(e, src); + + emit(pc, e); } static void @@ -548,72 +589,6 @@ emit_add_addr_imm(struct nv50_pc *pc, struct nv50_reg *dst, emit(pc, e); } -static struct nv50_reg * -alloc_addr(struct nv50_pc *pc, struct nv50_reg *ref) -{ - struct nv50_reg *a_tgsi = NULL, *a = NULL; - int i; - uint8_t avail = ~pc->addr_alloc; - - if (!ref) { - /* allocate for TGSI_FILE_ADDRESS */ - while (avail) { - i = ffs(avail) - 1; - - if (pc->r_addr[i].rhw < 0 || - pc->r_addr[i].acc != pc->insn_cur) { - pc->addr_alloc |= (1 << i); - - pc->r_addr[i].rhw = -1; - pc->r_addr[i].index = i; - return &pc->r_addr[i]; - } - avail &= ~(1 << i); - } - assert(0); - return NULL; - } - - /* Allocate and set an address reg so we can access 'ref'. - * - * If and r_addr->index will be -1 or the hw index the value - * value in rhw is relative to. If rhw < 0, the reg has not - * been initialized or is in use for TGSI_FILE_ADDRESS. - */ - while (avail) { /* only consider regs that are not TGSI */ - i = ffs(avail) - 1; - avail &= ~(1 << i); - - if ((!a || a->rhw >= 0) && pc->r_addr[i].rhw < 0) { - /* prefer an usused reg with low hw index */ - a = &pc->r_addr[i]; - continue; - } - if (!a && pc->r_addr[i].acc != pc->insn_cur) - a = &pc->r_addr[i]; - - if (ref->hw - pc->r_addr[i].rhw >= 128) - continue; - - if ((ref->acc >= 0 && pc->r_addr[i].index < 0) || - (ref->acc < 0 && pc->r_addr[i].index == ref->index)) { - pc->r_addr[i].acc = pc->insn_cur; - return &pc->r_addr[i]; - } - } - assert(a); - - if (ref->acc < 0) - a_tgsi = pc->addr[ref->index]; - - emit_add_addr_imm(pc, a, a_tgsi, (ref->hw & ~0x7f) * 4); - - a->rhw = ref->hw & ~0x7f; - a->acc = pc->insn_cur; - a->index = a_tgsi ? ref->index : -1; - return a; -} - #define INTERP_LINEAR 0 #define INTERP_FLAT 1 #define INTERP_PERSPECTIVE 2 @@ -657,15 +632,15 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s, e->param.shift = s; e->param.mask = m << (s % 32); - if (src->hw > 127) - set_addr(e, alloc_addr(pc, src)); + if (src->hw < 0 || src->hw > 127) /* need (additional) address reg */ + set_addr(e, get_address_reg(pc, src)); else if (src->acc < 0) { assert(src->type == P_CONST); - set_addr(e, pc->addr[src->index]); + set_addr(e, pc->addr[src->indirect[0]]); } - e->inst[1] |= (((src->type == P_IMMD) ? 0 : 1) << 22); + e->inst[1] |= (src->buf_index << 22); } /* Never apply nv50_reg::mod in emit_mov, or carefully check the code !!! */ @@ -694,6 +669,12 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src) if (src->type == P_ATTR) { set_long(pc, e); e->inst[1] |= 0x00200000; + + if (src->vtx >= 0) { + /* indirect (vertex base + c) load from p[] */ + e->inst[0] |= 0x01800000; + set_addr(e, get_address_reg(pc, src)); + } } alloc_reg(pc, src); @@ -808,6 +789,11 @@ set_src_0(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) if (src->type == P_ATTR) { set_long(pc, e); e->inst[1] |= 0x00200000; + + if (src->vtx >= 0) { + e->inst[0] |= 0x01800000; /* src from p[] */ + set_addr(e, get_address_reg(pc, src)); + } } else if (src->type == P_CONST || src->type == P_IMMD) { struct nv50_reg *temp = temp_temp(pc, e); @@ -832,13 +818,13 @@ set_src_1(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - assert(!(e->inst[0] & 0x00800000)); - if (e->inst[0] & 0x01000000) { + if (e->inst[0] & 0x01800000) { struct nv50_reg *temp = temp_temp(pc, e); emit_mov(pc, temp, src); src = temp; } else { + assert(!(e->inst[0] & 0x00800000)); set_data(pc, src, 0x7f, 16, e); e->inst[0] |= 0x00800000; } @@ -862,13 +848,13 @@ set_src_2(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e) src = temp; } else if (src->type == P_CONST || src->type == P_IMMD) { - assert(!(e->inst[0] & 0x01000000)); - if (e->inst[0] & 0x00800000) { + if (e->inst[0] & 0x01800000) { struct nv50_reg *temp = temp_temp(pc, e); emit_mov(pc, temp, src); src = temp; } else { + assert(!(e->inst[0] & 0x01000000)); set_data(pc, src, 0x7f, 32+14, e); e->inst[0] |= 0x01000000; } @@ -997,11 +983,125 @@ emit_arl(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src, e->inst[0] |= dst->hw << 2; e->inst[0] |= s << 16; /* shift left */ - set_src_0_restricted(pc, src, e); + set_src_0(pc, src, e); emit(pc, e); } +static boolean +address_reg_suitable(struct nv50_reg *a, struct nv50_reg *r) +{ + if (!r) + return FALSE; + + if (r->vtx != a->vtx) + return FALSE; + if (r->vtx >= 0) + return (r->indirect[1] == a->indirect[1]); + + if (r->hw < a->rhw || (r->hw - a->rhw) >= 128) + return FALSE; + + if (a->index >= 0) + return (a->index == r->indirect[0]); + return (a->indirect[0] == r->indirect[0]); +} + +static void +load_vertex_base(struct nv50_pc *pc, struct nv50_reg *dst, + struct nv50_reg *a, int shift) +{ + struct nv50_reg mem, *temp; + + ctor_reg(&mem, P_ATTR, -1, dst->vtx); + + assert(dst->type == P_ADDR); + if (!a) { + emit_arl(pc, dst, &mem, 0); + return; + } + temp = alloc_temp(pc, NULL); + + if (shift) { + emit_mov_from_addr(pc, temp, a); + if (shift < 0) + emit_shl_imm(pc, temp, temp, shift); + emit_arl(pc, dst, temp, MAX2(shift, 0)); + } + emit_mov(pc, temp, &mem); + set_addr(pc->p->exec_tail, dst); + + emit_arl(pc, dst, temp, 0); + free_temp(pc, temp); +} + +/* case (ref == NULL): allocate address register for TGSI_FILE_ADDRESS + * case (vtx >= 0, acc >= 0): load vertex base from a[vtx * 4] to $aX + * case (vtx >= 0, acc < 0): load vertex base from s[$aY + vtx * 4] to $aX + * case (vtx < 0, acc >= 0): memory address too high to encode + * case (vtx < 0, acc < 0): get source register for TGSI_FILE_ADDRESS + */ +static struct nv50_reg * +get_address_reg(struct nv50_pc *pc, struct nv50_reg *ref) +{ + int i; + struct nv50_reg *a_ref, *a = NULL; + + for (i = 0; i < NV50_SU_MAX_ADDR; ++i) { + if (pc->r_addr[i].acc == 0) + a = &pc->r_addr[i]; /* an unused address reg */ + else + if (address_reg_suitable(&pc->r_addr[i], ref)) { + pc->r_addr[i].acc = pc->insn_cur; + return &pc->r_addr[i]; + } else + if (!a && pc->r_addr[i].index < 0 && + pc->r_addr[i].acc < pc->insn_cur) + a = &pc->r_addr[i]; + } + if (!a) { + /* We'll be able to spill address regs when this + * mess is replaced with a proper compiler ... + */ + NOUVEAU_ERR("out of address regs\n"); + abort(); + return NULL; + } + + /* initialize and reserve for this TGSI instruction */ + a->rhw = 0; + a->index = a->indirect[0] = a->indirect[1] = -1; + a->acc = pc->insn_cur; + + if (!ref) { + a->vtx = -1; + return a; + } + a->vtx = ref->vtx; + + /* now put in the correct value ... */ + + if (ref->vtx >= 0) { + a->indirect[1] = ref->indirect[1]; + + /* For an indirect vertex index, we need to shift address right + * by 2, the address register will contain vtx * 16, we need to + * load from a[vtx * 4]. + */ + load_vertex_base(pc, a, (ref->acc < 0) ? + pc->addr[ref->indirect[1]] : NULL, -2); + } else { + assert(ref->acc < 0 || ref->indirect[0] < 0); + + a->rhw = ref->hw & ~0x7f; + a->indirect[0] = ref->indirect[0]; + a_ref = (ref->acc < 0) ? pc->addr[ref->indirect[0]] : NULL; + + emit_add_addr_imm(pc, a, a_ref, a->rhw * 4); + } + return a; +} + #define NV50_MAX_F32 0x880 #define NV50_MAX_S32 0x08c #define NV50_MAX_U32 0x084 @@ -1629,6 +1729,18 @@ emit_ret(struct nv50_pc *pc, int pred, unsigned cc) emit_control_flow(pc, 0x3, pred, cc); } +static void +emit_prim_cmd(struct nv50_pc *pc, unsigned cmd) +{ + struct nv50_program_exec *e = exec(pc); + + e->inst[0] = 0xf0000000 | (cmd << 9); + e->inst[1] = 0xc0000000; + set_long(pc, e); + + emit(pc, e); +} + #define QOP_ADD 0 #define QOP_SUBR 1 #define QOP_SUB 2 @@ -2171,14 +2283,19 @@ tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst) { struct nv50_reg *r = pc->addr[dst->Register.Index * 4 + c]; if (!r) { - r = alloc_addr(pc, NULL); - pc->addr[dst->Register.Index * 4 + c] = r; + r = get_address_reg(pc, NULL); + r->index = dst->Register.Index * 4 + c; + pc->addr[r->index] = r; } assert(r); return r; } case TGSI_FILE_NULL: return NULL; + case TGSI_FILE_SYSTEM_VALUE: + assert(pc->sysval[dst->Register.Index].type == P_RESULT); + assert(c == 0); + return &pc->sysval[dst->Register.Index]; default: break; } @@ -2208,6 +2325,18 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src, switch (src->Register.File) { case TGSI_FILE_INPUT: r = &pc->attr[src->Register.Index * 4 + c]; + + if (!src->Dimension.Dimension) + break; + r = reg_instance(pc, r); + r->vtx = src->Dimension.Index; + + if (!src->Dimension.Indirect) + break; + swz = tgsi_util_get_src_register_swizzle( + &src->DimIndirect, 0); + r->acc = -1; + r->indirect[1] = src->DimIndirect.Index * 4 + swz; break; case TGSI_FILE_TEMPORARY: r = &pc->temp[src->Register.Index * 4 + c]; @@ -2221,12 +2350,12 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src, * use the index field to select the address reg. */ r = reg_instance(pc, NULL); + ctor_reg(r, P_CONST, -1, src->Register.Index * 4 + c); + swz = tgsi_util_get_src_register_swizzle( - &src->Indirect, 0); - ctor_reg(r, P_CONST, - src->Indirect.Index * 4 + swz, - src->Register.Index * 4 + c); + &src->Indirect, 0); r->acc = -1; + r->indirect[0] = src->Indirect.Index * 4 + swz; break; case TGSI_FILE_IMMEDIATE: r = &pc->immd[src->Register.Index * 4 + c]; @@ -2237,6 +2366,10 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src, r = pc->addr[src->Register.Index * 4 + c]; assert(r); break; + case TGSI_FILE_SYSTEM_VALUE: + assert(c == 0); + r = &pc->sysval[src->Register.Index]; + break; default: assert(0); break; @@ -2273,7 +2406,7 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src, r->mod |= mod & NV50_MOD_I32; assert(r); - if (r->acc >= 0 && r != temp) + if (r->acc >= 0 && r->vtx < 0 && r != temp) return reg_instance(pc, r); /* will clear r->mod */ return r; } @@ -2495,10 +2628,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, } break; case TGSI_OPCODE_ARL: - assert(src[0][0]); temp = temp_temp(pc, NULL); - emit_cvt(pc, temp, src[0][0], -1, CVT_FLOOR | CVT_S32_F32); - emit_arl(pc, dst[0], temp, 4); + for (c = 0; c < 4; c++) { + if (!(mask & (1 << c))) + continue; + emit_cvt(pc, temp, src[0][c], -1, + CVT_FLOOR | CVT_S32_F32); + emit_arl(pc, dst[c], temp, 4); + } break; case TGSI_OPCODE_BGNLOOP: pc->loop_brka[pc->loop_lvl] = emit_breakaddr(pc); @@ -2605,6 +2742,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, pc->if_insn[pc->if_lvl++] = pc->p->exec_tail; terminate_mbb(pc); break; + case TGSI_OPCODE_EMIT: + emit_prim_cmd(pc, 1); + break; case TGSI_OPCODE_ENDIF: pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size; @@ -2628,8 +2768,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, pc->loop_brka[pc->loop_lvl]->param.index = pc->p->exec_size; terminate_mbb(pc); break; + case TGSI_OPCODE_ENDPRIM: + emit_prim_cmd(pc, 2); + break; case TGSI_OPCODE_ENDSUB: assert(pc->in_subroutine); + terminate_mbb(pc); pc->in_subroutine = FALSE; break; case TGSI_OPCODE_EX2: @@ -3028,10 +3172,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (!is_long(pc->p->exec_tail)) convert_to_long(pc, pc->p->exec_tail); else - if (is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail)) + if (is_immd(pc->p->exec_tail) || + is_join(pc->p->exec_tail) || + is_control_flow(pc->p->exec_tail)) emit_nop(pc); pc->p->exec_tail->inst[1] |= 1; /* set exit bit */ + + terminate_mbb(pc); break; default: NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode); @@ -3135,7 +3283,7 @@ prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn) static unsigned nv50_revdep_reorder(unsigned m[4], unsigned rdep[4]) { - unsigned i, c, x, unsafe; + unsigned i, c, x, unsafe = 0; for (c = 0; c < 4; c++) m[c] = c; @@ -3327,17 +3475,53 @@ load_interpolant(struct nv50_pc *pc, struct nv50_reg *reg) * value of 0 for back-facing, and 0xffffffff for front-facing. */ static void -load_frontfacing(struct nv50_pc *pc, struct nv50_reg *a) +load_frontfacing(struct nv50_pc *pc, struct nv50_reg *sv) { - struct nv50_reg *one = alloc_immd(pc, 1.0f); + struct nv50_reg *temp = alloc_temp(pc, NULL); + int r_pred = 0; - assert(a->rhw == -1); - alloc_reg(pc, a); /* do this before rhw is set */ - a->rhw = 255; - load_interpolant(pc, a); - emit_bitop2(pc, a, a, one, TGSI_OPCODE_AND); + temp->rhw = 255; + emit_interp(pc, temp, NULL, INTERP_FLAT); - FREE(one); + emit_cvt(pc, sv, temp, r_pred, CVT_ABS | CVT_F32_S32); + + emit_not(pc, temp, temp); + set_pred(pc, 0x2, r_pred, pc->p->exec_tail); + emit_cvt(pc, sv, temp, -1, CVT_F32_S32); + set_pred(pc, 0x2, r_pred, pc->p->exec_tail); + + free_temp(pc, temp); +} + +static void +load_instance_id(struct nv50_pc *pc, unsigned index) +{ + struct nv50_reg reg, mem; + + ctor_reg(®, P_TEMP, -1, -1); + ctor_reg(&mem, P_CONST, -1, 24); /* startInstance */ + mem.buf_index = 2; + + emit_add_b32(pc, ®, &pc->sysval[index], &mem); + pc->sysval[index] = reg; +} + +static void +copy_semantic_info(struct nv50_program *p) +{ + unsigned i, id; + + for (i = 0; i < p->cfg.in_nr; ++i) { + id = p->cfg.in[i].id; + p->cfg.in[i].sn = p->info.input_semantic_name[id]; + p->cfg.in[i].si = p->info.input_semantic_index[id]; + } + + for (i = 0; i < p->cfg.out_nr; ++i) { + id = p->cfg.out[i].id; + p->cfg.out[i].sn = p->info.output_semantic_name[id]; + p->cfg.out[i].si = p->info.output_semantic_index[id]; + } } static boolean @@ -3346,7 +3530,7 @@ nv50_program_tx_prep(struct nv50_pc *pc) struct tgsi_parse_context tp; struct nv50_program *p = pc->p; boolean ret = FALSE; - unsigned i, c, flat_nr = 0; + unsigned i, c, instance_id, vertex_id, flat_nr = 0; tgsi_parse_init(&tp, pc->p->pipe.tokens); while (!tgsi_parse_end_of_tokens(&tp)) { @@ -3386,13 +3570,13 @@ nv50_program_tx_prep(struct nv50_pc *pc) switch (d->Semantic.Name) { case TGSI_SEMANTIC_BCOLOR: p->cfg.two_side[si].hw = first; - if (p->cfg.io_nr > first) - p->cfg.io_nr = first; + if (p->cfg.out_nr > first) + p->cfg.out_nr = first; break; case TGSI_SEMANTIC_PSIZE: p->cfg.psiz = first; - if (p->cfg.io_nr > first) - p->cfg.io_nr = first; + if (p->cfg.out_nr > first) + p->cfg.out_nr = first; break; case TGSI_SEMANTIC_EDGEFLAG: pc->edgeflag_out = first; @@ -3432,6 +3616,37 @@ nv50_program_tx_prep(struct nv50_pc *pc) pc->interp_mode[i] = mode; } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(d->Declaration.Semantic); + switch (d->Semantic.Name) { + case TGSI_SEMANTIC_FACE: + assert(p->type == PIPE_SHADER_FRAGMENT); + load_frontfacing(pc, + &pc->sysval[first]); + break; + case TGSI_SEMANTIC_INSTANCEID: + assert(p->type == PIPE_SHADER_VERTEX); + instance_id = first; + p->cfg.regs[0] |= (1 << 4); + break; + case TGSI_SEMANTIC_PRIMID: + assert(p->type != PIPE_SHADER_VERTEX); + p->cfg.prim_id = first; + break; + /* + case TGSI_SEMANTIC_PRIMIDIN: + assert(p->type == PIPE_SHADER_GEOMETRY); + pc->sysval[first].hw = 6; + p->cfg.regs[0] |= (1 << 8); + break; + case TGSI_SEMANTIC_VERTEXID: + assert(p->type == PIPE_SHADER_VERTEX); + vertex_id = first; + p->cfg.regs[0] |= (1 << 12) | (1 << 0); + break; + */ + } + break; case TGSI_FILE_ADDRESS: case TGSI_FILE_CONSTANT: case TGSI_FILE_SAMPLER: @@ -3452,36 +3667,65 @@ nv50_program_tx_prep(struct nv50_pc *pc) } } - if (p->type == PIPE_SHADER_VERTEX) { + if (p->type == PIPE_SHADER_VERTEX || p->type == PIPE_SHADER_GEOMETRY) { int rid = 0; - for (i = 0; i < pc->attr_nr * 4; ++i) { - if (pc->attr[i].acc) { - pc->attr[i].hw = rid++; - p->cfg.attr[i / 32] |= 1 << (i % 32); + if (p->type == PIPE_SHADER_GEOMETRY) { + for (i = 0; i < pc->attr_nr; ++i) { + p->cfg.in[i].hw = rid; + p->cfg.in[i].id = i; + + for (c = 0; c < 4; ++c) { + int n = i * 4 + c; + if (!pc->attr[n].acc) + continue; + pc->attr[n].hw = rid++; + p->cfg.in[i].mask |= 1 << c; + } + } + } else { + for (i = 0; i < pc->attr_nr * 4; ++i) { + if (pc->attr[i].acc) { + pc->attr[i].hw = rid++; + p->cfg.attr[i / 32] |= 1 << (i % 32); + } + } + if (p->cfg.regs[0] & (1 << 0)) + pc->sysval[vertex_id].hw = rid++; + if (p->cfg.regs[0] & (1 << 4)) { + pc->sysval[instance_id].hw = rid++; + load_instance_id(pc, instance_id); } } for (i = 0, rid = 0; i < pc->result_nr; ++i) { - p->cfg.io[i].hw = rid; - p->cfg.io[i].id = i; + p->cfg.out[i].hw = rid; + p->cfg.out[i].id = i; for (c = 0; c < 4; ++c) { int n = i * 4 + c; if (!pc->result[n].acc) continue; pc->result[n].hw = rid++; - p->cfg.io[i].mask |= 1 << c; + p->cfg.out[i].mask |= 1 << c; } } + if (p->cfg.prim_id < 0x40) { + /* GP has to write to PrimitiveID */ + ctor_reg(&pc->sysval[p->cfg.prim_id], + P_RESULT, p->cfg.prim_id, rid); + p->cfg.prim_id = rid++; + } for (c = 0; c < 2; ++c) if (p->cfg.two_side[c].hw < 0x40) - p->cfg.two_side[c] = p->cfg.io[ + p->cfg.two_side[c] = p->cfg.out[ p->cfg.two_side[c].hw]; if (p->cfg.psiz < 0x40) - p->cfg.psiz = p->cfg.io[p->cfg.psiz].hw; + p->cfg.psiz = p->cfg.out[p->cfg.psiz].hw; + + copy_semantic_info(p); } else if (p->type == PIPE_SHADER_FRAGMENT) { int rid, aid; @@ -3489,31 +3733,34 @@ nv50_program_tx_prep(struct nv50_pc *pc) pc->allow32 = TRUE; - int base = (TGSI_SEMANTIC_POSITION == - p->info.input_semantic_name[0]) ? 0 : 1; + /* do we read FragCoord ? */ + if (pc->attr_nr && + p->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + /* select FCRD components we want accessible */ + for (c = 0; c < 4; ++c) + if (pc->attr[c].acc) + p->cfg.regs[1] |= 1 << (24 + c); + aid = 0; + } else /* offset by 1 if FCRD.w is needed for pinterp */ + aid = popcnt4(p->cfg.regs[1] >> 24); /* non-flat interpolants have to be mapped to * the lower hardware IDs, so sort them: */ for (i = 0; i < pc->attr_nr; i++) { if (pc->interp_mode[i] == INTERP_FLAT) - p->cfg.io[m++].id = i; + p->cfg.in[m++].id = i; else { if (!(pc->interp_mode[i] & INTERP_PERSPECTIVE)) - p->cfg.io[n].linear = TRUE; - p->cfg.io[n++].id = i; + p->cfg.in[n].linear = TRUE; + p->cfg.in[n++].id = i; } } - - if (!base) /* set w-coordinate mask from perspective interp */ - p->cfg.io[0].mask |= p->cfg.regs[1] >> 24; - - aid = popcnt4( /* if fcrd isn't contained in cfg.io */ - base ? (p->cfg.regs[1] >> 24) : p->cfg.io[0].mask); + copy_semantic_info(p); for (n = 0; n < pc->attr_nr; ++n) { - p->cfg.io[n].hw = rid = aid; - i = p->cfg.io[n].id; + p->cfg.in[n].hw = rid = aid; + i = p->cfg.in[n].id; if (p->info.input_semantic_name[n] == TGSI_SEMANTIC_FACE) { @@ -3525,16 +3772,13 @@ nv50_program_tx_prep(struct nv50_pc *pc) if (!pc->attr[i * 4 + c].acc) continue; pc->attr[i * 4 + c].rhw = rid++; - p->cfg.io[n].mask |= 1 << c; + p->cfg.in[n].mask |= 1 << c; load_interpolant(pc, &pc->attr[i * 4 + c]); } - aid += popcnt4(p->cfg.io[n].mask); + aid += popcnt4(p->cfg.in[n].mask); } - if (!base) - p->cfg.regs[1] |= p->cfg.io[0].mask << 24; - m = popcnt4(p->cfg.regs[1] >> 24); /* set count of non-position inputs and of non-flat @@ -3543,32 +3787,33 @@ nv50_program_tx_prep(struct nv50_pc *pc) p->cfg.regs[1] |= aid - m; if (flat_nr) { - i = p->cfg.io[pc->attr_nr - flat_nr].hw; + i = p->cfg.in[pc->attr_nr - flat_nr].hw; p->cfg.regs[1] |= (i - m) << 16; } else p->cfg.regs[1] |= p->cfg.regs[1] << 16; /* mark color semantic for light-twoside */ - n = 0x40; - for (i = 0; i < pc->attr_nr; i++) { - ubyte si, sn; - - sn = p->info.input_semantic_name[p->cfg.io[i].id]; - si = p->info.input_semantic_index[p->cfg.io[i].id]; - - if (sn == TGSI_SEMANTIC_COLOR) { - p->cfg.two_side[si] = p->cfg.io[i]; - - /* increase colour count */ - p->cfg.regs[0] += popcnt4( - p->cfg.two_side[si].mask) << 16; - - n = MIN2(n, p->cfg.io[i].hw - m); + n = 0x80; + for (i = 0; i < p->cfg.in_nr; i++) { + if (p->cfg.in[i].sn == TGSI_SEMANTIC_COLOR) { + n = MIN2(n, p->cfg.in[i].hw - m); + p->cfg.two_side[p->cfg.in[i].si] = p->cfg.in[i]; + + p->cfg.regs[0] += /* increase colour count */ + popcnt4(p->cfg.in[i].mask) << 16; } } - if (n < 0x40) + if (n < 0x80) p->cfg.regs[0] += n; + if (p->cfg.prim_id < 0x40) { + pc->sysval[p->cfg.prim_id].rhw = rid++; + emit_interp(pc, &pc->sysval[p->cfg.prim_id], NULL, + INTERP_FLAT); + /* increase FP_INTERPOLANT_CTRL_COUNT */ + p->cfg.regs[1] += 1; + } + /* Initialize FP results: * FragDepth is always first TGSI and last hw output */ @@ -3622,10 +3867,31 @@ free_nv50_pc(struct nv50_pc *pc) FREE(pc->attr); if (pc->temp) FREE(pc->temp); + if (pc->sysval) + FREE(pc->sysval); + if (pc->insn_pos) + FREE(pc->insn_pos); FREE(pc); } +static INLINE uint32_t +nv50_map_gs_output_prim(unsigned pprim) +{ + switch (pprim) { + case PIPE_PRIM_POINTS: + return NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_POINTS; + case PIPE_PRIM_LINE_STRIP: + return NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_LINE_STRIP; + case PIPE_PRIM_TRIANGLE_STRIP: + return NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE_TRIANGLE_STRIP; + default: + NOUVEAU_ERR("invalid GS_OUTPUT_PRIMITIVE: %u\n", pprim); + abort(); + return 0; + } +} + static boolean ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) { @@ -3639,25 +3905,55 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) pc->param_nr = p->info.file_max[TGSI_FILE_CONSTANT] + 1; pc->addr_nr = p->info.file_max[TGSI_FILE_ADDRESS] + 1; assert(pc->addr_nr <= 2); + pc->sysval_nr = p->info.file_max[TGSI_FILE_SYSTEM_VALUE] + 1; p->cfg.high_temp = 4; p->cfg.two_side[0].hw = 0x40; p->cfg.two_side[1].hw = 0x40; + p->cfg.prim_id = 0x40; p->cfg.edgeflag_in = pc->edgeflag_out = 0xff; + for (i = 0; i < p->info.num_properties; ++i) { + unsigned *data = &p->info.properties[i].data[0]; + + switch (p->info.properties[i].name) { + case TGSI_PROPERTY_GS_OUTPUT_PRIM: + p->cfg.prim_type = nv50_map_gs_output_prim(data[0]); + break; + case TGSI_PROPERTY_GS_MAX_VERTICES: + p->cfg.vert_count = data[0]; + break; + default: + break; + } + } + switch (p->type) { case PIPE_SHADER_VERTEX: p->cfg.psiz = 0x40; p->cfg.clpd = 0x40; - p->cfg.io_nr = pc->result_nr; + p->cfg.out_nr = pc->result_nr; + break; + case PIPE_SHADER_GEOMETRY: + assert(p->cfg.prim_type); + assert(p->cfg.vert_count); + + p->cfg.psiz = 0x80; + p->cfg.clpd = 0x80; + p->cfg.prim_id = 0x80; + p->cfg.out_nr = pc->result_nr; + p->cfg.in_nr = pc->attr_nr; + + p->cfg.two_side[0].hw = 0x80; + p->cfg.two_side[1].hw = 0x80; break; case PIPE_SHADER_FRAGMENT: rtype[0] = rtype[1] = P_TEMP; p->cfg.regs[0] = 0x01000004; - p->cfg.io_nr = pc->attr_nr; + p->cfg.in_nr = pc->attr_nr; if (p->info.writes_z) { p->cfg.regs[2] |= 0x00000100; @@ -3715,7 +4011,16 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p) return FALSE; } for (i = 0; i < NV50_SU_MAX_ADDR; ++i) - ctor_reg(&pc->r_addr[i], P_ADDR, -256, i + 1); + ctor_reg(&pc->r_addr[i], P_ADDR, -1, i + 1); + + if (pc->sysval_nr) { + pc->sysval = CALLOC(pc->sysval_nr, sizeof(struct nv50_reg *)); + if (!pc->sysval) + return FALSE; + /* will only ever use SYSTEM_VALUE[i].x (hopefully) */ + for (i = 0; i < pc->sysval_nr; ++i) + ctor_reg(&pc->sysval[i], rtype[0], i, -1); + } return TRUE; } @@ -3877,13 +4182,17 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) if (p->param_nr) { unsigned cb; - uint32_t *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type], + uint32_t *map = pipe_buffer_map(pscreen, + nv50->constbuf[p->type], PIPE_BUFFER_USAGE_CPU_READ); - - if (p->type == PIPE_SHADER_VERTEX) + switch (p->type) { + case PIPE_SHADER_GEOMETRY: cb = NV50_CB_PGP; break; + case PIPE_SHADER_FRAGMENT: cb = NV50_CB_PFP; break; + default: cb = NV50_CB_PVP; - else - cb = NV50_CB_PFP; + assert(p->type == PIPE_SHADER_VERTEX); + break; + } nv50_program_upload_data(nv50, map, 0, p->param_nr, cb); pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]); @@ -3977,19 +4286,18 @@ nv50_vertprog_validate(struct nv50_context *nv50) nv50_program_validate_data(nv50, p); nv50_program_validate_code(nv50, p); - so = so_new(5, 8, 2); + so = so_new(5, 7, 2); so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_HIGH, 0, 0); + NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | - NOUVEAU_BO_LOW, 0, 0); + NOUVEAU_BO_LOW, 0, 0); so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2); so_data (so, p->cfg.attr[0]); so_data (so, p->cfg.attr[1]); so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, p->cfg.high_result); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2); - so_data (so, p->cfg.high_result); //8); + so_method(so, tesla, NV50TCL_VP_REG_ALLOC_TEMP, 1); so_data (so, p->cfg.high_temp); so_method(so, tesla, NV50TCL_VP_START_ID, 1); so_data (so, 0); /* program start offset */ @@ -4033,42 +4341,74 @@ nv50_fragprog_validate(struct nv50_context *nv50) so_ref(NULL, &so); } +void +nv50_geomprog_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_program *p = nv50->geomprog; + struct nouveau_stateobj *so; + + if (!p->translated) { + nv50_program_validate(nv50, p); + if (!p->translated) + assert(0); + } + + nv50_program_validate_data(nv50, p); + nv50_program_validate_code(nv50, p); + + so = so_new(6, 7, 2); + so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2); + so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); + so_method(so, tesla, NV50TCL_GP_REG_ALLOC_TEMP, 1); + so_data (so, p->cfg.high_temp); + so_method(so, tesla, NV50TCL_GP_REG_ALLOC_RESULT, 1); + so_data (so, p->cfg.high_result); + so_method(so, tesla, NV50TCL_GP_OUTPUT_PRIMITIVE_TYPE, 1); + so_data (so, p->cfg.prim_type); + so_method(so, tesla, NV50TCL_GP_VERTEX_OUTPUT_COUNT, 1); + so_data (so, p->cfg.vert_count); + so_method(so, tesla, NV50TCL_GP_START_ID, 1); + so_data (so, 0); + so_ref(so, &nv50->state.geomprog); + so_ref(NULL, &so); +} + static uint32_t nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) { + struct nv50_program *vp; struct nv50_program *fp = nv50->fragprog; - struct nv50_program *vp = nv50->vertprog; unsigned i, c, m = base; uint32_t origin = 0x00000010; + vp = nv50->geomprog ? nv50->geomprog : nv50->vertprog; + /* XXX: this might not work correctly in all cases yet - we'll * just assume that an FP generic input that is not written in * the VP is PointCoord. */ memset(pntc, 0, 8 * sizeof(uint32_t)); - for (i = 0; i < fp->cfg.io_nr; i++) { - uint8_t sn, si; - uint8_t j, k = fp->cfg.io[i].id; - unsigned n = popcnt4(fp->cfg.io[i].mask); + for (i = 0; i < fp->cfg.in_nr; i++) { + unsigned j, n = popcnt4(fp->cfg.in[i].mask); - if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) { + if (fp->cfg.in[i].sn != TGSI_SEMANTIC_GENERIC) { m += n; continue; } - for (j = 0; j < vp->info.num_outputs; ++j) { - sn = vp->info.output_semantic_name[j]; - si = vp->info.output_semantic_index[j]; - - if (sn == fp->info.input_semantic_name[k] && - si == fp->info.input_semantic_index[k]) + for (j = 0; j < vp->cfg.out_nr; ++j) + if (vp->cfg.out[j].sn == fp->cfg.in[i].sn && + vp->cfg.out[j].si == fp->cfg.in[i].si) break; - } if (j < vp->info.num_outputs) { ubyte enable = - (nv50->rasterizer->pipe.sprite_coord_enable >> si) & 1; + (nv50->rasterizer->pipe.sprite_coord_enable >> vp->cfg.out[j].si) & 1; if (enable == 0) { m += n; @@ -4078,7 +4418,7 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) /* this is either PointCoord or replaced by sprite coords */ for (c = 0; c < 4; c++) { - if (!(fp->cfg.io[i].mask & (1 << c))) + if (!(fp->cfg.in[i].mask & (1 << c))) continue; pntc[m / 8] |= (c + 1) << ((m % 8) * 4); ++m; @@ -4088,18 +4428,22 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base) } static int -nv50_sreg4_map(uint32_t *p_map, int mid, uint32_t lin[4], - struct nv50_sreg4 *fpi, struct nv50_sreg4 *vpo) +nv50_vec4_map(uint32_t *map32, int mid, uint8_t zval, uint32_t lin[4], + struct nv50_sreg4 *fpi, struct nv50_sreg4 *vpo) { int c; uint8_t mv = vpo->mask, mf = fpi->mask, oid = vpo->hw; - uint8_t *map = (uint8_t *)p_map; + uint8_t *map = (uint8_t *)map32; for (c = 0; c < 4; ++c) { if (mf & 1) { if (fpi->linear == TRUE) lin[mid / 32] |= 1 << (mid % 32); - map[mid++] = (mv & 1) ? oid : ((c == 3) ? 0x41 : 0x40); + if (mv & 1) + map[mid] = oid; + else + map[mid] = (c == 3) ? (zval + 1) : zval; + ++mid; } oid += mv & 1; @@ -4111,34 +4455,42 @@ nv50_sreg4_map(uint32_t *p_map, int mid, uint32_t lin[4], } void -nv50_linkage_validate(struct nv50_context *nv50) +nv50_fp_linkage_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; struct nv50_program *vp = nv50->vertprog; struct nv50_program *fp = nv50->fragprog; struct nouveau_stateobj *so; - struct nv50_sreg4 dummy, *vpo; + struct nv50_sreg4 dummy; int i, n, c, m = 0; - uint32_t map[16], lin[4], reg[5], pcrd[8]; + uint32_t map[16], lin[4], reg[6], pcrd[8]; + uint8_t zval = 0x40; + if (nv50->geomprog) { + vp = nv50->geomprog; + zval = 0x80; + } memset(map, 0, sizeof(map)); memset(lin, 0, sizeof(lin)); reg[1] = 0x00000004; /* low and high clip distance map ids */ reg[2] = 0x00000000; /* layer index map id (disabled, GP only) */ reg[3] = 0x00000000; /* point size map id & enable */ + reg[5] = 0x00000000; /* primitive ID map slot */ reg[0] = fp->cfg.regs[0]; /* colour semantic reg */ reg[4] = fp->cfg.regs[1]; /* interpolant info */ dummy.linear = FALSE; dummy.mask = 0xf; /* map all components of HPOS */ - m = nv50_sreg4_map(map, m, lin, &dummy, &vp->cfg.io[0]); + m = nv50_vec4_map(map, m, zval, lin, &dummy, &vp->cfg.out[0]); dummy.mask = 0x0; if (vp->cfg.clpd < 0x40) { - for (c = 0; c < vp->cfg.clpd_nr; ++c) - map[m++] = vp->cfg.clpd + c; + for (c = 0; c < vp->cfg.clpd_nr; ++c) { + map[m / 4] |= (vp->cfg.clpd + c) << ((m % 4) * 8); + ++m; + } reg[1] = (m << 8); } @@ -4146,35 +4498,37 @@ nv50_linkage_validate(struct nv50_context *nv50) /* if light_twoside is active, it seems FFC0_ID == BFC0_ID is bad */ if (nv50->rasterizer->pipe.light_twoside) { - vpo = &vp->cfg.two_side[0]; + struct nv50_sreg4 *vpo = &vp->cfg.two_side[0]; + struct nv50_sreg4 *fpi = &fp->cfg.two_side[0]; - m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[0], &vpo[0]); - m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[1], &vpo[1]); + m = nv50_vec4_map(map, m, zval, lin, &fpi[0], &vpo[0]); + m = nv50_vec4_map(map, m, zval, lin, &fpi[1], &vpo[1]); } reg[0] += m - 4; /* adjust FFC0 id */ reg[4] |= m << 8; /* set mid where 'normal' FP inputs start */ - for (i = 0; i < fp->cfg.io_nr; i++) { - ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id]; - ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id]; - - /* position must be mapped first */ - assert(i == 0 || sn != TGSI_SEMANTIC_POSITION); - + for (i = 0; i < fp->cfg.in_nr; i++) { /* maybe even remove these from cfg.io */ - if (sn == TGSI_SEMANTIC_POSITION || sn == TGSI_SEMANTIC_FACE) + if (fp->cfg.in[i].sn == TGSI_SEMANTIC_POSITION || + fp->cfg.in[i].sn == TGSI_SEMANTIC_FACE) continue; - /* VP outputs and vp->cfg.io are in the same order */ - for (n = 0; n < vp->info.num_outputs; ++n) { - if (vp->info.output_semantic_name[n] == sn && - vp->info.output_semantic_index[n] == si) + for (n = 0; n < vp->cfg.out_nr; ++n) + if (vp->cfg.out[n].sn == fp->cfg.in[i].sn && + vp->cfg.out[n].si == fp->cfg.in[i].si) break; - } - vpo = (n < vp->info.num_outputs) ? &vp->cfg.io[n] : &dummy; - m = nv50_sreg4_map(map, m, lin, &fp->cfg.io[i], vpo); + m = nv50_vec4_map(map, m, zval, lin, &fp->cfg.in[i], + (n < vp->cfg.out_nr) ? + &vp->cfg.out[n] : &dummy); + } + /* PrimitiveID either is replaced by the system value, or + * written by the geometry shader into an output register + */ + if (fp->cfg.prim_id < 0x40) { + map[m / 4] |= vp->cfg.prim_id << ((m % 4) * 8); + reg[5] = m++; } if (nv50->rasterizer->pipe.point_size_per_vertex) { @@ -4182,14 +4536,28 @@ nv50_linkage_validate(struct nv50_context *nv50) reg[3] = (m++ << 4) | 1; } - /* now fill the stateobj */ - so = so_new(7, 57, 0); + /* now fill the stateobj (at most 28 so_data) */ + so = so_new(10, 54, 0); n = (m + 3) / 4; - so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); - so_data (so, m); - so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n); - so_datap (so, map, n); + assert(m <= 32); + if (vp->type == PIPE_SHADER_GEOMETRY) { + so_method(so, tesla, NV50TCL_GP_RESULT_MAP_SIZE, 1); + so_data (so, m); + so_method(so, tesla, NV50TCL_GP_RESULT_MAP(0), n); + so_datap (so, map, n); + } else { + so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1); + so_data (so, vp->cfg.regs[0]); + + so_method(so, tesla, NV50TCL_MAP_SEMANTIC_4, 1); + so_data (so, reg[5]); + + so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); + so_data (so, m); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n); + so_datap (so, map, n); + } so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); so_datap (so, reg, 4); @@ -4209,8 +4577,77 @@ nv50_linkage_validate(struct nv50_context *nv50) so_datap (so, pcrd, 8); } - so_ref(so, &nv50->state.programs); - so_ref(NULL, &so); + so_method(so, tesla, NV50TCL_GP_ENABLE, 1); + so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0); + + so_ref(so, &nv50->state.fp_linkage); + so_ref(NULL, &so); +} + +static int +construct_vp_gp_mapping(uint32_t *map32, int m, + struct nv50_program *vp, struct nv50_program *gp) +{ + uint8_t *map = (uint8_t *)map32; + int i, j, c; + + for (i = 0; i < gp->cfg.in_nr; ++i) { + uint8_t oid, mv = 0, mg = gp->cfg.in[i].mask; + + for (j = 0; j < vp->cfg.out_nr; ++j) { + if (vp->cfg.out[j].sn == gp->cfg.in[i].sn && + vp->cfg.out[j].si == gp->cfg.in[i].si) { + mv = vp->cfg.out[j].mask; + oid = vp->cfg.out[j].hw; + break; + } + } + + for (c = 0; c < 4; ++c, mv >>= 1, mg >>= 1) { + if (mg & mv & 1) + map[m++] = oid; + else + if (mg & 1) + map[m++] = (c == 3) ? 0x41 : 0x40; + oid += mv & 1; + } + } + return m; +} + +void +nv50_gp_linkage_validate(struct nv50_context *nv50) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_stateobj *so; + struct nv50_program *vp = nv50->vertprog; + struct nv50_program *gp = nv50->geomprog; + uint32_t map[16]; + int m = 0; + + if (!gp) { + so_ref(NULL, &nv50->state.gp_linkage); + return; + } + memset(map, 0, sizeof(map)); + + m = construct_vp_gp_mapping(map, m, vp, gp); + + so = so_new(3, 24 - 3, 0); + + so_method(so, tesla, NV50TCL_VP_GP_BUILTIN_ATTR_EN, 1); + so_data (so, vp->cfg.regs[0] | gp->cfg.regs[0]); + + assert(m <= 32); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1); + so_data (so, m); + + m = (m + 3) / 4; + so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m); + so_datap (so, map, m); + + so_ref(so, &nv50->state.gp_linkage); + so_ref(NULL, &so); } void @@ -4227,6 +4664,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) nouveau_bo_ref(NULL, &p->bo); + FREE(p->immd); nouveau_resource_free(&p->data[0]); p->translated = 0; diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 461fec1d89..1e3ad6bff0 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -16,11 +16,13 @@ struct nv50_program_exec { }; struct nv50_sreg4 { - uint8_t hw; - uint8_t id; /* tgsi index, nv50 needs them sorted: flat ones last */ + uint8_t hw; /* hw index, nv50 wants flat FP inputs last */ + uint8_t id; /* tgsi index */ uint8_t mask; boolean linear; + + ubyte sn, si; /* semantic name & index */ }; struct nv50_program { @@ -49,16 +51,24 @@ struct nv50_program { uint32_t regs[4]; /* for VPs, io_nr doesn't count 'private' results (PSIZ etc.) */ - unsigned io_nr; - struct nv50_sreg4 io[PIPE_MAX_SHADER_OUTPUTS]; + unsigned in_nr, out_nr; + struct nv50_sreg4 in[PIPE_MAX_SHADER_INPUTS]; + struct nv50_sreg4 out[PIPE_MAX_SHADER_OUTPUTS]; /* FP colour inputs, VP/GP back colour outputs */ struct nv50_sreg4 two_side[2]; - /* VP only */ + /* GP only */ + unsigned vert_count; + uint8_t prim_type; + + /* VP & GP only */ uint8_t clpd, clpd_nr; uint8_t psiz; uint8_t edgeflag_in; + + /* FP & GP only */ + uint8_t prim_id; } cfg; }; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 5a4ab3508b..57b16a355d 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -21,7 +21,7 @@ */ #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "nv50_context.h" @@ -48,7 +48,7 @@ nv50_query_create(struct pipe_context *pipe, unsigned type) assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); q->type = type; - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 256, + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256, 16, &q->bo); if (ret) { FREE(q); @@ -95,11 +95,13 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */ BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); - OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (chan, 0x00000000); OUT_RING (chan, 0x0100f002); - FIRE_RING (chan); + + BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); + OUT_RING (chan, 0); } static boolean @@ -123,6 +125,35 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, return q->ready; } +static void +nv50_render_condition(struct pipe_context *pipe, + struct pipe_query *pq, uint mode) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_query *q; + + if (!pq) { + BEGIN_RING(chan, tesla, NV50TCL_COND_MODE, 1); + OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS); + return; + } + q = nv50_query(pq); + + if (mode == PIPE_RENDER_COND_WAIT || + mode == PIPE_RENDER_COND_BY_REGION_WAIT) { + /* XXX: big fence, FIFO semaphore might be better */ + BEGIN_RING(chan, tesla, 0x0110, 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, tesla, NV50TCL_COND_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RING (chan, NV50TCL_COND_MODE_RES); +} + void nv50_init_query_functions(struct nv50_context *nv50) { @@ -131,4 +162,5 @@ nv50_init_query_functions(struct nv50_context *nv50) nv50->pipe.begin_query = nv50_query_begin; nv50->pipe.end_query = nv50_query_end; nv50->pipe.get_query_result = nv50_query_result; + nv50->pipe.render_condition = nv50_render_condition; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 28e2b35dea..8c4478e483 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -135,6 +135,16 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case NOUVEAU_CAP_HW_IDXBUF: return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 1; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -167,7 +177,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen) struct nv50_screen *screen = nv50_screen(pscreen); unsigned i; - for (i = 0; i < 2; i++) { + for (i = 0; i < 3; i++) { if (screen->constbuf_parm[i]) nouveau_bo_ref(NULL, &screen->constbuf_parm[i]); } @@ -185,6 +195,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen) nouveau_grobj_free(&screen->tesla); nouveau_grobj_free(&screen->eng2d); nouveau_grobj_free(&screen->m2mf); + nouveau_resource_destroy(&screen->immd_heap[0]); + nouveau_resource_destroy(&screen->parm_heap[0]); + nouveau_resource_destroy(&screen->parm_heap[1]); nouveau_screen_fini(&screen->base); FREE(screen); } @@ -238,6 +251,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) pscreen->get_param = nv50_screen_get_param; pscreen->get_paramf = nv50_screen_get_paramf; pscreen->is_format_supported = nv50_screen_is_format_supported; + pscreen->context_create = nv50_create; screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map; nv50_screen_init_miptree_functions(pscreen); @@ -329,7 +343,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_ref(NULL, &so); /* Static tesla init */ - so = so_new(40, 84, 20); + so = so_new(47, 95, 24); so_method(so, screen->tesla, NV50TCL_COND_MODE, 1); so_data (so, NV50TCL_COND_MODE_ALWAYS); @@ -352,10 +366,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_data (so, 0xf); /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */ - so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(0), 1); - so_data (so, 0x54); - so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(2), 1); - so_data (so, 0x54); + for (i = 0; i < 3; ++i) { + so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(i), 1); + so_data (so, 0x54); + } + /* origin is top left (set to 1 for bottom left) */ so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1); so_data (so, 0); @@ -370,8 +385,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - for (i = 0; i < 2; i++) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (128 * 4) * 4, + for (i = 0; i < 3; i++) { + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4, &screen->constbuf_parm[i]); if (ret) { nv50_screen_destroy(pscreen); @@ -406,22 +421,45 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000001 | (NV50_CB_PMISC << 12)); so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000021 | (NV50_CB_PMISC << 12)); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000031 | (NV50_CB_PMISC << 12)); + /* bind auxiliary constbuf to immediate data bo */ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, (NV50_CB_AUX << 16) | 0x00000200); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000201 | (NV50_CB_AUX << 12)); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000221 | (NV50_CB_AUX << 12)); + + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PVP << 16) | 0x00000800); so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000101 | (NV50_CB_PVP << 12)); so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); - so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); - so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, (NV50_CB_PGP << 16) | 0x00000800); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000121 | (NV50_CB_PGP << 12)); + + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PFP << 16) | 0x00000800); so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000131 | (NV50_CB_PFP << 12)); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index a038a4e3c2..2687b72127 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -9,7 +9,6 @@ struct nv50_screen { struct nouveau_winsys *nvws; - unsigned cur_pctx; struct nv50_context *cur_ctx; struct nouveau_grobj *tesla; @@ -18,10 +17,12 @@ struct nv50_screen { struct nouveau_notifier *sync; struct nouveau_bo *constbuf_misc[1]; - struct nouveau_bo *constbuf_parm[2]; + struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES]; struct nouveau_resource *immd_heap[1]; - struct nouveau_resource *parm_heap[2]; + struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES]; + + struct pipe_buffer *strm_vbuf[16]; struct nouveau_bo *tic; struct nouveau_bo *tsc; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index f19a21d5cc..7c531b50a5 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -22,7 +22,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi/tgsi_parse.h" @@ -31,6 +31,23 @@ #include "nouveau/nouveau_stateobj.h" +static INLINE uint32_t +nv50_colormask(unsigned mask) +{ + uint32_t cmask = 0; + + if (mask & PIPE_MASK_R) + cmask |= 0x0001; + if (mask & PIPE_MASK_G) + cmask |= 0x0010; + if (mask & PIPE_MASK_B) + cmask |= 0x0100; + if (mask & PIPE_MASK_A) + cmask |= 0x1000; + + return cmask; +} + static void * nv50_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) @@ -38,28 +55,37 @@ nv50_blend_state_create(struct pipe_context *pipe, struct nouveau_stateobj *so = so_new(5, 24, 0); struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj); - unsigned cmask = 0, i; + unsigned i, blend_enabled = 0; /*XXX ignored: * - dither */ - if (cso->blend_enable == 0) { - so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + if (cso->independent_blend_enable) { + for (i = 0; i < 8; ++i) { + so_data(so, cso->rt[i].blend_enable); + if (cso->rt[i].blend_enable) + blend_enabled = 1; + } + } else + if (cso->rt[0].blend_enable) { + blend_enabled = 1; for (i = 0; i < 8; i++) - so_data(so, 0); + so_data(so, 1); } else { - so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); for (i = 0; i < 8; i++) - so_data(so, 1); + so_data(so, 0); + } + if (blend_enabled) { so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5); - so_data (so, nvgl_blend_eqn(cso->rgb_func)); - so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_dst_factor)); - so_data (so, nvgl_blend_eqn(cso->alpha_func)); - so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_src_factor)); + so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_dst_factor)); + so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_src_factor)); so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); - so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_dst_factor)); } if (cso->logicop_enable == 0 ) { @@ -71,17 +97,15 @@ nv50_blend_state_create(struct pipe_context *pipe, so_data (so, nvgl_logicop_func(cso->logicop_func)); } - if (cso->colormask & PIPE_MASK_R) - cmask |= (1 << 0); - if (cso->colormask & PIPE_MASK_G) - cmask |= (1 << 4); - if (cso->colormask & PIPE_MASK_B) - cmask |= (1 << 8); - if (cso->colormask & PIPE_MASK_A) - cmask |= (1 << 12); so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8); - for (i = 0; i < 8; i++) - so_data(so, cmask); + if (cso->independent_blend_enable) + for (i = 0; i < 8; ++i) + so_data(so, nv50_colormask(cso->rt[i].colormask)); + else { + uint32_t cmask = nv50_colormask(cso->rt[0].colormask); + for (i = 0; i < 8; i++) + so_data(so, cmask); + } bso->pipe = *cso; so_ref(so, &bso->so); @@ -531,7 +555,7 @@ nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv50_program *p = hwcso; nv50_program_destroy(nv50, p); - FREE((void*)p->pipe.tokens); + FREE((void *)p->pipe.tokens); FREE(p); } @@ -563,7 +587,39 @@ nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv50_program *p = hwcso; nv50_program_destroy(nv50, p); - FREE((void*)p->pipe.tokens); + FREE((void *)p->pipe.tokens); + FREE(p); +} + +static void * +nv50_gp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv50_program *p = CALLOC_STRUCT(nv50_program); + + p->pipe.tokens = tgsi_dup_tokens(cso->tokens); + p->type = PIPE_SHADER_GEOMETRY; + tgsi_scan_shader(p->pipe.tokens, &p->info); + return (void *)p; +} + +static void +nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->fragprog = hwcso; + nv50->dirty |= NV50_NEW_GEOMPROG; +} + +static void +nv50_gp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_program *p = hwcso; + + nv50_program_destroy(nv50, p); + FREE((void *)p->pipe.tokens); FREE(p); } @@ -585,17 +641,21 @@ nv50_set_clip_state(struct pipe_context *pipe, static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf ) + struct pipe_buffer *buf ) { struct nv50_context *nv50 = nv50_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv50->constbuf[PIPE_SHADER_VERTEX] = buf; nv50->dirty |= NV50_NEW_VERTPROG_CB; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf; nv50->dirty |= NV50_NEW_FRAGPROG_CB; + } else + if (shader == PIPE_SHADER_GEOMETRY) { + nv50->constbuf[PIPE_SHADER_GEOMETRY] = buf; + nv50->dirty |= NV50_NEW_GEOMPROG_CB; } } @@ -696,6 +756,10 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.bind_fs_state = nv50_fp_state_bind; nv50->pipe.delete_fs_state = nv50_fp_state_delete; + nv50->pipe.create_gs_state = nv50_gp_state_create; + nv50->pipe.bind_gs_state = nv50_gp_state_bind; + nv50->pipe.delete_gs_state = nv50_gp_state_delete; + nv50->pipe.set_blend_color = nv50_set_blend_color; nv50->pipe.set_clip_state = nv50_set_clip_state; nv50->pipe.set_constant_buffer = nv50_set_constant_buffer; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index f83232f43c..ee28fa63c1 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -185,10 +185,10 @@ nv50_state_emit(struct nv50_context *nv50) struct nv50_screen *screen = nv50->screen; struct nouveau_channel *chan = screen->base.channel; - /* I don't want to copy headers from the winsys. */ - screen->cur_ctx = nv50; - - if (nv50->pctx_id != screen->cur_pctx) { + /* XXX: this is racy for multiple contexts active on separate + * threads. + */ + if (screen->cur_ctx != nv50) { if (nv50->state.fb) nv50->state.dirty |= NV50_NEW_FRAMEBUFFER; if (nv50->state.blend) @@ -199,6 +199,8 @@ nv50_state_emit(struct nv50_context *nv50) nv50->state.dirty |= NV50_NEW_VERTPROG; if (nv50->state.fragprog) nv50->state.dirty |= NV50_NEW_FRAGPROG; + if (nv50->state.geomprog) + nv50->state.dirty |= NV50_NEW_GEOMPROG; if (nv50->state.rast) nv50->state.dirty |= NV50_NEW_RASTERIZER; if (nv50->state.blend_colour) @@ -215,7 +217,7 @@ nv50_state_emit(struct nv50_context *nv50) nv50->state.dirty |= NV50_NEW_TEXTURE; if (nv50->state.vtxfmt && nv50->state.vtxbuf) nv50->state.dirty |= NV50_NEW_ARRAYS; - screen->cur_pctx = nv50->pctx_id; + screen->cur_ctx = nv50; } if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER) @@ -228,9 +230,14 @@ nv50_state_emit(struct nv50_context *nv50) so_emit(chan, nv50->state.vertprog); if (nv50->state.dirty & NV50_NEW_FRAGPROG) so_emit(chan, nv50->state.fragprog); + if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog) + so_emit(chan, nv50->state.geomprog); if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | - NV50_NEW_RASTERIZER)) - so_emit(chan, nv50->state.programs); + NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER)) + so_emit(chan, nv50->state.fp_linkage); + if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG)) + && nv50->state.gp_linkage) + so_emit(chan, nv50->state.gp_linkage); if (nv50->state.dirty & NV50_NEW_RASTERIZER) so_emit(chan, nv50->state.rast); if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR) @@ -267,6 +274,9 @@ nv50_state_flush_notify(struct nouveau_channel *chan) so_emit_reloc_markers(chan, nv50->state.fragprog); so_emit_reloc_markers(chan, nv50->state.vtxbuf); so_emit_reloc_markers(chan, nv50->screen->static_init); + + if (nv50->state.instbuf) + so_emit_reloc_markers(chan, nv50->state.instbuf); } boolean @@ -291,9 +301,15 @@ nv50_state_validate(struct nv50_context *nv50) if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB)) nv50_fragprog_validate(nv50); + if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB)) + nv50_geomprog_validate(nv50); + if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG | - NV50_NEW_RASTERIZER)) - nv50_linkage_validate(nv50); + NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER)) + nv50_fp_linkage_validate(nv50); + + if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG)) + nv50_gp_linkage_validate(nv50); if (nv50->dirty & NV50_NEW_RASTERIZER) so_ref(nv50->rasterizer->so, &nv50->state.rast); @@ -400,8 +416,9 @@ viewport_uptodate: for (i = 0; i < PIPE_SHADER_TYPES; ++i) nr += nv50->sampler_nr[i]; - so = so_new(1+ 5 * PIPE_SHADER_TYPES, 1+ 19 * PIPE_SHADER_TYPES - + nr * 8, PIPE_SHADER_TYPES * 2); + so = so_new(1 + 5 * PIPE_SHADER_TYPES, + 1 + 19 * PIPE_SHADER_TYPES + nr * 8, + PIPE_SHADER_TYPES * 2); nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX); nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 6378132979..ac0c1d0270 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -25,8 +25,8 @@ #include "nouveau/nouveau_pushbuf.h" #include "nv50_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" #include "util/u_tile.h" diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index bef548b728..9f1a171303 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -155,7 +155,7 @@ static boolean nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so, unsigned p) { - static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2 }; + static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 }; struct nouveau_grobj *eng2d = nv50->screen->eng2d; struct nouveau_grobj *tesla = nv50->screen->tesla; @@ -220,11 +220,8 @@ nv50_tex_validate(struct nv50_context *nv50) return; } - /* not sure if the following really do what I think: */ so_method(so, tesla, 0x1330, 1); /* flush TIC */ so_data (so, 0); - so_method(so, tesla, 0x1338, 1); /* flush texture caches */ - so_data (so, 0x20); so_ref(so, &nv50->state.tic_upload); so_ref(NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index a2f1db2914..d08b4d7354 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -1,6 +1,6 @@ #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index f2e510fba6..ca2f8061f3 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -22,7 +22,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" @@ -40,6 +40,8 @@ nv50_push_elements_u32(struct nv50_context *, uint32_t *, unsigned); static boolean nv50_push_arrays(struct nv50_context *, unsigned, unsigned); +#define NV50_USING_LOATHED_EDGEFLAG(ctx) ((ctx)->vertprog->cfg.edgeflag_in < 16) + static INLINE unsigned nv50_prim(unsigned mode) { @@ -55,6 +57,14 @@ nv50_prim(unsigned mode) case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS; case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP; case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON; + case PIPE_PRIM_LINES_ADJACENCY: + return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY; + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY; + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY; default: break; } @@ -152,6 +162,309 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve) return (hw_type | hw_size); } +/* For instanced drawing from user buffers, hitting the FIFO repeatedly + * with the same vertex data is probably worse than uploading all data. + */ +static boolean +nv50_upload_vtxbuf(struct nv50_context *nv50, unsigned i) +{ + struct nv50_screen *nscreen = nv50->screen; + struct pipe_screen *pscreen = &nscreen->base.base; + struct pipe_buffer *buf = nscreen->strm_vbuf[i]; + struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; + uint8_t *src; + unsigned size = align(vb->buffer->size, 4096); + + if (buf && buf->size < size) + pipe_buffer_reference(&nscreen->strm_vbuf[i], NULL); + + if (!nscreen->strm_vbuf[i]) { + nscreen->strm_vbuf[i] = pipe_buffer_create( + pscreen, 0, PIPE_BUFFER_USAGE_VERTEX, size); + buf = nscreen->strm_vbuf[i]; + } + + src = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + if (!src) + return FALSE; + src += vb->buffer_offset; + + size = (vb->max_index + 1) * vb->stride + 16; /* + 16 is for stride 0 */ + if (vb->buffer_offset + size > vb->buffer->size) + size = vb->buffer->size - vb->buffer_offset; + + pipe_buffer_write(pscreen, buf, vb->buffer_offset, size, src); + pipe_buffer_unmap(pscreen, vb->buffer); + + vb->buffer = buf; /* don't pipe_reference, this is a private copy */ + return TRUE; +} + +static void +nv50_upload_user_vbufs(struct nv50_context *nv50) +{ + unsigned i; + + if (nv50->vbo_fifo) + nv50->dirty |= NV50_NEW_ARRAYS; + if (!(nv50->dirty & NV50_NEW_ARRAYS)) + return; + + for (i = 0; i < nv50->vtxbuf_nr; ++i) { + if (nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX) + continue; + nv50_upload_vtxbuf(nv50, i); + } +} + +static void +nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + float v[4]; + + util_format_read_4f(nv50->vtxelt[i].src_format, + v, 0, data, 0, 0, 0, 1, 1); + + switch (nv50->vtxelt[i].nr_components) { + case 4: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + OUT_RINGf (chan, v[3]); + break; + case 3: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_3F_X(i), 3); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + break; + case 2: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_2F_X(i), 2); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + break; + case 1: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_1F(i), 1); + OUT_RINGf (chan, v[0]); + break; + default: + assert(0); + break; + } +} + +static unsigned +init_per_instance_arrays_immd(struct nv50_context *nv50, + unsigned startInstance, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_bo *bo; + unsigned i, b, count = 0; + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + ++count; + b = nv50->vtxelt[i].vertex_buffer_index; + + pos[i] = nv50->vtxelt[i].src_offset + + nv50->vtxbuf[b].buffer_offset + + startInstance * nv50->vtxbuf[b].stride; + step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + if (!bo->map) + nouveau_bo_map(bo, NOUVEAU_BO_RD); + + nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]); + } + + return count; +} + +static unsigned +init_per_instance_arrays(struct nv50_context *nv50, + unsigned startInstance, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct nouveau_bo *bo; + struct nouveau_stateobj *so; + unsigned i, b, count = 0; + const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + if (nv50->vbo_fifo) + return init_per_instance_arrays_immd(nv50, startInstance, + pos, step); + + so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + ++count; + b = nv50->vtxelt[i].vertex_buffer_index; + + pos[i] = nv50->vtxelt[i].src_offset + + nv50->vtxbuf[b].buffer_offset + + startInstance * nv50->vtxbuf[b].stride; + + if (!startInstance) { + step[i] = 0; + continue; + } + step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0); + } + + if (count && startInstance) { + so_ref (so, &nv50->state.instbuf); /* for flush notify */ + so_emit(chan, nv50->state.instbuf); + } + so_ref (NULL, &so); + + return count; +} + +static void +step_per_instance_arrays_immd(struct nv50_context *nv50, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_bo *bo; + unsigned i, b; + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + if (++step[i] != nv50->vtxelt[i].instance_divisor) + continue; + b = nv50->vtxelt[i].vertex_buffer_index; + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + step[i] = 0; + pos[i] += nv50->vtxbuf[b].stride; + + nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]); + } +} + +static void +step_per_instance_arrays(struct nv50_context *nv50, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct nouveau_bo *bo; + struct nouveau_stateobj *so; + unsigned i, b; + const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + if (nv50->vbo_fifo) { + step_per_instance_arrays_immd(nv50, pos, step); + return; + } + + so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + b = nv50->vtxelt[i].vertex_buffer_index; + + if (++step[i] == nv50->vtxelt[i].instance_divisor) { + step[i] = 0; + pos[i] += nv50->vtxbuf[b].stride; + } + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0); + } + + so_ref (so, &nv50->state.instbuf); /* for flush notify */ + so_ref (NULL, &so); + + so_emit(chan, nv50->state.instbuf); +} + +static INLINE void +nv50_unmap_vbufs(struct nv50_context *nv50) +{ + unsigned i; + + for (i = 0; i < nv50->vtxbuf_nr; ++i) + if (nouveau_bo(nv50->vtxbuf[i].buffer)->map) + nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer)); +} + +void +nv50_draw_arrays_instanced(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count, + unsigned startInstance, unsigned instanceCount) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->tesla->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + unsigned i, nz_divisors; + unsigned step[16], pos[16]; + + if (!NV50_USING_LOATHED_EDGEFLAG(nv50)) + nv50_upload_user_vbufs(nv50); + + nv50_state_validate(nv50); + + nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); + OUT_RING (chan, NV50_CB_AUX | (24 << 8)); + OUT_RING (chan, startInstance); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); + + if (nv50->vbo_fifo) + nv50_push_arrays(nv50, start, count); + else { + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + } + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + + for (i = 1; i < instanceCount; i++) { + if (nz_divisors) /* any non-zero array divisors ? */ + step_per_instance_arrays(nv50, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode) | (1 << 28)); + + if (nv50->vbo_fifo) + nv50_push_arrays(nv50, start, count); + else { + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + } + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + } + nv50_unmap_vbufs(nv50); + + so_ref(NULL, &nv50->state.instbuf); +} + void nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -182,6 +495,8 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); + nv50_unmap_vbufs(nv50); + /* XXX: not sure what to do if ret != TRUE: flush and retry? */ assert(ret); @@ -210,7 +525,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1); for (i = 0; i < nr; i += 2) OUT_RING (chan, (map[i + 1] << 16) | map[i]); @@ -243,7 +558,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1); for (i = 0; i < nr; i += 2) OUT_RING (chan, (map[i + 1] << 16) | map[i]); @@ -268,7 +583,7 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x40000000, nr); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr); OUT_RINGp (chan, map, nr); count -= nr; @@ -277,6 +592,77 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, return TRUE; } +static INLINE void +nv50_draw_elements_inline(struct nv50_context *nv50, + void *map, unsigned indexSize, + unsigned start, unsigned count) +{ + switch (indexSize) { + case 1: + nv50_draw_elements_inline_u08(nv50, map, start, count); + break; + case 2: + nv50_draw_elements_inline_u16(nv50, map, start, count); + break; + case 4: + nv50_draw_elements_inline_u32(nv50, map, start, count); + break; + } +} + +void +nv50_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count, + unsigned startInstance, unsigned instanceCount) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct pipe_screen *pscreen = pipe->screen; + void *map; + unsigned i, nz_divisors; + unsigned step[16], pos[16]; + + map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); + + if (!NV50_USING_LOATHED_EDGEFLAG(nv50)) + nv50_upload_user_vbufs(nv50); + + nv50_state_validate(nv50); + + nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); + OUT_RING (chan, NV50_CB_AUX | (24 << 8)); + OUT_RING (chan, startInstance); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + + for (i = 1; i < instanceCount; ++i) { + if (nz_divisors) /* any non-zero array divisors ? */ + step_per_instance_arrays(nv50, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode) | (1 << 28)); + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + } + nv50_unmap_vbufs(nv50); + + so_ref(NULL, &nv50->state.instbuf); +} + void nv50_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, @@ -287,7 +673,6 @@ nv50_draw_elements(struct pipe_context *pipe, struct nouveau_grobj *tesla = nv50->screen->tesla; struct pipe_screen *pscreen = pipe->screen; void *map; - boolean ret; map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); @@ -300,29 +685,15 @@ nv50_draw_elements(struct pipe_context *pipe, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (chan, nv50_prim(mode)); - switch (indexSize) { - case 1: - ret = nv50_draw_elements_inline_u08(nv50, map, start, count); - break; - case 2: - ret = nv50_draw_elements_inline_u16(nv50, map, start, count); - break; - case 4: - ret = nv50_draw_elements_inline_u32(nv50, map, start, count); - break; - default: - assert(0); - ret = FALSE; - break; - } + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); + nv50_unmap_vbufs(nv50); + pipe_buffer_unmap(pscreen, indexBuffer); - - /* XXX: what to do if ret != TRUE? Flush and retry? - */ - assert(ret); } static INLINE boolean @@ -335,23 +706,16 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, struct nouveau_stateobj *so; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_bo *bo = nouveau_bo(vb->buffer); - float *v; + float v[4]; int ret; - enum pipe_format pf = ve->src_format; - const struct util_format_description *desc; - - desc = util_format_description(pf); - assert(desc); - - if ((desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT) || - util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0) != 32) - return FALSE; ret = nouveau_bo_map(bo, NOUVEAU_BO_RD); if (ret) return FALSE; - v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset)); + util_format_read_4f(ve->src_format, v, 0, (uint8_t *)bo->map + + (vb->buffer_offset + ve->src_offset), 0, + 0, 0, 1, 1); so = *pso; if (!so) *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0); @@ -409,7 +773,7 @@ nv50_vbo_validate(struct nv50_context *nv50) !(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)) nv50->vbo_fifo = 0xffff; - if (nv50->vertprog->cfg.edgeflag_in < 16) + if (NV50_USING_LOATHED_EDGEFLAG(nv50)) nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */ n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr); @@ -437,17 +801,20 @@ nv50_vbo_validate(struct nv50_context *nv50) nv50->vbo_fifo &= ~(1 << i); continue; } - so_data(vtxfmt, hw | i); if (nv50->vbo_fifo) { + so_data (vtxfmt, hw | + (ve->instance_divisor ? (1 << 4) : i)); so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); so_data (vtxbuf, 0); continue; } + so_data(vtxfmt, hw | i); so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3); - so_data (vtxbuf, 0x20000000 | vb->stride); + so_data (vtxbuf, 0x20000000 | + (ve->instance_divisor ? 0 : vb->stride)); so_reloc (vtxbuf, bo, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); @@ -485,7 +852,7 @@ typedef void (*pfn_push)(struct nouveau_channel *, void *); struct nv50_vbo_emitctx { pfn_push push[16]; - void *map[16]; + uint8_t *map[16]; unsigned stride[16]; unsigned nr_ve; unsigned vtx_dwords; @@ -523,19 +890,18 @@ nv50_map_vbufs(struct nv50_context *nv50) for (i = 0; i < nv50->vtxbuf_nr; ++i) { struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; - unsigned size, delta; + unsigned size = vb->stride * (vb->max_index + 1) + 16; if (nouveau_bo(vb->buffer)->map) continue; - size = vb->stride * (vb->max_index + 1); - delta = vb->buffer_offset; - + size = vb->stride * (vb->max_index + 1) + 16; + size = MIN2(size, vb->buffer->size); if (!size) - size = vb->buffer->size - vb->buffer_offset; + size = vb->buffer->size; if (nouveau_bo_map_range(nouveau_bo(vb->buffer), - delta, size, NOUVEAU_BO_RD)) + 0, size, NOUVEAU_BO_RD)) break; } @@ -546,16 +912,6 @@ nv50_map_vbufs(struct nv50_context *nv50) return FALSE; } -static INLINE void -nv50_unmap_vbufs(struct nv50_context *nv50) -{ - unsigned i; - - for (i = 0; i < nv50->vtxbuf_nr; ++i) - if (nouveau_bo(nv50->vtxbuf[i].buffer)->map) - nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer)); -} - static void emit_b32_1(struct nouveau_channel *chan, void *data) { @@ -650,12 +1006,13 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit, ve = &nv50->vtxelt[i]; vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - if (!(nv50->vbo_fifo & (1 << i))) + if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor) continue; n = emit->nr_ve++; emit->stride[n] = vb->stride; - emit->map[n] = nouveau_bo(vb->buffer)->map + + emit->map[n] = (uint8_t *)nouveau_bo(vb->buffer)->map + + vb->buffer_offset + (start * vb->stride + ve->src_offset); desc = util_format_description(ve->src_format); @@ -745,13 +1102,12 @@ nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count) set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */ - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx_next(chan, &emit); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -772,13 +1128,12 @@ nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -799,13 +1154,12 @@ nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -826,13 +1180,12 @@ nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index c14414fff6..cdedb30220 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -23,8 +23,6 @@ #include "r300_blit.h" #include "r300_context.h" -#include "util/u_rect.h" - static void r300_blitter_save_states(struct r300_context* r300) { util_blitter_save_blend(r300->blitter, r300->blend_state.state); @@ -75,13 +73,15 @@ void r300_clear(struct pipe_context* pipe, */ struct r300_context* r300 = r300_context(pipe); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; r300_blitter_save_states(r300); util_blitter_clear(r300->blitter, - r300->framebuffer_state.width, - r300->framebuffer_state.height, - r300->framebuffer_state.nr_cbufs, + fb->width, + fb->height, + fb->nr_cbufs, buffers, rgba, depth, stencil); } @@ -99,7 +99,7 @@ void r300_surface_copy(struct pipe_context* pipe, * is really transparent. The states will be restored by the blitter once * copying is done. */ r300_blitter_save_states(r300); - util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_save_fragment_sampler_states( r300->blitter, r300->sampler_count, (void**)r300->sampler_states); @@ -123,7 +123,7 @@ void r300_surface_fill(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); r300_blitter_save_states(r300); - util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_fill(r300->blitter, dst, dstx, dsty, width, height, value); diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 51fdb82ff3..92de297ef1 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -33,6 +33,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) /* Reasonable defaults */ caps->num_vert_fpus = 4; caps->has_tcl = debug_get_bool_option("RADEON_NO_TCL", FALSE) ? FALSE : TRUE; + caps->is_r400 = FALSE; caps->is_r500 = FALSE; caps->high_second_pipe = FALSE; @@ -123,6 +124,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x4A54: caps->family = CHIP_FAMILY_R420; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x5548: @@ -136,6 +138,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5D57: caps->family = CHIP_FAMILY_R423; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x554C: @@ -147,6 +150,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5D4A: caps->family = CHIP_FAMILY_R430; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x5D4C: @@ -157,6 +161,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5D52: caps->family = CHIP_FAMILY_R480; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x4B48: @@ -166,6 +171,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x4B4C: caps->family = CHIP_FAMILY_R481; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x5E4C: @@ -182,6 +188,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5E4D: caps->family = CHIP_FAMILY_RV410; caps->num_vert_fpus = 6; + caps->is_r400 = TRUE; break; case 0x5954: @@ -212,6 +219,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x791F: caps->family = CHIP_FAMILY_RS690; caps->has_tcl = FALSE; + caps->is_r400 = TRUE; break; case 0x793F: @@ -219,6 +227,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x7942: caps->family = CHIP_FAMILY_RS600; caps->has_tcl = FALSE; + caps->is_r400 = TRUE; break; case 0x796C: @@ -227,6 +236,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x796F: caps->family = CHIP_FAMILY_RS740; caps->has_tcl = FALSE; + caps->is_r400 = TRUE; break; case 0x7100: diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index 0633a8b8a7..2808486492 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -40,11 +40,18 @@ struct r300_capabilities { unsigned num_z_pipes; /* Whether or not TCL is physically present */ boolean has_tcl; + /* Whether or not this is R400. The differences compared to their R3xx + * cousins are: + * - Extended fragment shader registers + * - Blend LTE/GTE thresholds */ + boolean is_r400; /* Whether or not this is an RV515 or newer; R500s have many differences * that require extra consideration, compared to their R3xx cousins: * - Extra bit of width and height on texture sizes * - Blend color is split across two registers - * - Universal Shader (US) block used for fragment shaders */ + * - Blend LTE/GTE thresholds + * - Universal Shader (US) block used for fragment shaders + * - FP16 blending and multisampling */ boolean is_r500; /* Whether or not the second pixel pipe is accessed with the high bit */ boolean high_second_pipe; diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index af95bbe789..14820ca854 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -22,9 +22,6 @@ #include "draw/draw_context.h" -#include "tgsi/tgsi_scan.h" - -#include "util/u_hash_table.h" #include "util/u_memory.h" #include "util/u_simple_list.h" @@ -35,30 +32,16 @@ #include "r300_query.h" #include "r300_render.h" #include "r300_screen.h" -#include "r300_state_derived.h" #include "r300_state_invariant.h" #include "r300_texture.h" #include "r300_winsys.h" -static enum pipe_error r300_clear_hash_table(void* key, void* value, - void* data) -{ - FREE(key); - FREE(value); - return PIPE_OK; -} - static void r300_destroy_context(struct pipe_context* context) { struct r300_context* r300 = r300_context(context); struct r300_query* query, * temp; util_blitter_destroy(r300->blitter); - - util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table, - NULL); - util_hash_table_destroy(r300->shader_hash_table); - draw_destroy(r300->draw); /* Free the OQ BO. */ @@ -72,9 +55,10 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); - FREE(r300->rs_block); + FREE(r300->fb_state.state); + FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); - FREE(r300->vertex_info); + FREE(r300->vertex_format_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); FREE(r300); @@ -87,7 +71,7 @@ r300_is_texture_referenced(struct pipe_context *pipe, { struct pipe_buffer* buf = 0; - r300_get_texture_buffer(texture, &buf, NULL); + r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); return pipe->is_buffer_referenced(pipe, buf); } @@ -110,30 +94,48 @@ static void r300_flush_cb(void *data) cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL); } -#define R300_INIT_ATOM(name) \ - r300->name##_state.state = NULL; \ - r300->name##_state.emit = r300_emit_##name##_state; \ - r300->name##_state.dirty = FALSE; \ - insert_at_tail(&r300->atom_list, &r300->name##_state); +#define R300_INIT_ATOM(atomname, atomsize) \ + r300->atomname##_state.name = #atomname; \ + r300->atomname##_state.state = NULL; \ + r300->atomname##_state.size = atomsize; \ + r300->atomname##_state.emit = r300_emit_##atomname##_state; \ + r300->atomname##_state.dirty = FALSE; \ + insert_at_tail(&r300->atom_list, &r300->atomname##_state); static void r300_setup_atoms(struct r300_context* r300) { + /* Create the actual atom list. + * + * Each atom is examined and emitted in the order it appears here, which + * can affect performance and conformance if not handled with care. + * + * Some atoms never change size, others change every emit. This is just + * an upper bound on each atom, to keep the emission machinery from + * underallocating space. */ make_empty_list(&r300->atom_list); - R300_INIT_ATOM(ztop); - R300_INIT_ATOM(blend); - R300_INIT_ATOM(blend_color); - R300_INIT_ATOM(clip); - R300_INIT_ATOM(dsa); - R300_INIT_ATOM(rs); - R300_INIT_ATOM(scissor); - R300_INIT_ATOM(viewport); + R300_INIT_ATOM(invariant, 71); + R300_INIT_ATOM(ztop, 2); + R300_INIT_ATOM(blend, 8); + R300_INIT_ATOM(blend_color, 3); + R300_INIT_ATOM(clip, 29); + R300_INIT_ATOM(dsa, 8); + R300_INIT_ATOM(fb, 56); + R300_INIT_ATOM(rs, 25); + R300_INIT_ATOM(scissor, 3); + R300_INIT_ATOM(viewport, 9); + R300_INIT_ATOM(rs_block, 21); + R300_INIT_ATOM(vertex_format, 26); + + /* Some non-CSO atoms need explicit space to store the state locally. */ + r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); } struct pipe_context* r300_create_context(struct pipe_screen* screen, - struct radeon_winsys* radeon_winsys) + void *priv) { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); + struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys; if (!r300) return NULL; @@ -142,8 +144,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.winsys = (struct pipe_winsys*)radeon_winsys; r300->context.screen = screen; - - r300_init_debug(r300); + r300->context.priv = priv; r300->context.destroy = r300_destroy_context; @@ -174,16 +175,13 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.is_texture_referenced = r300_is_texture_referenced; r300->context.is_buffer_referenced = r300_is_buffer_referenced; - r300->shader_hash_table = util_hash_table_create(r300_shader_key_hash, - r300_shader_key_compare); - r300_setup_atoms(r300); r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state); - r300->rs_block = CALLOC_STRUCT(r300_rs_block); - r300->scissor_state.state = CALLOC_STRUCT(r300_scissor_state); - r300->vertex_info = CALLOC_STRUCT(r300_vertex_info); + r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); + r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); + r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); @@ -200,7 +198,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300_init_state_functions(r300); - r300_emit_invariant_state(r300); + r300->invariant_state.dirty = TRUE; r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 5937f0e2cc..8461757812 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -28,7 +28,9 @@ #include "util/u_blitter.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" + +#include "r300_screen.h" struct r300_context; @@ -36,10 +38,20 @@ struct r300_fragment_shader; struct r300_vertex_shader; struct r300_atom { + /* List pointers. */ struct r300_atom *prev, *next; + /* Name, for debugging. */ + const char* name; + /* Opaque state. */ void* state; + /* Emit the state to the context. */ void (*emit)(struct r300_context*, void*); + /* Upper bound on number of dwords to emit. */ + unsigned size; + /* Whether this atom should be emitted. */ boolean dirty; + /* Another dirty flag that is never automatically cleared. */ + boolean always_dirty; }; struct r300_blend_state { @@ -72,13 +84,14 @@ struct r300_rs_state { struct pipe_rasterizer_state rs; uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ + uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */ uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */ uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ - uint32_t depth_scale_front; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ - uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ - uint32_t depth_scale_back; /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ - uint32_t depth_offset_back; /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ + float depth_scale; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ + /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ + float depth_offset; /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ + /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */ uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ @@ -106,16 +119,6 @@ struct r300_sampler_state { unsigned min_lod, max_lod; }; -struct r300_scissor_regs { - uint32_t top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ - uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ -}; - -struct r300_scissor_state { - struct r300_scissor_regs framebuffer; - struct r300_scissor_regs scissor; -}; - struct r300_texture_state { uint32_t format0; /* R300_TX_FORMAT0: 0x4480 */ uint32_t format1; /* R300_TX_FORMAT1: 0x44c0 */ @@ -136,15 +139,12 @@ struct r300_ztop_state { uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */ }; -#define R300_NEW_FRAMEBUFFERS 0x00000010 #define R300_NEW_FRAGMENT_SHADER 0x00000020 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040 -#define R300_NEW_RS_BLOCK 0x00000100 #define R300_NEW_SAMPLER 0x00000200 #define R300_ANY_NEW_SAMPLERS 0x0001fe00 #define R300_NEW_TEXTURE 0x00040000 #define R300_ANY_NEW_TEXTURES 0x03fc0000 -#define R300_NEW_VERTEX_FORMAT 0x04000000 #define R300_NEW_VERTEX_SHADER 0x08000000 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 @@ -188,6 +188,12 @@ struct r300_query { struct r300_query* next; }; +enum r300_buffer_tiling { + R300_BUFFER_LINEAR = 0, + R300_BUFFER_TILED, + R300_BUFFER_SQUARETILED +}; + struct r300_texture { /* Parent class */ struct pipe_texture tex; @@ -224,6 +230,9 @@ struct r300_texture { /* Registers carrying texture format data. */ struct r300_texture_state state; + + /* Buffer tiling */ + enum r300_buffer_tiling microtile, macrotile; }; struct r300_vertex_info { @@ -260,11 +269,8 @@ struct r300_context { struct r300_query *query_current; struct r300_query query_list; - /* Shader hash table. Used to store vertex formatting information, which - * depends on the combination of both currently loaded shaders. */ - struct util_hash_table* shader_hash_table; /* Vertex formatting information. */ - struct r300_vertex_info* vertex_info; + struct r300_atom vertex_format_state; /* Various CSO state objects. */ /* Beginning of atom list. */ @@ -281,12 +287,12 @@ struct r300_context { struct r300_atom dsa_state; /* Fragment shader. */ struct r300_fragment_shader* fs; - /* Framebuffer state. We currently don't need our own version of this. */ - struct pipe_framebuffer_state framebuffer_state; + /* Framebuffer state. */ + struct r300_atom fb_state; /* Rasterizer state. */ struct r300_atom rs_state; /* RS block state. */ - struct r300_rs_block* rs_block; + struct r300_atom rs_block_state; /* Sampler states. */ struct r300_sampler_state* sampler_states[8]; int sampler_count; @@ -302,6 +308,9 @@ struct r300_context { /* ZTOP state. */ struct r300_atom ztop_state; + /* Invariant state. This must be emitted to get the engine started. */ + struct r300_atom invariant_state; + /* Vertex buffers for Gallium. */ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; @@ -315,9 +324,10 @@ struct r300_context { uint32_t dirty_hw; /* Whether the TCL engine should be in bypass mode. */ boolean tcl_bypass; - - /** Combination of DBG_xxx flags */ - unsigned debug; + /* Whether polygon offset is enabled. */ + boolean polygon_offset_enabled; + /* Z buffer bit depth. */ + uint32_t zbuffer_bpp; }; /* Convenience cast wrapper. */ @@ -326,40 +336,24 @@ static INLINE struct r300_context* r300_context(struct pipe_context* context) return (struct r300_context*)context; } + +struct pipe_context* r300_create_context(struct pipe_screen* screen, + void *priv); + /* Context initialization. */ struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_surface_functions(struct r300_context* r300); -/* Debug functionality. */ - -/** - * Debug flags to disable/enable certain groups of debugging outputs. - * - * \note These may be rather coarse, and the grouping may be impractical. - * If you find, while debugging the driver, that a different grouping - * of these flags would be beneficial, just feel free to change them - * but make sure to update the documentation in r300_debug.c to reflect - * those changes. - */ -/*@{*/ -#define DBG_HELP 0x0000001 -#define DBG_FP 0x0000002 -#define DBG_VP 0x0000004 -#define DBG_CS 0x0000008 -#define DBG_DRAW 0x0000010 -#define DBG_TEX 0x0000020 -#define DBG_FALL 0x0000040 -/*@}*/ - -static INLINE boolean DBG_ON(struct r300_context * ctx, unsigned flags) +static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags) { - return (ctx->debug & flags) ? TRUE : FALSE; + return SCREEN_DBG_ON(r300_screen(ctx->context.screen), flags); } -static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * fmt, ...) +static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags, + const char * fmt, ...) { - if (DBG_ON(ctx, flags)) { + if (CTX_DBG_ON(ctx, flags)) { va_list va; va_start(va, fmt); debug_vprintf(fmt, va); @@ -367,6 +361,8 @@ static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * f } } -void r300_init_debug(struct r300_context * ctx); +#define DBG_ON CTX_DBG_ON +#define DBG CTX_DBG #endif /* R300_CONTEXT_H */ + diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index d142fee050..151f72b0fe 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -52,7 +52,7 @@ #define CS_LOCALS(context) \ struct r300_context* const cs_context_copy = (context); \ struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \ - int cs_count = 0; + int cs_count = 0; (void) cs_count; #define CHECK_CS(size) \ assert(cs_winsys->check_cs(cs_winsys, (size))) diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 2a6ed54ac9..b881730848 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,8 +22,6 @@ #include "r300_context.h" -#include <ctype.h> - struct debug_option { const char * name; @@ -46,7 +44,7 @@ static struct debug_option debug_options[] = { { 0, 0, 0 } }; -void r300_init_debug(struct r300_context * ctx) +void r300_init_debug(struct r300_screen * screen) { const char * options = debug_get_option("RADEON_DEBUG", 0); boolean printhint = FALSE; @@ -64,7 +62,7 @@ void r300_init_debug(struct r300_context * ctx) for(opt = debug_options; opt->name; ++opt) { if (!strncmp(options, opt->name, length)) { - ctx->debug |= opt->flag; + screen->debug |= opt->flag; break; } } @@ -77,11 +75,11 @@ void r300_init_debug(struct r300_context * ctx) options += length; } - if (!ctx->debug) + if (!screen->debug) printhint = TRUE; } - if (printhint || ctx->debug & DBG_HELP) { + if (printhint || screen->debug & DBG_HELP) { debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n" "to a comma-separated list of debug options. Available options are:\n"); for(opt = debug_options; opt->name; ++opt) { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 0e5533c790..ae83511a85 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,19 +32,20 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" -#include "r300_state_derived.h" #include "r300_state_inlines.h" -#include "r300_texture.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) { struct r300_blend_state* blend = (struct r300_blend_state*)state; + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); + BEGIN_CS(8); OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3); - if (r300->framebuffer_state.nr_cbufs) { + if (fb->nr_cbufs) { OUT_CS(blend->blend_control); OUT_CS(blend->alpha_blend_control); OUT_CS(blend->color_channel_mask); @@ -111,19 +112,15 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) { struct r300_dsa_state* dsa = (struct r300_dsa_state*)state; struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6); OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); - - /* not needed since we use the 8bit alpha ref */ - /*if (r300screen->caps->is_r500) { - OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference); - }*/ - OUT_CS_REG_SEQ(R300_ZB_CNTL, 3); - if (r300->framebuffer_state.zsbuf) { + if (fb->zsbuf) { OUT_CS(dsa->z_buffer_control); OUT_CS(dsa->z_stencil_control); } else { @@ -133,7 +130,6 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) OUT_CS(dsa->stencil_ref_mask); - /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */ if (r300screen->caps->is_r500) { OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); } @@ -167,9 +163,8 @@ static const float * get_shader_constant( vec[1] = 1.0 / tex->height0; break; - /* Texture compare-fail value. */ - /* XXX Since Gallium doesn't support GL_ARB_shadow_ambient, - * this is always (0,0,0,0), right? */ + /* Texture compare-fail value. Shouldn't ever show up, but if + * it does, we'll be ready. */ case RC_STATE_SHADOW_AMBIENT: vec[3] = 0; break; @@ -383,17 +378,14 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, END_CS; } -void r300_emit_fb_state(struct r300_context* r300, - struct pipe_framebuffer_state* fb) +void r300_emit_fb_state(struct r300_context* r300, void* state) { + struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_texture* tex; struct pipe_surface* surf; int i; CS_LOCALS(r300); - /* Shouldn't fail unless there is a bug in the state tracker. */ - assert(fb->nr_cbufs <= 4); - BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + (fb->zsbuf ? 10 : 0) + 6); @@ -406,7 +398,14 @@ void r300_emit_fb_state(struct r300_context* r300, R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); /* Set the number of colorbuffers. */ - OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs)); + if (fb->nr_cbufs > 1) { + OUT_CS_REG(R300_RB3D_CCTL, + R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) | + R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE | + R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE); + } else { + OUT_CS_REG(R300_RB3D_CCTL, 0x0); + } /* Set up colorbuffers. */ for (i = 0; i < fb->nr_cbufs; i++) { @@ -419,8 +418,10 @@ void r300_emit_fb_state(struct r300_context* r300, OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | - r300_translate_colorformat(tex->tex.format), 0, - RADEON_GEM_DOMAIN_VRAM, 0); + r300_translate_colorformat(tex->tex.format) | + R300_COLOR_TILE(tex->macrotile) | + R300_COLOR_MICROTILE(tex->microtile), + 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), r300_translate_out_fmt(surf->format)); @@ -443,8 +444,10 @@ void r300_emit_fb_state(struct r300_context* r300, OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format)); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level], 0, - RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | + R300_DEPTHMACROTILE(tex->macrotile) | + R300_DEPTHMICROTILE(tex->microtile), + 0, RADEON_GEM_DOMAIN_VRAM, 0); } END_CS; @@ -579,32 +582,52 @@ void r300_emit_query_end(struct r300_context* r300) void r300_emit_rs_state(struct r300_context* r300, void* state) { struct r300_rs_state* rs = (struct r300_rs_state*)state; + float scale, offset; CS_LOCALS(r300); - BEGIN_CS(22); + BEGIN_CS(18 + (rs->polygon_offset_enable ? 5 : 0)); OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); + + OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config); + OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size); OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2); OUT_CS(rs->point_minmax); OUT_CS(rs->line_control); - OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6); - OUT_CS(rs->depth_scale_front); - OUT_CS(rs->depth_offset_front); - OUT_CS(rs->depth_scale_back); - OUT_CS(rs->depth_offset_back); + + if (rs->polygon_offset_enable) { + scale = rs->depth_scale * 12; + offset = rs->depth_offset; + + switch (r300->zbuffer_bpp) { + case 16: + offset *= 4; + break; + case 24: + offset *= 2; + break; + } + + OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); + OUT_CS_32F(scale); + OUT_CS_32F(offset); + OUT_CS_32F(scale); + OUT_CS_32F(offset); + } + + OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2); OUT_CS(rs->polygon_offset_enable); OUT_CS(rs->cull_mode); OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config); OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value); - OUT_CS_REG(R300_GA_COLOR_CONTROL, rs->color_control); OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode); END_CS; } -void r300_emit_rs_block_state(struct r300_context* r300, - struct r300_rs_block* rs) +void r300_emit_rs_block_state(struct r300_context* r300, void* state) { - int i; + struct r300_rs_block* rs = (struct r300_rs_block*)state; + unsigned i; struct r300_screen* r300screen = r300_screen(r300->context.screen); CS_LOCALS(r300); @@ -641,27 +664,65 @@ void r300_emit_rs_block_state(struct r300_context* r300, END_CS; } -static void r300_emit_scissor_regs(struct r300_context* r300, - struct r300_scissor_regs* scissor) +void r300_emit_scissor_state(struct r300_context* r300, void* state) { + unsigned minx, miny, maxx, maxy; + uint32_t top_left, bottom_right; + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state; + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); - BEGIN_CS(3); - OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); - OUT_CS(scissor->top_left); - OUT_CS(scissor->bottom_right); - END_CS; -} + minx = miny = 0; + maxx = fb->width; + maxy = fb->height; -void r300_emit_scissor_state(struct r300_context* r300, void* state) -{ - struct r300_scissor_state* scissor = (struct r300_scissor_state*)state; - /* XXX argfl! */ if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) { - r300_emit_scissor_regs(r300, &scissor->scissor); + minx = MAX2(minx, scissor->minx); + miny = MAX2(miny, scissor->miny); + maxx = MIN2(maxx, scissor->maxx); + maxy = MIN2(maxy, scissor->maxy); + } + + /* Special case for zero-area scissor. + * + * We can't allow the variables maxx and maxy to be zero because they are + * subtracted from later in the code, which would cause emitting ~0 and + * making the kernel checker angry. + * + * Let's consider we change maxx and maxy to 1, which is effectively + * a one-pixel area. We must then change minx and miny to a number which is + * greater than 1 to get the zero area back. */ + if (!maxx || !maxy) { + minx = 2; + miny = 2; + maxx = 1; + maxy = 1; + } + + if (r300screen->caps->is_r500) { + top_left = + (minx << R300_SCISSORS_X_SHIFT) | + (miny << R300_SCISSORS_Y_SHIFT); + bottom_right = + ((maxx - 1) << R300_SCISSORS_X_SHIFT) | + ((maxy - 1) << R300_SCISSORS_Y_SHIFT); } else { - r300_emit_scissor_regs(r300, &scissor->framebuffer); + /* Offset of 1440 in non-R500 chipsets. */ + top_left = + ((minx + 1440) << R300_SCISSORS_X_SHIFT) | + ((miny + 1440) << R300_SCISSORS_Y_SHIFT); + bottom_right = + (((maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | + (((maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); } + + BEGIN_CS(3); + OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2); + OUT_CS(top_left); + OUT_CS(bottom_right); + END_CS; } void r300_emit_texture(struct r300_context* r300, @@ -680,12 +741,18 @@ void r300_emit_texture(struct r300_context* r300, filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } - /* determine min/max levels */ - /* the MAX_MIP level is the largest (finest) one */ - max_level = MIN2(sampler->max_lod, tex->tex.last_level); - min_level = MIN2(sampler->min_lod, max_level); - format0 |= R300_TX_NUM_LEVELS(max_level); - filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); + if (tex->is_npot) { + /* NPOT textures don't support mip filter, unfortunately. + * This prevents incorrect rendering. */ + filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; + } else { + /* determine min/max levels */ + /* the MAX_MIP level is the largest (finest) one */ + max_level = MIN2(sampler->max_lod, tex->tex.last_level); + min_level = MIN2(sampler->min_lod, max_level); + format0 |= R300_TX_NUM_LEVELS(max_level); + filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); + } BEGIN_CS(16); OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 | @@ -697,27 +764,13 @@ void r300_emit_texture(struct r300_context* r300, OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1); OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2); OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1); - OUT_CS_RELOC(tex->buffer, 0, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); + OUT_CS_RELOC(tex->buffer, + R300_TXO_MACRO_TILE(tex->macrotile) | + R300_TXO_MICRO_TILE(tex->microtile), + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); END_CS; } -static boolean r300_validate_aos(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; - int i; - - /* Check if formats and strides are aligned to the size of DWORD. */ - for (i = 0; i < r300->vertex_element_count; i++) { - if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || - util_format_get_blocksize(velem[i].src_format) % 4 != 0) { - return FALSE; - } - } - return TRUE; -} - void r300_emit_aos(struct r300_context* r300, unsigned offset) { struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; @@ -727,12 +780,6 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) unsigned packet_size = (aos_count * 3 + 1) / 2; CS_LOCALS(r300); - /* XXX Move this checking to a more approriate place. */ - if (!r300_validate_aos(r300)) { - /* XXX We should fallback using Draw. */ - assert(0); - } - BEGIN_CS(2 + packet_size + aos_count * 2); OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); OUT_CS(aos_count); @@ -764,64 +811,39 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } -#if 0 -void r300_emit_draw_packet(struct r300_context* r300) +void r300_emit_vertex_format_state(struct r300_context* r300, void* state) { - CS_LOCALS(r300); - - DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, " - "vertex size %d\n", r300->vbo, - r300->vertex_info->vinfo.size); - /* Set the pointer to our vertex buffer. The emitted values are this: - * PACKET3 [3D_LOAD_VBPNTR] - * COUNT [1] - * FORMAT [size | stride << 8] - * OFFSET [offset into BO] - * VBPNTR [relocated BO] - */ - BEGIN_CS(7); - OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); - OUT_CS(1); - OUT_CS(r300->vertex_info->vinfo.size | - (r300->vertex_info->vinfo.size << 8)); - OUT_CS(r300->vbo_offset); - OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); - END_CS; -} -#endif - -void r300_emit_vertex_format_state(struct r300_context* r300) -{ - int i; + struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state; + unsigned i; CS_LOCALS(r300); DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n"); BEGIN_CS(26); - OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size); + OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size); OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); - OUT_CS(r300->vertex_info->vinfo.hwfmt[0]); - OUT_CS(r300->vertex_info->vinfo.hwfmt[1]); + OUT_CS(vertex_info->vinfo.hwfmt[0]); + OUT_CS(vertex_info->vinfo.hwfmt[1]); OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_CS(r300->vertex_info->vinfo.hwfmt[2]); - OUT_CS(r300->vertex_info->vinfo.hwfmt[3]); + OUT_CS(vertex_info->vinfo.hwfmt[2]); + OUT_CS(vertex_info->vinfo.hwfmt[3]); for (i = 0; i < 4; i++) { DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i, - r300->vertex_info->vinfo.hwfmt[i]); + vertex_info->vinfo.hwfmt[i]); } OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8); for (i = 0; i < 8; i++) { - OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]); + OUT_CS(vertex_info->vap_prog_stream_cntl[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i, - r300->vertex_info->vap_prog_stream_cntl[i]); + vertex_info->vap_prog_stream_cntl[i]); } OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8); for (i = 0; i < 8; i++) { - OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]); + OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i, - r300->vertex_info->vap_prog_stream_cntl_ext[i]); + vertex_info->vap_prog_stream_cntl_ext[i]); } END_CS; } @@ -986,30 +1008,21 @@ static void r300_flush_pvs(struct r300_context* r300) END_CS; } -/* Emit all dirty state. */ -void r300_emit_dirty_state(struct r300_context* r300) +void r300_emit_buffer_validate(struct r300_context *r300) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_texture* tex; - struct r300_atom* atom; - int i, dirty_tex = 0; + unsigned i; boolean invalid = FALSE; - /* Check size of CS. */ - /* Make sure we have at least 8*1024 spare dwords. */ - /* XXX It would be nice to know the number of dwords we really need to - * XXX emit. */ - if (!r300->winsys->check_cs(r300->winsys, 8*1024)) { - r300->context.flush(&r300->context, 0, NULL); - } - /* Clean out BOs. */ r300->winsys->reset_bos(r300->winsys); validate: /* Color buffers... */ - for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { - tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture; + for (i = 0; i < fb->nr_cbufs; i++) { + tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, 0, RADEON_GEM_DOMAIN_VRAM)) { @@ -1018,8 +1031,8 @@ validate: } } /* ...depth buffer... */ - if (r300->framebuffer_state.zsbuf) { - tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture; + if (fb->zsbuf) { + tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, 0, RADEON_GEM_DOMAIN_VRAM)) { @@ -1039,10 +1052,12 @@ validate: } } /* ...occlusion query buffer... */ - if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { - r300->context.flush(&r300->context, 0, NULL); - goto validate; + if (r300->dirty_state & R300_NEW_QUERY) { + if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { + r300->context.flush(&r300->context, 0, NULL); + goto validate; + } } /* ...and vertex buffer. */ if (r300->vbo) { @@ -1064,6 +1079,31 @@ validate: invalid = TRUE; goto validate; } +} + +/* Emit all dirty state. */ +void r300_emit_dirty_state(struct r300_context* r300) +{ + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_atom* atom; + unsigned i, dwords = 1024; + int dirty_tex = 0; + + /* Check the required number of dwords against the space remaining in the + * current CS object. If we need more, then flush. */ + + foreach(atom, &r300->atom_list) { + if (atom->dirty || atom->always_dirty) { + dwords += atom->size; + } + } + + /* Make sure we have at least 2*1024 spare dwords. */ + /* XXX It would be nice to know the number of dwords we really need to + * XXX emit. */ + while (!r300->winsys->check_cs(r300->winsys, dwords)) { + r300->context.flush(&r300->context, 0, NULL); + } if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); @@ -1071,7 +1111,7 @@ validate: } foreach(atom, &r300->atom_list) { - if (atom->dirty) { + if (atom->dirty || atom->always_dirty) { atom->emit(r300, atom->state); atom->dirty = FALSE; } @@ -1098,16 +1138,6 @@ validate: r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; } - if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) { - r300_emit_fb_state(r300, &r300->framebuffer_state); - r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS; - } - - if (r300->dirty_state & R300_NEW_RS_BLOCK) { - r300_emit_rs_block_state(r300, r300->rs_block); - r300->dirty_state &= ~R300_NEW_RS_BLOCK; - } - /* Samplers and textures are tracked separately but emitted together. */ if (r300->dirty_state & (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) { @@ -1133,11 +1163,6 @@ validate: r300_flush_textures(r300); } - if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) { - r300_emit_vertex_format_state(r300); - r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT; - } - if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) { r300_flush_pvs(r300); } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 05a6bfeae8..6b96d9b57c 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -51,8 +51,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300, void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_fb_state(struct r300_context* r300, - struct pipe_framebuffer_state* fb); +void r300_emit_fb_state(struct r300_context* r300, void* state); void r300_emit_query_begin(struct r300_context* r300, struct r300_query* query); @@ -61,8 +60,7 @@ void r300_emit_query_end(struct r300_context* r300); void r300_emit_rs_state(struct r300_context* r300, void* state); -void r300_emit_rs_block_state(struct r300_context* r300, - struct r300_rs_block* rs); +void r300_emit_rs_block_state(struct r300_context* r300, void* state); void r300_emit_scissor_state(struct r300_context* r300, void* state); @@ -73,7 +71,7 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_buffer(struct r300_context* r300); -void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_format_state(struct r300_context* r300, void* state); void r300_emit_vertex_program_code(struct r300_context* r300, struct r300_vertex_program_code* code); @@ -95,4 +93,6 @@ void r300_flush_textures(struct r300_context* r300); /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); +void r300_emit_buffer_validate(struct r300_context *r300); + #endif /* R300_EMIT_H */ diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 14a08241fc..e37d309270 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -29,7 +29,6 @@ #include "r300_cs.h" #include "r300_emit.h" #include "r300_flush.h" -#include "r300_state_invariant.h" static void r300_flush(struct pipe_context* pipe, unsigned flags, @@ -37,8 +36,10 @@ static void r300_flush(struct pipe_context* pipe, { struct r300_context *r300 = r300_context(pipe); struct r300_query *query; + struct r300_atom *atom; CS_LOCALS(r300); + (void) cs_count; /* We probably need to flush Draw, but we may have been called from * within Draw. This feels kludgy, but it might be the best thing. * @@ -51,10 +52,17 @@ static void r300_flush(struct pipe_context* pipe, if (r300->dirty_hw) { FLUSH_CS; - r300_emit_invariant_state(r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw = 0; + + /* New kitchen sink, baby. */ + foreach(atom, &r300->atom_list) { + if (atom->state) { + atom->dirty = TRUE; + } + } } + /* reset flushed query */ foreach(query, &r300->query_list) { query->flushed = TRUE; diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index 60ea9c171d..75a05498eb 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -49,12 +49,12 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, switch (info->input_semantic_name[i]) { case TGSI_SEMANTIC_COLOR: - assert(index <= ATTR_COLOR_COUNT); + assert(index < ATTR_COLOR_COUNT); fs_inputs->color[index] = i; break; case TGSI_SEMANTIC_GENERIC: - assert(index <= ATTR_GENERIC_COUNT); + assert(index < ATTR_GENERIC_COUNT); fs_inputs->generic[index] = i; break; @@ -77,17 +77,21 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, static void find_output_registers(struct r300_fragment_program_compiler * compiler, struct r300_fragment_shader * fs) { - unsigned i; + unsigned i, colorbuf_count = 0; /* Mark the outputs as not present initially */ - compiler->OutputColor = fs->info.num_outputs; + compiler->OutputColor[0] = fs->info.num_outputs; + compiler->OutputColor[1] = fs->info.num_outputs; + compiler->OutputColor[2] = fs->info.num_outputs; + compiler->OutputColor[3] = fs->info.num_outputs; compiler->OutputDepth = fs->info.num_outputs; /* Now see where they really are. */ for(i = 0; i < fs->info.num_outputs; ++i) { switch(fs->info.output_semantic_name[i]) { case TGSI_SEMANTIC_COLOR: - compiler->OutputColor = i; + compiler->OutputColor[colorbuf_count] = i; + colorbuf_count++; break; case TGSI_SEMANTIC_POSITION: compiler->OutputDepth = i; diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 034bfc15cf..361813891f 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -1619,18 +1619,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_TX_OFFSET_5 0x4554 #define R300_TX_OFFSET_6 0x4558 #define R300_TX_OFFSET_7 0x455C - /* BEGIN: Guess from R200 */ + # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) # define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -# define R300_TXO_MACRO_TILE (1 << 2) +# define R300_TXO_MACRO_TILE_LINEAR (0 << 2) +# define R300_TXO_MACRO_TILE_TILED (1 << 2) +# define R300_TXO_MACRO_TILE(x) ((x) << 2) # define R300_TXO_MICRO_TILE_LINEAR (0 << 3) -# define R300_TXO_MICRO_TILE (1 << 3) -# define R300_TXO_MICRO_TILE_SQUARE (2 << 3) +# define R300_TXO_MICRO_TILE_TILED (1 << 3) +# define R300_TXO_MICRO_TILE_TILED_SQUARE (2 << 3) +# define R300_TXO_MICRO_TILE(x) ((x) << 3) # define R300_TXO_OFFSET_MASK 0xffffffe0 # define R300_TXO_OFFSET_SHIFT 5 - /* END: Guess from R200 */ /* 32 bit chroma key */ #define R300_TX_CHROMA_KEY_0 0x4580 @@ -2283,9 +2285,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_COLORPITCH_MASK 0x00003FFE # define R300_COLOR_TILE_DISABLE (0 << 16) # define R300_COLOR_TILE_ENABLE (1 << 16) +# define R300_COLOR_TILE(x) ((x) << 16) # define R300_COLOR_MICROTILE_DISABLE (0 << 17) # define R300_COLOR_MICROTILE_ENABLE (1 << 17) # define R300_COLOR_MICROTILE_ENABLE_SQUARE (2 << 17) /* Only available in 16-bit */ +# define R300_COLOR_MICROTILE(x) ((x) << 17) # define R300_COLOR_ENDIAN_NO_SWAP (0 << 19) # define R300_COLOR_ENDIAN_WORD_SWAP (1 << 19) # define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 19) @@ -2544,9 +2548,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_DEPTHPITCH_MASK 0x00003FFC # define R300_DEPTHMACROTILE_DISABLE (0 << 16) # define R300_DEPTHMACROTILE_ENABLE (1 << 16) +# define R300_DEPTHMACROTILE(x) ((x) << 16) # define R300_DEPTHMICROTILE_LINEAR (0 << 17) # define R300_DEPTHMICROTILE_TILED (1 << 17) # define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) +# define R300_DEPTHMICROTILE(x) ((x) << 17) # define R300_DEPTHENDIAN_NO_SWAP (0 << 18) # define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) # define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index ee43421cdb..cd4971ae13 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -26,8 +26,9 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" +#include "util/u_format.h" #include "util/u_memory.h" #include "util/u_prim.h" @@ -114,6 +115,97 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } +static boolean immd_is_good_idea(struct r300_context *r300, + unsigned count) +{ + return count <= 4; +} + +static void r300_emit_draw_arrays_immediate(struct r300_context *r300, + unsigned mode, + unsigned start, + unsigned count) +{ + struct pipe_vertex_element* velem; + struct pipe_vertex_buffer* vbuf; + unsigned vertex_element_count = r300->vertex_element_count; + unsigned i, v, vbi, dw, elem_offset; + + /* Size of the vertex, in dwords. */ + unsigned vertex_size = 0; + + /* Offsets of the attribute, in dwords, from the start of the vertex. */ + unsigned offset[PIPE_MAX_ATTRIBS]; + + /* Size of the vertex element, in dwords. */ + unsigned size[PIPE_MAX_ATTRIBS]; + + /* Stride to the same attrib in the next vertex in the vertex buffer, + * in dwords. */ + unsigned stride[PIPE_MAX_ATTRIBS] = {0}; + + /* Mapped vertex buffers. */ + uint32_t* map[PIPE_MAX_ATTRIBS] = {0}; + + CS_LOCALS(r300); + + /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ + for (i = 0; i < vertex_element_count; i++) { + velem = &r300->vertex_element[i]; + offset[i] = velem->src_offset / 4; + size[i] = util_format_get_blocksize(velem->src_format) / 4; + vertex_size += size[i]; + vbi = velem->vertex_buffer_index; + + /* Map the buffer. */ + if (!map[vbi]) { + vbuf = &r300->vertex_buffer[vbi]; + map[vbi] = (uint32_t*)pipe_buffer_map(r300->context.screen, + vbuf->buffer, + PIPE_BUFFER_USAGE_CPU_READ); + map[vbi] += vbuf->buffer_offset / 4; + stride[vbi] = vbuf->stride / 4; + } + } + + r300_emit_dirty_state(r300); + + BEGIN_CS(10 + count * vertex_size); + OUT_CS_REG(R300_GA_COLOR_CONTROL, + r300_provoking_vertex_fixes(r300, mode)); + OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); + OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0); + OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); + OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); + OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | + r300_translate_primitive(mode)); + + /* Emit vertices. */ + for (v = 0; v < count; v++) { + for (i = 0; i < vertex_element_count; i++) { + velem = &r300->vertex_element[i]; + vbi = velem->vertex_buffer_index; + elem_offset = offset[i] + stride[vbi] * (v + start); + + for (dw = 0; dw < size[i]; dw++) { + OUT_CS(map[vbi][elem_offset + dw]); + } + } + } + END_CS; + + /* Unmap buffers. */ + for (i = 0; i < vertex_element_count; i++) { + vbi = r300->vertex_element[i].vertex_buffer_index; + + if (map[vbi]) { + vbuf = &r300->vertex_buffer[vbi]; + pipe_buffer_unmap(r300->context.screen, vbuf->buffer); + map[vbi] = NULL; + } + } +} + static void r300_emit_draw_arrays(struct r300_context *r300, unsigned mode, unsigned count) @@ -183,17 +275,18 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } - static boolean r300_setup_vertex_buffers(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_buffer *pbuf; validate: for (int i = 0; i < r300->vertex_element_count; i++) { - if (!r300->winsys->add_buffer(r300->winsys, - vbuf[velem[i].vertex_buffer_index].buffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + pbuf = vbuf[velem[i].vertex_buffer_index].buffer; + + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -207,17 +300,49 @@ validate: return TRUE; } +static void r300_shorten_ubyte_elts(struct r300_context* r300, + struct pipe_buffer** elts, + unsigned count) +{ + struct pipe_screen* screen = r300->context.screen; + struct pipe_buffer* new_elts; + unsigned char *in_map; + unsigned short *out_map; + unsigned i; + + new_elts = screen->buffer_create(screen, 32, + PIPE_BUFFER_USAGE_INDEX | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ, + 2 * count); + + in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); + out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); + + for (i = 0; i < count; i++) { + *out_map = (unsigned short)*in_map; + in_map++; + out_map++; + } + + pipe_buffer_unmap(screen, *elts); + pipe_buffer_unmap(screen, new_elts); + + *elts = new_elts; +} + /* This is the fast-path drawing & emission for HW TCL. */ void r300_draw_range_elements(struct pipe_context* pipe, - struct pipe_buffer* indexBuffer, - unsigned indexSize, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) + struct pipe_buffer* indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) { struct r300_context* r300 = r300_context(pipe); + struct pipe_buffer* orgIndexBuffer = indexBuffer; if (!u_trim_pipe_prim(mode, &count)) { return; @@ -232,17 +357,24 @@ void r300_draw_range_elements(struct pipe_context* pipe, r300_update_derived_state(r300); + r300_emit_buffer_validate(r300); + if (!r300_setup_vertex_buffers(r300)) { return; } + if (indexSize == 1) { + r300_shorten_ubyte_elts(r300, &indexBuffer, count); + indexSize = 2; + } + if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, RADEON_GEM_DOMAIN_GTT, 0)) { - return; + goto cleanup; } if (!r300->winsys->validate(r300->winsys)) { - return; + goto cleanup; } r300_emit_dirty_state(r300); @@ -251,6 +383,11 @@ void r300_draw_range_elements(struct pipe_context* pipe, r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); + +cleanup: + if (indexBuffer != orgIndexBuffer) { + pipe->screen->buffer_destroy(indexBuffer); + } } /* Simple helpers for context setup. Should probably be moved to util. */ @@ -264,7 +401,7 @@ void r300_draw_elements(struct pipe_context* pipe, } void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, - unsigned start, unsigned count) + unsigned start, unsigned count) { struct r300_context* r300 = r300_context(pipe); @@ -281,15 +418,19 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, r300_update_derived_state(r300); - if (!r300_setup_vertex_buffers(r300)) { - return; - } - - r300_emit_dirty_state(r300); + r300_emit_buffer_validate(r300); - r300_emit_aos(r300, start); + if (immd_is_good_idea(r300, count)) { + r300_emit_draw_arrays_immediate(r300, mode, start, count); + } else { + if (!r300_setup_vertex_buffers(r300)) { + return; + } - r300_emit_draw_arrays(r300, mode, count); + r300_emit_dirty_state(r300); + r300_emit_aos(r300, start); + r300_emit_draw_arrays(r300, mode, count); + } } /**************************************************************************** @@ -321,6 +462,7 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, + 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, r300->shader_constants[PIPE_SHADER_VERTEX].count * (sizeof(float) * 4)); @@ -365,6 +507,7 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, + 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, r300->shader_constants[PIPE_SHADER_VERTEX].count * (sizeof(float) * 4)); @@ -416,7 +559,7 @@ r300_render_get_vertex_info(struct vbuf_render* render) r300_update_derived_state(r300); - return &r300->vertex_info->vinfo; + return (struct vertex_info*)r300->vertex_format_state.state; } static boolean r300_render_allocate_vertices(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 287664b1d2..da4ec542ad 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -20,7 +20,7 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_simple_screen.h" @@ -30,6 +30,7 @@ #include "r300_texture.h" #include "radeon_winsys.h" +#include "r300_winsys.h" /* Return the identifier behind whom the brave coders responsible for this * amalgamation of code, sweat, and duct tape, routinely obscure their names. @@ -113,6 +114,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) * ~ C. */ return 1; + case PIPE_CAP_DUAL_SOURCE_BLEND: + return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: @@ -149,6 +152,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) } else { return 0; } + case PIPE_CAP_INDEP_BLEND_ENABLE: + if (r300screen->caps->is_r500) { + return 1; + } else { + return 0; + } + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: debug_printf("r300: Implementation error: Bad param %d\n", param); @@ -183,10 +200,20 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param) } } -static boolean check_tex_format(enum pipe_format format, uint32_t usage, - boolean is_r500) +static boolean r300_is_format_supported(struct pipe_screen* screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned usage, + unsigned geom_flags) { uint32_t retval = 0; + boolean is_r500 = r300_screen(screen)->caps->is_r500; + + if (target >= PIPE_MAX_TEXTURE_TYPES) { + debug_printf("r300: Implementation error: Received bogus texture " + "target %d in %s\n", target, __FUNCTION__); + return FALSE; + } switch (format) { /* Supported formats. */ @@ -194,6 +221,8 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_L8_UNORM: retval = usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | @@ -208,7 +237,8 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_YCBCR: - case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_L8_SRGB: + case PIPE_FORMAT_A8L8_SRGB: case PIPE_FORMAT_A8L8_UNORM: retval = usage & PIPE_TEXTURE_USAGE_SAMPLER; break; @@ -247,28 +277,13 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: - debug_printf("r300: Note: Got unsupported format: %s in %s\n", - pf_name(format), __FUNCTION__); + SCREEN_DBG(r300_screen(screen), DBG_TEX, + "r300: Note: Got unsupported format: %s in %s\n", + pf_name(format), __FUNCTION__); return FALSE; - /* XXX These don't even exist - case PIPE_FORMAT_A32R32G32B32: - case PIPE_FORMAT_A16R16G16B16: */ - /* XXX What the deuce is UV88? (r3xx accel page 14) - debug_printf("r300: Warning: Got unimplemented format: %s in %s\n", - pf_name(format), __FUNCTION__); - return FALSE; */ - - /* XXX Supported yet unimplemented r5xx formats: */ - /* XXX Again, what is UV1010 this time? (r5xx accel page 148) */ - /* XXX Even more that don't exist - case PIPE_FORMAT_A10R10G10B10_UNORM: - case PIPE_FORMAT_A2R10G10B10_UNORM: - case PIPE_FORMAT_I10_UNORM: - debug_printf( - "r300: Warning: Got unimplemented r500 format: %s in %s\n", - pf_name(format), __FUNCTION__); - return FALSE; */ + /* XXX Add all remaining gallium-supported formats, + * see util/u_format.csv. */ default: /* Unknown format... */ @@ -286,30 +301,6 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, return (retval >= usage); } -static boolean r300_is_format_supported(struct pipe_screen* pscreen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, - unsigned geom_flags) -{ - switch (target) { - case PIPE_TEXTURE_1D: /* handle 1D textures as 2D ones */ - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_3D: - case PIPE_TEXTURE_CUBE: - return check_tex_format(format, tex_usage, - r300_screen(pscreen)->caps->is_r500); - - default: - debug_printf("r300: Fatal: This is not a format target: %d\n", - target); - assert(0); - break; - } - - return FALSE; -} - static struct pipe_transfer* r300_get_tex_transfer(struct pipe_screen *screen, struct pipe_texture *texture, @@ -319,6 +310,7 @@ r300_get_tex_transfer(struct pipe_screen *screen, { struct r300_texture *tex = (struct r300_texture *)texture; struct r300_transfer *trans; + struct r300_screen *rscreen = r300_screen(screen); unsigned offset; offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ @@ -330,11 +322,8 @@ r300_get_tex_transfer(struct pipe_screen *screen, trans->transfer.y = y; trans->transfer.width = w; trans->transfer.height = h; - trans->transfer.stride = r300_texture_get_stride(tex, level); + trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); trans->transfer.usage = usage; - - /* XXX not sure whether it's required to set these two, - the driver doesn't use them */ trans->transfer.zslice = zslice; trans->transfer.face = face; @@ -389,16 +378,21 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); - if (!r300screen || !caps) + if (!r300screen || !caps) { + FREE(r300screen); + FREE(caps); return NULL; + } caps->pci_id = radeon_winsys->pci_id; caps->num_frag_pipes = radeon_winsys->gb_pipes; caps->num_z_pipes = radeon_winsys->z_pipes; + r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; + r300screen->radeon_winsys = radeon_winsys; r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys; r300screen->screen.destroy = r300_destroy_screen; r300screen->screen.get_name = r300_get_name; @@ -406,6 +400,7 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) r300screen->screen.get_param = r300_get_param; r300screen->screen.get_paramf = r300_get_paramf; r300screen->screen.is_format_supported = r300_is_format_supported; + r300screen->screen.context_create = r300_create_context; r300screen->screen.get_tex_transfer = r300_get_tex_transfer; r300screen->screen.tex_transfer_destroy = r300_tex_transfer_destroy; r300screen->screen.transfer_map = r300_transfer_map; diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 2217988add..502fbfa5a2 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -33,8 +33,13 @@ struct r300_screen { /* Parent class */ struct pipe_screen screen; + struct radeon_winsys* radeon_winsys; + /* Chipset capabilities */ struct r300_capabilities* caps; + + /** Combination of DBG_xxx flags */ + unsigned debug; }; struct r300_transfer { @@ -57,7 +62,44 @@ r300_transfer(struct pipe_transfer* transfer) return (struct r300_transfer*)transfer; } -/* Creates a new r300 screen. */ -struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); +/* Debug functionality. */ + +/** + * Debug flags to disable/enable certain groups of debugging outputs. + * + * \note These may be rather coarse, and the grouping may be impractical. + * If you find, while debugging the driver, that a different grouping + * of these flags would be beneficial, just feel free to change them + * but make sure to update the documentation in r300_debug.c to reflect + * those changes. + */ +/*@{*/ +#define DBG_HELP 0x0000001 +#define DBG_FP 0x0000002 +#define DBG_VP 0x0000004 +#define DBG_CS 0x0000008 +#define DBG_DRAW 0x0000010 +#define DBG_TEX 0x0000020 +#define DBG_FALL 0x0000040 +/*@}*/ + +static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags) +{ + return (screen->debug & flags) ? TRUE : FALSE; +} + +static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags, + const char * fmt, ...) +{ + if (SCREEN_DBG_ON(screen, flags)) { + va_list va; + va_start(va, fmt); + debug_vprintf(fmt, va); + va_end(va); + } +} + +void r300_init_debug(struct r300_screen* ctx); #endif /* R300_SCREEN_H */ + diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 435e613ddf..d07e90860c 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -30,7 +30,6 @@ #include "tgsi/tgsi_parse.h" #include "pipe/p_config.h" -#include "pipe/internal/p_winsys_screen.h" #include "r300_context.h" #include "r300_reg.h" @@ -156,23 +155,33 @@ static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA dstA == PIPE_BLENDFACTOR_ONE); } +static unsigned bgra_cmask(unsigned mask) +{ + /* Gallium uses RGBA color ordering while R300 expects BGRA. */ + + return ((mask & PIPE_MASK_R) << 2) | + ((mask & PIPE_MASK_B) >> 2) | + (mask & (PIPE_MASK_G | PIPE_MASK_A)); +} + /* Create a new blend state based on the CSO blend state. * * This encompasses alpha blending, logic/raster ops, and blend dithering. */ static void* r300_create_blend_state(struct pipe_context* pipe, const struct pipe_blend_state* state) { + struct r300_screen* r300screen = r300_screen(pipe->screen); struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); - if (state->blend_enable) + if (state->rt[0].blend_enable) { - unsigned eqRGB = state->rgb_func; - unsigned srcRGB = state->rgb_src_factor; - unsigned dstRGB = state->rgb_dst_factor; + unsigned eqRGB = state->rt[0].rgb_func; + unsigned srcRGB = state->rt[0].rgb_src_factor; + unsigned dstRGB = state->rt[0].rgb_dst_factor; - unsigned eqA = state->alpha_func; - unsigned srcA = state->alpha_src_factor; - unsigned dstA = state->alpha_dst_factor; + unsigned eqA = state->rt[0].alpha_func; + unsigned srcA = state->rt[0].alpha_src_factor; + unsigned dstA = state->rt[0].alpha_dst_factor; /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha, * this is just the crappy D3D naming */ @@ -289,18 +298,18 @@ static void* r300_create_blend_state(struct pipe_context* pipe, (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; } - /* Color Channel Mask */ - if (state->colormask & PIPE_MASK_R) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_RED_MASK0; - } - if (state->colormask & PIPE_MASK_G) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0; - } - if (state->colormask & PIPE_MASK_B) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0; - } - if (state->colormask & PIPE_MASK_A) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0; + /* Color channel masks for all MRTs. */ + blend->color_channel_mask = bgra_cmask(state->rt[0].colormask); + if (r300screen->caps->is_r500 && state->independent_blend_enable) { + if (state->rt[1].blend_enable) { + blend->color_channel_mask |= bgra_cmask(state->rt[1].colormask) << 4; + } + if (state->rt[2].blend_enable) { + blend->color_channel_mask |= bgra_cmask(state->rt[2].colormask) << 8; + } + if (state->rt[3].blend_enable) { + blend->color_channel_mask |= bgra_cmask(state->rt[3].colormask) << 12; + } } if (state->dither) { @@ -340,6 +349,7 @@ static void r300_set_blend_color(struct pipe_context* pipe, const struct pipe_blend_color* color) { struct r300_context* r300 = r300_context(pipe); + struct r300_screen* r300screen = r300_screen(pipe->screen); struct r300_blend_color_state* state = (struct r300_blend_color_state*)r300->blend_color_state.state; union util_color uc; @@ -355,6 +365,7 @@ static void r300_set_blend_color(struct pipe_context* pipe, float_to_fixed10(color->color[2]) | (float_to_fixed10(color->color[1]) << 16); + r300->blend_color_state.size = r300screen->caps->is_r500 ? 3 : 2; r300->blend_color_state.dirty = TRUE; } @@ -365,11 +376,14 @@ static void r300_set_clip_state(struct pipe_context* pipe, if (r300_screen(pipe->screen)->caps->has_tcl) { memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state)); - r300->clip_state.dirty = TRUE; + r300->clip_state.size = 29; } else { draw_flush(r300->draw); draw_set_clip_state(r300->draw, state); + r300->clip_state.size = 2; } + + r300->clip_state.dirty = TRUE; } /* Create a new depth, stencil, and alpha state based on the CSO dsa state. @@ -427,7 +441,6 @@ static void* (r300_translate_stencil_op(state->stencil[1].zfail_op) << R300_S_BACK_ZFAIL_OP_SHIFT); - /* XXX it seems r3xx doesn't support STENCILREFMASK_BF */ if (caps->is_r500) { dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK; @@ -446,8 +459,7 @@ static void* r300_translate_alpha_function(state->alpha.func) | R300_FG_ALPHA_FUNC_ENABLE; - /* XXX figure out why emitting 10bit alpha ref causes CS to dump */ - /* always use 8bit alpha ref */ + /* We could use 10bit alpha ref but who needs that? */ dsa->alpha_function |= float_to_ubyte(state->alpha.ref_value); if (caps->is_r500) @@ -462,8 +474,10 @@ static void r300_bind_dsa_state(struct pipe_context* pipe, void* state) { struct r300_context* r300 = r300_context(pipe); + struct r300_screen* r300screen = r300_screen(pipe->screen); r300->dsa_state.state = state; + r300->dsa_state.size = r300screen->caps->is_r500 ? 8 : 6; r300->dsa_state.dirty = TRUE; } @@ -474,56 +488,52 @@ static void r300_delete_dsa_state(struct pipe_context* pipe, FREE(state); } -static void r300_set_scissor_regs(const struct pipe_scissor_state* state, - struct r300_scissor_regs *scissor, - boolean is_r500) -{ - if (is_r500) { - scissor->top_left = - (state->minx << R300_SCISSORS_X_SHIFT) | - (state->miny << R300_SCISSORS_Y_SHIFT); - scissor->bottom_right = - ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | - ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT); - } else { - /* Offset of 1440 in non-R500 chipsets. */ - scissor->top_left = - ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | - ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); - scissor->bottom_right = - (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | - (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); - } -} - static void r300_set_framebuffer_state(struct pipe_context* pipe, const struct pipe_framebuffer_state* state) { struct r300_context* r300 = r300_context(pipe); - struct r300_scissor_state* scissor = - (struct r300_scissor_state*)r300->scissor_state.state; - struct pipe_scissor_state pscissor; + uint32_t zbuffer_bpp = 0; + + r300->fb_state.size = (10 * state->nr_cbufs) + + (2 * (4 - state->nr_cbufs)) + + (state->zsbuf ? 10 : 0) + 6; + + if (state->nr_cbufs > 4) { + debug_printf("r300: Implementation error: Too many MRTs in %s, " + "refusing to bind framebuffer state!\n", __FUNCTION__); + return; + } if (r300->draw) { draw_flush(r300->draw); } - r300->framebuffer_state = *state; - - /* XXX Arg. This is silly. */ - pscissor.minx = pscissor.miny = 0; - pscissor.maxx = state->width; - pscissor.maxy = state->height; - r300_set_scissor_regs(&pscissor, &scissor->framebuffer, - r300_screen(r300->context.screen)->caps->is_r500); + memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); /* Don't rely on the order of states being set for the first time. */ - r300->dirty_state |= R300_NEW_FRAMEBUFFERS; - + /* XXX wait what */ r300->blend_state.dirty = TRUE; r300->dsa_state.dirty = TRUE; + r300->fb_state.dirty = TRUE; r300->scissor_state.dirty = TRUE; + + /* Polygon offset depends on the zbuffer bit depth. */ + if (state->zsbuf && r300->polygon_offset_enabled) { + switch (util_format_get_blocksize(state->zsbuf->texture->format)) { + case 2: + zbuffer_bpp = 16; + break; + case 4: + zbuffer_bpp = 24; + break; + } + + if (r300->zbuffer_bpp != zbuffer_bpp) { + r300->zbuffer_bpp = zbuffer_bpp; + r300->rs_state.dirty = TRUE; + } + } } /* Create fragment shader state. */ @@ -559,7 +569,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300_pick_fragment_shader(r300); if (r300->vs && r300_vertex_shader_setup_wpos(r300)) { - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; } r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -629,9 +639,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->line_control = pack_float_16_6x(state->line_width) | R300_GA_LINE_CNTL_END_TYPE_COMP; - /* XXX I think there is something wrong with the polygon mode, - * XXX re-test when r300g is in a better shape */ - /* Enable polygon mode */ if (state->fill_cw != PIPE_POLYGON_MODE_FILL || state->fill_ccw != PIPE_POLYGON_MODE_FILL) { @@ -684,10 +691,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe, } if (rs->polygon_offset_enable) { - rs->depth_offset_front = rs->depth_offset_back = - fui(state->offset_units); - rs->depth_scale_front = rs->depth_scale_back = - fui(state->offset_scale); + rs->depth_offset = state->offset_units; + rs->depth_scale = state->offset_scale; } if (state->line_stipple_enable) { @@ -719,7 +724,13 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) draw_set_rasterizer_state(r300->draw, &rs->rs); } - r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport; + if (rs) { + r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport; + r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; + } else { + r300->tcl_bypass = FALSE; + r300->polygon_offset_enabled = FALSE; + } r300->rs_state.state = rs; r300->rs_state.dirty = TRUE; @@ -728,7 +739,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) r300->viewport_state.dirty = TRUE; /* XXX Clean these up when we move to atom emits */ - r300->dirty_state |= R300_NEW_RS_BLOCK; if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -866,11 +876,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe, const struct pipe_scissor_state* state) { struct r300_context* r300 = r300_context(pipe); - struct r300_scissor_state* scissor = - (struct r300_scissor_state*)r300->scissor_state.state; - r300_set_scissor_regs(state, &scissor->scissor, - r300_screen(r300->context.screen)->caps->is_r500); + memcpy(r300->scissor_state.state, state, + sizeof(struct pipe_scissor_state)); r300->scissor_state.dirty = TRUE; } @@ -931,7 +939,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, draw_set_vertex_buffers(r300->draw, count, buffers); } - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; +} + +static boolean r300_validate_aos(struct r300_context *r300) +{ + struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + int i; + + /* Check if formats and strides are aligned to the size of DWORD. */ + for (i = 0; i < r300->vertex_element_count; i++) { + if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || + util_format_get_blocksize(velem[i].src_format) % 4 != 0) { + return FALSE; + } + } + return TRUE; } static void r300_set_vertex_elements(struct pipe_context* pipe, @@ -949,6 +973,12 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, count, elements); } + + if (!r300_validate_aos(r300)) { + /* XXX We should fallback using draw. */ + assert(0); + abort(); + } } static void* r300_create_vs_state(struct pipe_context* pipe, @@ -989,9 +1019,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300_vertex_shader_setup_wpos(r300); } + r300->vertex_format_state.dirty = TRUE; + r300->dirty_state |= - R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS | - R300_NEW_VERTEX_FORMAT; + R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, @@ -1017,22 +1048,22 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) static void r300_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct r300_context* r300 = r300_context(pipe); void *mapped; - if (buf == NULL || buf->buffer->size == 0 || - (mapped = pipe_buffer_map(pipe->screen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) + if (buf == NULL || buf->size == 0 || + (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) { r300->shader_constants[shader].count = 0; return; } - assert((buf->buffer->size % 4 * sizeof(float)) == 0); - memcpy(r300->shader_constants[shader].constants, mapped, buf->buffer->size); - r300->shader_constants[shader].count = buf->buffer->size / (4 * sizeof(float)); - pipe_buffer_unmap(pipe->screen, buf->buffer); + assert((buf->size % 4 * sizeof(float)) == 0); + memcpy(r300->shader_constants[shader].constants, mapped, buf->size); + r300->shader_constants[shader].count = buf->size / (4 * sizeof(float)); + pipe_buffer_unmap(pipe->screen, buf); if (shader == PIPE_SHADER_VERTEX) r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 192846411b..bad9e76067 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -37,32 +37,6 @@ /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ -struct r300_shader_key { - struct r300_vertex_shader* vs; - struct r300_fragment_shader* fs; -}; - -struct r300_shader_derived_value { - struct r300_vertex_format* vformat; - struct r300_rs_block* rs_block; -}; - -unsigned r300_shader_key_hash(void* key) { - struct r300_shader_key* shader_key = (struct r300_shader_key*)key; - unsigned vs = (intptr_t)shader_key->vs; - unsigned fs = (intptr_t)shader_key->fs; - - return (vs << 16) | (fs & 0xffff); -} - -int r300_shader_key_compare(void* key1, void* key2) { - struct r300_shader_key* shader_key1 = (struct r300_shader_key*)key1; - struct r300_shader_key* shader_key2 = (struct r300_shader_key*)key2; - - return (shader_key1->vs == shader_key2->vs) && - (shader_key1->fs == shader_key2->fs); -} - static void r300_draw_emit_attrib(struct r300_context* r300, enum attrib_emit emit, enum interp_mode interp, @@ -74,7 +48,9 @@ static void r300_draw_emit_attrib(struct r300_context* r300, output = draw_find_shader_output(r300->draw, info->output_semantic_name[index], info->output_semantic_index[index]); - draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output); + draw_emit_vertex_attr( + (struct vertex_info*)r300->vertex_format_state.state, + emit, interp, output); } static void r300_draw_emit_all_attribs(struct r300_context* r300) @@ -130,7 +106,8 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) /* Update the PSC tables. */ static void r300_vertex_psc(struct r300_context* r300) { - struct r300_vertex_info *vformat = r300->vertex_info; + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; uint16_t type, swizzle; enum pipe_format format; unsigned i; @@ -182,7 +159,8 @@ static void r300_vertex_psc(struct r300_context* r300) /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { - struct r300_vertex_info *vformat = r300->vertex_info; + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; struct vertex_info* vinfo = &vformat->vinfo; uint16_t type, swizzle; enum pipe_format format; @@ -327,7 +305,7 @@ static void r300_update_rs_block(struct r300_context* r300, struct r300_shader_semantics* vs_outputs, struct r300_shader_semantics* fs_inputs) { - struct r300_rs_block* rs = r300->rs_block; + struct r300_rs_block rs = { { 0 } }; int i, col_count = 0, tex_count = 0, fp_offset = 0; void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); @@ -350,14 +328,15 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_col(rs, col_count, i, FALSE); + rX00_rs_col(&rs, col_count, i, FALSE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->color[i] != ATTR_UNUSED) { - rX00_rs_col_write(rs, col_count, fp_offset); + rX00_rs_col_write(&rs, col_count, fp_offset); fp_offset++; } col_count++; @@ -375,11 +354,11 @@ static void r300_update_rs_block(struct r300_context* r300, if (vs_outputs->generic[i] != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(rs, tex_count, tex_count, FALSE); + rX00_rs_tex(&rs, tex_count, tex_count, FALSE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->generic[i] != ATTR_UNUSED) { - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; } tex_count++; @@ -396,11 +375,11 @@ static void r300_update_rs_block(struct r300_context* r300, if (vs_outputs->fog != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(rs, tex_count, tex_count, TRUE); + rX00_rs_tex(&rs, tex_count, tex_count, TRUE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; } tex_count++; @@ -415,8 +394,8 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize WPOS. */ /* If the FS doesn't need it, it's not written by the VS. */ if (fs_inputs->wpos != ATTR_UNUSED) { - rX00_rs_tex(rs, tex_count, tex_count, FALSE); - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex(&rs, tex_count, tex_count, FALSE); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; tex_count++; @@ -424,51 +403,33 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize at least one color, or bad things happen. */ if (col_count == 0 && tex_count == 0) { - rX00_rs_col(rs, 0, 0, TRUE); + rX00_rs_col(&rs, 0, 0, TRUE); col_count++; } - rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | + rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; - rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0); + rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0); + + /* Now, after all that, see if we actually need to update the state. */ + if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { + memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); + r300->rs_block_state.dirty = TRUE; + } } -/* Update the vertex format. */ +/* Update the shader-dependant states. */ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; + struct vertex_info* vinfo = &vformat->vinfo; - /* - struct r300_shader_key* key; - struct r300_shader_derived_value* value; - key = CALLOC_STRUCT(r300_shader_key); - key->vs = r300->vs; - key->fs = r300->fs; - - value = (struct r300_shader_derived_value*) - util_hash_table_get(r300->shader_hash_table, (void*)key); - if (value) { - //vformat = value->vformat; - rs_block = value->rs_block; - - FREE(key); - } else { - rs_block = CALLOC_STRUCT(r300_rs_block); - value = CALLOC_STRUCT(r300_shader_derived_value); - - r300_update_rs_block(r300, rs_block); - - //value->vformat = vformat; - value->rs_block = rs_block; - util_hash_table_set(r300->shader_hash_table, - (void*)key, (void*)value); - } */ - - /* Reset structures */ - memset(r300->rs_block, 0, sizeof(struct r300_rs_block)); - memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info)); - memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4); + /* Mmm, delicious hax */ + memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); + memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4); r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs); @@ -476,11 +437,10 @@ static void r300_update_derived_shader_state(struct r300_context* r300) r300_vertex_psc(r300); } else { r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size(&r300->vertex_info->vinfo); + draw_compute_vertex_size( + (struct vertex_info*)r300->vertex_format_state.state); r300_swtcl_vertex_psc(r300); } - - r300->dirty_state |= R300_NEW_RS_BLOCK; } static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) @@ -558,8 +518,8 @@ void r300_update_derived_state(struct r300_context* r300) { /* XXX */ if (r300->dirty_state & - (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER | - R300_NEW_VERTEX_FORMAT) || r300->rs_state.dirty) { + (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) || + r300->vertex_format_state.dirty || r300->rs_state.dirty) { r300_update_derived_shader_state(r300); } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 35be00e1b0..5df6815221 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -81,9 +81,6 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact) return R300_BLEND_GL_CONST_COLOR; case PIPE_BLENDFACTOR_CONST_ALPHA: return R300_BLEND_GL_CONST_ALPHA; - /* XXX WTF are these? - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: */ case PIPE_BLENDFACTOR_ZERO: return R300_BLEND_GL_ZERO; case PIPE_BLENDFACTOR_INV_SRC_COLOR: @@ -98,9 +95,16 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact) return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; - /* XXX see above + + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + debug_printf("r300: Implementation error: " + "Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + default: debug_printf("r300: Unknown blend factor %d\n", blend_fact); assert(0); @@ -331,7 +335,10 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) { switch (format) { /* 8-bit buffers */ + case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + /* case PIPE_FORMAT_S8_UNORM: ??? */ return R300_COLOR_FORMAT_I8; /* 16-bit buffers */ case PIPE_FORMAT_R5G6B5_UNORM: @@ -408,6 +415,16 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) return R300_US_OUT_FMT_C4_8 | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; + + /* 8-bit outputs */ + case PIPE_FORMAT_A8_UNORM: + return R300_US_OUT_FMT_C4_8 | + R300_C0_SEL_A; + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + return R300_US_OUT_FMT_C4_8 | + R300_C0_SEL_R; + /* R300_OUT_SIGN(x) */ default: debug_printf("r300: Implementation error: " "Got unsupported output format %s in %s\n", @@ -537,6 +554,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { static INLINE uint16_t r300_translate_vertex_data_swizzle(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); + unsigned swizzle[4], i; assert(format); @@ -547,11 +565,26 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { return 0; } - return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | - (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | - (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | - (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | - (0xf << R300_WRITE_ENA_SHIFT)); + /* Swizzles for 8bits formats are in the reversed order, not sure why. */ + if (desc->channel[0].size == 8) { + for (i = 0; i < 4; i++) { + if (desc->swizzle[i] <= 3) { + swizzle[i] = 3 - desc->swizzle[i]; + } else { + swizzle[i] = desc->swizzle[i]; + } + } + } else { + for (i = 0; i < 4; i++) { + swizzle[i] = desc->swizzle[i]; + } + } + + return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | + (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | + (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | + (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | + (0xf << R300_WRITE_ENA_SHIFT)); } #endif /* R300_STATE_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index f25f3ca217..97927acf1b 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -38,12 +38,12 @@ struct pipe_viewport_state r300_viewport_identity = { * * Note that eventually this should be empty, but it's useful for development * and general unduplication of code. */ -void r300_emit_invariant_state(struct r300_context* r300) +void r300_emit_invariant_state(struct r300_context* r300, void* state) { struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); - BEGIN_CS(16 + (caps->has_tcl ? 2: 0)); + BEGIN_CS(14 + (caps->has_tcl ? 2: 0)); /*** Graphics Backend (GB) ***/ /* Various GB enables */ @@ -58,8 +58,6 @@ void r300_emit_invariant_state(struct r300_context* r300) */ /* Source of fog depth */ OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W); - /* AA enable */ - OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); /*** Fog (FG) ***/ OUT_CS_REG(R300_FG_FOG_BLEND, 0x0); @@ -79,7 +77,8 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0)); + BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + + (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0)); if (caps->has_tcl) { /*Flushing PVS is required before the VAP_GB registers can be changed*/ @@ -115,10 +114,12 @@ void r300_emit_invariant_state(struct r300_context* r300) OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C); OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525); OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000); - if (caps->is_r500) { + + if (caps->family >= CHIP_FAMILY_RV350) { OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101); OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE); } + OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000); OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h index 05cff0d6df..5d1a963654 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.h +++ b/src/gallium/drivers/r300/r300_state_invariant.h @@ -25,6 +25,6 @@ struct r300_context; -void r300_emit_invariant_state(struct r300_context* r300); +void r300_emit_invariant_state(struct r300_context* r300, void* state); #endif /* R300_STATE_INVARIANT_H */ diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 9a96206a4d..67bf8ce13f 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -30,10 +30,25 @@ #include "r300_texture.h" #include "r300_screen.h" -static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) +#include "radeon_winsys.h" + +#define TILE_WIDTH 0 +#define TILE_HEIGHT 1 + +static const unsigned microblock_table[5][3][2] = { + /*linear tiled square-tiled */ + {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */ + {{16, 1}, {8, 2}, {4, 4}}, /* 16 bits per pixel */ + {{ 8, 1}, {4, 2}, {0, 0}}, /* 32 bits per pixel */ + {{ 4, 1}, {0, 0}, {2, 2}}, /* 64 bits per pixel */ + {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ +}; + +static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; + boolean is_r500 = screen->caps->is_r500; state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); @@ -67,8 +82,8 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) } assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048)); - debug_printf("r300: Set texture state (%dx%d, %d levels)\n", - pt->width0, pt->height0, pt->last_level); + SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", + pt->width0, pt->height0, pt->last_level); } unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, @@ -92,33 +107,78 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, } /** + * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile + * of the given texture. + */ +static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim) +{ + unsigned pixsize, tile_size; + + pixsize = util_format_get_blocksize(tex->tex.format); + tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim] * + (tex->macrotile == R300_BUFFER_TILED ? 8 : 1); + + assert(tile_size); + return tile_size; +} + +/** * Return the stride, in bytes, of the texture images of the given texture * at the given level. */ -unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) +unsigned r300_texture_get_stride(struct r300_screen* screen, + struct r300_texture* tex, unsigned level) { + unsigned tile_width, width; + if (tex->stride_override) return tex->stride_override; + /* Check the level. */ if (level > tex->tex.last_level) { - debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, - level, tex->tex.last_level); + SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", + __FUNCTION__, level, tex->tex.last_level); return 0; } - return align(util_format_get_stride(tex->tex.format, u_minify(tex->tex.width0, level)), 32); + width = u_minify(tex->tex.width0, level); + + if (!util_format_is_compressed(tex->tex.format)) { + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH); + width = align(width, tile_width); + return util_format_get_stride(tex->tex.format, width); + } else { + return align(util_format_get_stride(tex->tex.format, width), 32); + } } -static void r300_setup_miptree(struct r300_texture* tex) +static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, + unsigned level) +{ + unsigned height, tile_height; + + height = u_minify(tex->tex.height0, level); + + if (!util_format_is_compressed(tex->tex.format)) { + tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT); + height = align(height, tile_height); + } + + return util_format_get_nblocksy(tex->tex.format, height); +} + +static void r300_setup_miptree(struct r300_screen* screen, + struct r300_texture* tex) { struct pipe_texture* base = &tex->tex; - int stride, size, layer_size; - int i; + unsigned stride, size, layer_size, nblocksy, i; - for (i = 0; i <= base->last_level; i++) { - unsigned nblocksy = util_format_get_nblocksy(base->format, u_minify(base->height0, i)); + SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", + pf_name(base->format)); - stride = r300_texture_get_stride(tex, i); + for (i = 0; i <= base->last_level; i++) { + stride = r300_texture_get_stride(screen, tex, i); + nblocksy = r300_texture_get_nblocksy(tex, i); layer_size = stride * nblocksy; if (base->target == PIPE_TEXTURE_CUBE) @@ -131,10 +191,10 @@ static void r300_setup_miptree(struct r300_texture* tex) tex->layer_size[i] = layer_size; tex->pitch[i] = stride / util_format_get_blocksize(base->format); - debug_printf("r300: Texture miptree: Level %d " - "(%dx%dx%d px, pitch %d bytes)\n", + SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " + "(%dx%dx%d px, pitch %d bytes) %d bytes total\n", i, u_minify(base->width0, i), u_minify(base->height0, i), - u_minify(base->depth0, i), stride); + u_minify(base->depth0, i), stride, tex->size); } } @@ -150,6 +210,8 @@ static struct pipe_texture* const struct pipe_texture* template) { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); + struct r300_screen* rscreen = r300_screen(screen); + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; if (!tex) { return NULL; @@ -160,12 +222,16 @@ static struct pipe_texture* tex->tex.screen = screen; r300_setup_flags(tex); - r300_setup_miptree(tex); - r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); + r300_setup_miptree(rscreen, tex); + r300_setup_texture_state(rscreen, tex); - tex->buffer = screen->buffer_create(screen, 1024, + tex->buffer = screen->buffer_create(screen, 2048, PIPE_BUFFER_USAGE_PIXEL, tex->size); + winsys->buffer_set_tiling(winsys, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -227,6 +293,7 @@ static struct pipe_texture* struct pipe_buffer* buffer) { struct r300_texture* tex; + struct r300_screen* rscreen = r300_screen(screen); /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -248,7 +315,7 @@ static struct pipe_texture* tex->pitch[0] = *stride / util_format_get_blocksize(base->format); r300_setup_flags(tex); - r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); + r300_setup_texture_state(rscreen, tex); pipe_buffer_reference(&tex->buffer, buffer); @@ -315,7 +382,8 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->video_surface_destroy= r300_video_surface_destroy; } -boolean r300_get_texture_buffer(struct pipe_texture* texture, +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride) { @@ -327,7 +395,7 @@ boolean r300_get_texture_buffer(struct pipe_texture* texture, pipe_buffer_reference(buffer, tex->buffer); if (stride) { - *stride = r300_texture_get_stride(tex, 0); + *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } return TRUE; diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 55ceb1a513..961bdcc5b3 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -31,31 +31,46 @@ struct r300_texture; void r300_init_screen_texture_functions(struct pipe_screen* screen); -unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level); +unsigned r300_texture_get_stride(struct r300_screen* screen, + struct r300_texture* tex, unsigned level); unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, unsigned zslice, unsigned face); -/* Note the signature of R300_EASY_TX_FORMAT(A, R, G, B, FORMAT)... */ +/* Translate a pipe_format into a useful texture format for sampling. + * + * R300_EASY_TX_FORMAT swizzles the texture. + * Note the signature of R300_EASY_TX_FORMAT: + * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT); + * + * The FORMAT specifies how the texture sampler will treat the texture, and + * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) { switch (format) { /* X8 */ + case PIPE_FORMAT_A8_UNORM: + return R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8); case PIPE_FORMAT_I8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X8); case PIPE_FORMAT_L8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, ONE, X8); + case PIPE_FORMAT_L8_SRGB: + return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | + R300_TX_FORMAT_GAMMA; /* X16 */ case PIPE_FORMAT_R16_UNORM: + case PIPE_FORMAT_Z16_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X16); case PIPE_FORMAT_R16_SNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X16) | R300_TX_FORMAT_SIGNED; - case PIPE_FORMAT_Z16_UNORM: - return R300_EASY_TX_FORMAT(X, X, X, X, X16); /* Y8X8 */ case PIPE_FORMAT_A8L8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8); + case PIPE_FORMAT_A8L8_SRGB: + return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | + R300_TX_FORMAT_GAMMA; /* W8Z8Y8X8 */ case PIPE_FORMAT_A8R8G8B8_UNORM: return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); @@ -115,7 +130,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H -boolean r300_get_texture_buffer(struct pipe_texture* texture, +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index a792c2cf98..941ec17016 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -201,6 +201,8 @@ static void transform_srcreg( struct rc_src_register * dst, struct tgsi_full_src_register * src) { + unsigned i, j; + dst->File = translate_register_file(src->Register.File); dst->Index = translate_register_index(ttr, src->Register.File, src->Register.Index); dst->RelAddr = src->Register.Indirect; @@ -210,6 +212,21 @@ static void transform_srcreg( dst->Swizzle |= tgsi_util_get_full_src_register_swizzle(src, 3) << 9; dst->Abs = src->Register.Absolute; dst->Negate = src->Register.Negate ? RC_MASK_XYZW : 0; + + if (src->Register.File == TGSI_FILE_IMMEDIATE) { + for (i = 0; i < ttr->imms_to_swizzle_count; i++) { + if (ttr->imms_to_swizzle[i].index == src->Register.Index) { + dst->File = RC_FILE_TEMPORARY; + dst->Index = 0; + dst->Swizzle = 0; + for (j = 0; j < 4; j++) { + dst->Swizzle |= GET_SWZ(ttr->imms_to_swizzle[i].swizzle, + tgsi_util_get_full_src_register_swizzle(src, j)) << (j * 3); + } + break; + } + } + } } static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_texture src, @@ -277,21 +294,45 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst &ttr->compiler->Program.ShadowSamplers); } -static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm) +static void handle_immediate(struct tgsi_to_rc * ttr, + struct tgsi_full_immediate * imm, + unsigned index) { struct rc_constant constant; - int i; + unsigned swizzle = 0; + boolean can_swizzle = TRUE; + unsigned i; - constant.Type = RC_CONSTANT_IMMEDIATE; - constant.Size = 4; - for(i = 0; i < 4; ++i) - constant.u.Immediate[i] = imm->u[i].Float; - rc_constants_add(&ttr->compiler->Program.Constants, &constant); + for (i = 0; i < 4; i++) { + if (imm->u[i].Float == 0.0f) { + swizzle |= RC_SWIZZLE_ZERO << (i * 3); + } else if (imm->u[i].Float == 0.5f) { + swizzle |= RC_SWIZZLE_HALF << (i * 3); + } else if (imm->u[i].Float == 1.0f) { + swizzle |= RC_SWIZZLE_ONE << (i * 3); + } else { + can_swizzle = FALSE; + break; + } + } + + if (can_swizzle) { + ttr->imms_to_swizzle[ttr->imms_to_swizzle_count].index = index; + ttr->imms_to_swizzle[ttr->imms_to_swizzle_count].swizzle = swizzle; + ttr->imms_to_swizzle_count++; + } else { + constant.Type = RC_CONSTANT_IMMEDIATE; + constant.Size = 4; + for(i = 0; i < 4; ++i) + constant.u.Immediate[i] = imm->u[i].Float; + rc_constants_add(&ttr->compiler->Program.Constants, &constant); + } } void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) { struct tgsi_parse_context parser; + unsigned imm_index = 0; int i; /* Allocate constants placeholders. @@ -308,6 +349,9 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) ttr->immediate_offset = ttr->compiler->Program.Constants.Count; + ttr->imms_to_swizzle = malloc(ttr->info->immediate_count * sizeof(struct swizzled_imms)); + ttr->imms_to_swizzle_count = 0; + tgsi_parse_init(&parser, tokens); while (!tgsi_parse_end_of_tokens(&parser)) { @@ -317,7 +361,8 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) case TGSI_TOKEN_TYPE_DECLARATION: break; case TGSI_TOKEN_TYPE_IMMEDIATE: - handle_immediate(ttr, &parser.FullToken.FullImmediate); + handle_immediate(ttr, &parser.FullToken.FullImmediate, imm_index); + imm_index++; break; case TGSI_TOKEN_TYPE_INSTRUCTION: transform_instruction(ttr, &parser.FullToken.FullInstruction); @@ -327,6 +372,8 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens) tgsi_parse_free(&parser); + free(ttr->imms_to_swizzle); + rc_calculate_inputs_outputs(ttr->compiler); } diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h index 93e90ec6d2..39b473c7bf 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.h +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h @@ -29,11 +29,18 @@ struct tgsi_full_declaration; struct tgsi_shader_info; struct tgsi_token; +struct swizzled_imms { + unsigned index; + unsigned swizzle; +}; + struct tgsi_to_rc { struct radeon_compiler * compiler; const struct tgsi_shader_info * info; int immediate_offset; + struct swizzled_imms * imms_to_swizzle; + unsigned imms_to_swizzle_count; }; void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens); diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 68aef70872..fb81b2439b 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -61,17 +61,17 @@ static void r300_shader_read_vs_outputs( break; case TGSI_SEMANTIC_COLOR: - assert(index <= ATTR_COLOR_COUNT); + assert(index < ATTR_COLOR_COUNT); vs_outputs->color[index] = i; break; case TGSI_SEMANTIC_BCOLOR: - assert(index <= ATTR_COLOR_COUNT); + assert(index < ATTR_COLOR_COUNT); vs_outputs->bcolor[index] = i; break; case TGSI_SEMANTIC_GENERIC: - assert(index <= ATTR_GENERIC_COUNT); + assert(index < ATTR_GENERIC_COUNT); vs_outputs->generic[index] = i; break; @@ -124,7 +124,8 @@ static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs) /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { hwfmt[1] |= R300_INPUT_CNTL_COLOR; hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; } @@ -182,7 +183,8 @@ static void r300_stream_locations_notcl( /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { stream_loc[tabi++] = 2 + i; } } @@ -259,7 +261,8 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (outputs->color[i] != ATTR_UNUSED) { c->code->outputs[outputs->color[i]] = reg++; - } else if (any_bcolor_used) { + } else if (any_bcolor_used || + outputs->color[1] != ATTR_UNUSED) { reg++; } } diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 1ae6de70fe..f4a8ae120c 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -29,18 +29,20 @@ extern "C" { /* The public interface header for the r300 pipe driver. * Any winsys hosting this pipe needs to implement r300_winsys and then - * call r300_create_context to start things. */ + * call r300_create_screen to start things. */ #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "radeon_winsys.h" -struct pipe_context* r300_create_context(struct pipe_screen* screen, - struct radeon_winsys* radeon_winsys); +/* Creates a new r300 screen. */ +struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); -boolean r300_get_texture_buffer(struct pipe_texture* texture, + +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index bcb887a0b2..e4ac49fa85 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -32,6 +32,7 @@ C_SOURCES = \ sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c \ - sp_video_context.c + sp_video_context.c \ + sp_winsys.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index aac9edf44e..3042e556c6 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -34,6 +34,7 @@ softpipe = env.ConvenienceLibrary( 'sp_texture.c', 'sp_tile_cache.c', 'sp_video_context.c', + 'sp_winsys.c' ]) Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index f3ac6760db..2b22ce256e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -35,6 +35,7 @@ #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" @@ -43,8 +44,6 @@ #include "sp_surface.h" #include "sp_tile_cache.h" #include "sp_tex_tile_cache.h" -#include "sp_texture.h" -#include "sp_winsys.h" #include "sp_query.h" @@ -112,9 +111,13 @@ softpipe_destroy( struct pipe_context *pipe ) pipe_texture_reference(&softpipe->vertex_textures[i], NULL); } - for (i = 0; i < Elements(softpipe->constants); i++) { - if (softpipe->constants[i].buffer) { - pipe_buffer_reference(&softpipe->constants[i].buffer, NULL); + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (softpipe->constants[i][j]) { + pipe_buffer_reference(&softpipe->constants[i][j], NULL); + } } } @@ -190,7 +193,8 @@ softpipe_render_condition( struct pipe_context *pipe, struct pipe_context * -softpipe_create( struct pipe_screen *screen ) +softpipe_create_context( struct pipe_screen *screen, + void *priv ) { struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i; @@ -209,6 +213,7 @@ softpipe_create( struct pipe_screen *screen ) softpipe->pipe.winsys = screen->winsys; softpipe->pipe.screen = screen; softpipe->pipe.destroy = softpipe_destroy; + softpipe->pipe.priv = priv; /* state setters */ softpipe->pipe.create_blend_state = softpipe_create_blend_state; @@ -256,6 +261,8 @@ softpipe_create( struct pipe_screen *screen ) softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_elements = softpipe_draw_elements; softpipe->pipe.draw_range_elements = softpipe_draw_range_elements; + softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced; + softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced; softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 73fa744f9d..62f9e7aad3 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -63,7 +63,7 @@ struct softpipe_context { /** Other rendering state */ struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -92,7 +92,7 @@ struct softpipe_context { ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; /** Mapped constant buffers */ - void *mapped_constants[PIPE_SHADER_TYPES]; + void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; /** Vertex format */ struct vertex_info vertex_info; @@ -166,5 +166,8 @@ softpipe_context( struct pipe_context *pipe ) void softpipe_reset_sampler_varients(struct softpipe_context *softpipe); +struct pipe_context * +softpipe_create_context( struct pipe_screen *, void *priv ); + #endif /* SP_CONTEXT_H */ diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 03d35fb3cb..b2acc36bf7 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -33,8 +33,8 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" #include "util/u_prim.h" #include "sp_context.h" @@ -49,30 +49,36 @@ static void softpipe_map_constant_buffers(struct softpipe_context *sp) { struct pipe_winsys *ws = sp->pipe.winsys; - uint i, vssize, gssize; + uint i; for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (sp->constants[i].buffer && sp->constants[i].buffer->size) - sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (sp->constants[i][j] && sp->constants[i][j]->size) { + sp->mapped_constants[i][j] = ws->buffer_map(ws, + sp->constants[i][j], + PIPE_BUFFER_USAGE_CPU_READ); + } + } } - if (sp->constants[PIPE_SHADER_VERTEX].buffer) - vssize = sp->constants[PIPE_SHADER_VERTEX].buffer->size; - else - vssize = 0; - - if (sp->constants[PIPE_SHADER_GEOMETRY].buffer) - gssize = sp->constants[PIPE_SHADER_GEOMETRY].buffer->size; - else - gssize = 0; - - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, - sp->mapped_constants[PIPE_SHADER_VERTEX], - vssize); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, - sp->mapped_constants[PIPE_SHADER_GEOMETRY], - gssize); + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + if (sp->constants[PIPE_SHADER_VERTEX][i]) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_VERTEX, + i, + sp->mapped_constants[PIPE_SHADER_VERTEX][i], + sp->constants[PIPE_SHADER_VERTEX][i]->size); + } + if (sp->constants[PIPE_SHADER_GEOMETRY][i]) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_GEOMETRY, + i, + sp->mapped_constants[PIPE_SHADER_GEOMETRY][i], + sp->constants[PIPE_SHADER_GEOMETRY][i]->size); + } + } } @@ -87,30 +93,67 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) */ draw_flush(sp->draw); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0); + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_VERTEX, + i, + NULL, + 0); + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_GEOMETRY, + i, + NULL, + 0); + } for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (sp->constants[i].buffer && sp->constants[i].buffer->size) - ws->buffer_unmap(ws, sp->constants[i].buffer); - sp->mapped_constants[i] = NULL; + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (sp->constants[i][j] && sp->constants[i][j]->size) { + ws->buffer_unmap(ws, sp->constants[i][j]); + } + sp->mapped_constants[i][j] = NULL; + } } } +/** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + */ +static void +softpipe_draw_range_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + + void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { - softpipe_draw_elements(pipe, NULL, 0, mode, start, count); + softpipe_draw_range_elements_instanced(pipe, + NULL, + 0, + 0, + 0xffffffff, + mode, + start, + count, + 0, + 1); } -/** - * Draw vertex arrays, with optional indexing. - * Basically, map the vertex buffers (and drawing surfaces), then hand off - * the drawing to the 'draw' module. - */ void softpipe_draw_range_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, @@ -119,6 +162,91 @@ softpipe_draw_range_elements(struct pipe_context *pipe, unsigned max_index, unsigned mode, unsigned start, unsigned count) { + softpipe_draw_range_elements_instanced(pipe, + indexBuffer, + indexSize, + min_index, + max_index, + mode, + start, + count, + 0, + 1); +} + + +void +softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + softpipe_draw_range_elements_instanced(pipe, + indexBuffer, + indexSize, + 0, + 0xffffffff, + mode, + start, + count, + 0, + 1); +} + +void +softpipe_draw_arrays_instanced(struct pipe_context *pipe, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount) +{ + softpipe_draw_range_elements_instanced(pipe, + NULL, + 0, + 0, + 0xffffffff, + mode, + start, + count, + startInstance, + instanceCount); +} + +void +softpipe_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount) +{ + softpipe_draw_range_elements_instanced(pipe, + indexBuffer, + indexSize, + 0, + 0xffffffff, + mode, + start, + count, + startInstance, + instanceCount); +} + +static void +softpipe_draw_range_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount) +{ struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; unsigned i; @@ -128,45 +256,48 @@ softpipe_draw_range_elements(struct pipe_context *pipe, sp->reduced_api_prim = u_reduced_prim(mode); - if (sp->dirty) - softpipe_update_derived( sp ); + if (sp->dirty) { + softpipe_update_derived(sp); + } softpipe_map_transfers(sp); softpipe_map_constant_buffers(sp); - /* - * Map vertex buffers - */ + /* Map vertex buffers */ for (i = 0; i < sp->num_vertex_buffers; i++) { - void *buf - = pipe_buffer_map(pipe->screen, - sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *buf; + + buf = pipe_buffer_map(pipe->screen, + sp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes - = pipe_buffer_map(pipe->screen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer_range(draw, indexSize, - min_index, - max_index, + void *mapped_indexes; + + mapped_indexes = pipe_buffer_map(pipe->screen, + indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer_range(draw, + indexSize, + minIndex, + maxIndex, mapped_indexes); - } - else { + } else { /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, 0, start, - start + count - 1, NULL); + draw_set_mapped_element_buffer_range(draw, + 0, + start, + start + count - 1, + NULL); } /* draw! */ - draw_arrays(draw, mode, start, count); + draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount); - /* - * unmap vertex/index buffers - will cause draw module to flush - */ + /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer); @@ -176,22 +307,8 @@ softpipe_draw_range_elements(struct pipe_context *pipe, pipe_buffer_unmap(pipe->screen, indexBuffer); } - /* Note: leave drawing surfaces mapped */ softpipe_unmap_constant_buffers(sp); sp->dirty_render_cache = TRUE; } - - -void -softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count) -{ - softpipe_draw_range_elements( pipe, indexBuffer, - indexSize, - 0, 0xffffffff, - mode, start, count ); -} diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 75dac810a1..e8952bf4fb 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -34,11 +34,9 @@ #include "draw/draw_context.h" #include "sp_flush.h" #include "sp_context.h" -#include "sp_surface.h" #include "sp_state.h" #include "sp_tile_cache.h" #include "sp_tex_tile_cache.h" -#include "sp_winsys.h" void diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index f912950658..acee213670 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -135,7 +135,7 @@ fs_sse_run( const struct sp_fragment_shader *base, tgsi_set_exec_mask(machine, 1, 1, 1, 1); shader->func( machine, - machine->Consts, + (const float (*)[4])machine->Consts[0], (const float (*)[4])shader->immediates, machine->InterpCoefs /*, &machine->QuadPos*/ diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 7f573aef3c..98c08eaffa 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -526,6 +526,8 @@ static void sp_vbuf_destroy(struct vbuf_render *vbr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + if(cvbr->vertex_buffer) + align_free(cvbr->vertex_buffer); sp_setup_destroy_context(cvbr->setup); FREE(cvbr); } @@ -541,7 +543,6 @@ sp_create_vbuf_backend(struct softpipe_context *sp) assert(sp->draw); - cvbr->base.max_indices = SP_MAX_VBUF_INDEXES; cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index d9babe81da..d65307b7f6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -35,7 +35,6 @@ #include "util/u_memory.h" #include "sp_context.h" #include "sp_quad.h" -#include "sp_surface.h" #include "sp_tile_cache.h" #include "sp_quad_pipe.h" @@ -224,7 +223,8 @@ logicop_quad(struct quad_stage *qs, static void blend_quad(struct quad_stage *qs, float (*quadColor)[4], - float (*dest)[4]) + float (*dest)[4], + unsigned cbuf) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; @@ -234,7 +234,7 @@ blend_quad(struct quad_stage *qs, /* * Compute src/first term RGB */ - switch (softpipe->blend->rgb_src_factor) { + switch (softpipe->blend->rt[cbuf].rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[0], quadColor[0]); /* R */ VEC4_COPY(source[1], quadColor[1]); /* G */ @@ -384,7 +384,7 @@ blend_quad(struct quad_stage *qs, /* * Compute src/first term A */ - switch (softpipe->blend->alpha_src_factor) { + switch (softpipe->blend->rt[cbuf].alpha_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[3], quadColor[3]); /* A */ break; @@ -453,7 +453,7 @@ blend_quad(struct quad_stage *qs, /* * Compute dest/second term RGB */ - switch (softpipe->blend->rgb_dst_factor) { + switch (softpipe->blend->rt[cbuf].rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -593,7 +593,7 @@ blend_quad(struct quad_stage *qs, /* * Compute dest/second term A */ - switch (softpipe->blend->alpha_dst_factor) { + switch (softpipe->blend->rt[cbuf].alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -656,7 +656,7 @@ blend_quad(struct quad_stage *qs, /* * Combine RGB terms */ - switch (softpipe->blend->rgb_func) { + switch (softpipe->blend->rt[cbuf].rgb_func) { case PIPE_BLEND_ADD: VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ @@ -689,7 +689,7 @@ blend_quad(struct quad_stage *qs, /* * Combine A terms */ - switch (softpipe->blend->alpha_func) { + switch (softpipe->blend->rt[cbuf].alpha_func) { case PIPE_BLEND_ADD: VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ break; @@ -711,26 +711,24 @@ blend_quad(struct quad_stage *qs, } static void -colormask_quad(struct quad_stage *qs, +colormask_quad(unsigned colormask, float (*quadColor)[4], float (*dest)[4]) { - struct softpipe_context *softpipe = qs->softpipe; - /* R */ - if (!(softpipe->blend->colormask & PIPE_MASK_R)) + if (!(colormask & PIPE_MASK_R)) COPY_4V(quadColor[0], dest[0]); /* G */ - if (!(softpipe->blend->colormask & PIPE_MASK_G)) + if (!(colormask & PIPE_MASK_G)) COPY_4V(quadColor[1], dest[1]); /* B */ - if (!(softpipe->blend->colormask & PIPE_MASK_B)) + if (!(colormask & PIPE_MASK_B)) COPY_4V(quadColor[2], dest[2]); /* A */ - if (!(softpipe->blend->colormask & PIPE_MASK_A)) + if (!(colormask & PIPE_MASK_A)) COPY_4V(quadColor[3], dest[3]); } @@ -773,12 +771,12 @@ blend_fallback(struct quad_stage *qs, if (blend->logicop_enable) { logicop_quad( qs, quadColor, dest ); } - else if (blend->blend_enable) { - blend_quad( qs, quadColor, dest ); + else if (blend->rt[cbuf].blend_enable) { + blend_quad( qs, quadColor, dest, cbuf ); } - if (blend->colormask != 0xf) - colormask_quad( qs, quadColor, dest ); + if (blend->rt[cbuf].colormask != 0xf) + colormask_quad( blend->rt[cbuf].colormask, quadColor, dest); /* Output color values */ @@ -954,23 +952,23 @@ choose_blend_quad(struct quad_stage *qs, qs->run = blend_noop; } else if (!softpipe->blend->logicop_enable && - softpipe->blend->colormask == 0xf && + softpipe->blend->rt[0].colormask == 0xf && softpipe->framebuffer.nr_cbufs == 1) { - if (!blend->blend_enable) { + if (!blend->rt[0].blend_enable) { qs->run = single_output_color; } - else if (blend->rgb_src_factor == blend->alpha_src_factor && - blend->rgb_dst_factor == blend->alpha_dst_factor && - blend->rgb_func == blend->alpha_func) + else if (blend->rt[0].rgb_src_factor == blend->rt[0].alpha_src_factor && + blend->rt[0].rgb_dst_factor == blend->rt[0].alpha_dst_factor && + blend->rt[0].rgb_func == blend->rt[0].alpha_func) { - if (blend->alpha_func == PIPE_BLEND_ADD) { - if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE && - blend->rgb_dst_factor == PIPE_BLENDFACTOR_ONE) { + if (blend->rt[0].alpha_func == PIPE_BLEND_ADD) { + if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_ONE && + blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_ONE) { qs->run = blend_single_add_one_one; } - else if (blend->rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA && - blend->rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA) + else if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA && + blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA) qs->run = blend_single_add_src_alpha_inv_src_alpha; } diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 0ca86c4e1c..a981775cbd 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -30,11 +30,11 @@ */ #include "pipe/p_defines.h" +#include "util/u_format.h" #include "util/u_memory.h" #include "tgsi/tgsi_scan.h" #include "sp_context.h" #include "sp_quad.h" -#include "sp_surface.h" #include "sp_quad_pipe.h" #include "sp_tile_cache.h" #include "sp_state.h" /* for sp_fragment_shader */ @@ -651,6 +651,20 @@ static unsigned mask_count[16] = +/** helper to get number of Z buffer bits */ +static unsigned +get_depth_bits(struct quad_stage *qs) +{ + struct pipe_surface *zsurf = qs->softpipe->framebuffer.zsbuf; + if (zsurf) + return util_format_get_component_bits(zsurf->format, + UTIL_FORMAT_COLORSPACE_ZS, 0); + else + return 0; +} + + + static void depth_test_quads_fallback(struct quad_stage *qs, struct quad_header *quads[], @@ -666,7 +680,7 @@ depth_test_quads_fallback(struct quad_stage *qs, nr = alpha_test_quads(qs, quads, nr); } - if (qs->softpipe->framebuffer.zsbuf && + if (get_depth_bits(qs) > 0 && (qs->softpipe->depth_stencil->depth.enabled || qs->softpipe->depth_stencil->stencil[0].enabled)) { @@ -884,7 +898,7 @@ choose_depth_test(struct quad_stage *qs, boolean alpha = qs->softpipe->depth_stencil->alpha.enabled; - boolean depth = (qs->softpipe->framebuffer.zsbuf && + boolean depth = (get_depth_bits(qs) > 0 && qs->softpipe->depth_stencil->depth.enabled); unsigned depthfunc = qs->softpipe->depth_stencil->depth.func; @@ -895,7 +909,6 @@ choose_depth_test(struct quad_stage *qs, boolean occlusion = qs->softpipe->active_query_count; - if (!alpha && !depth && !stencil) { diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 1e7533d0f9..ad04dc2afc 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -45,8 +45,6 @@ #include "sp_state.h" #include "sp_quad.h" #include "sp_quad_pipe.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" struct quad_shade_stage @@ -109,10 +107,11 @@ shade_quads(struct quad_stage *qs, struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = qss->machine; - unsigned i, pass = 0; - - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i]; + } machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index bd3532de4f..87415f4340 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -28,13 +28,14 @@ #include "util/u_memory.h" #include "util/u_simple_screen.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "sp_texture.h" #include "sp_winsys.h" #include "sp_screen.h" +#include "sp_context.h" static const char * @@ -91,6 +92,19 @@ softpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; + case PIPE_CAP_MAX_CONST_BUFFERS: + return PIPE_MAX_CONSTANT_BUFFERS; + case PIPE_CAP_MAX_CONST_BUFFER_SIZE: + return 4096 * 4 * sizeof(float); + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 1; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 1; default: return 0; } @@ -191,6 +205,7 @@ softpipe_create_screen(struct pipe_winsys *winsys) screen->base.get_param = softpipe_get_param; screen->base.get_paramf = softpipe_get_paramf; screen->base.is_format_supported = softpipe_is_format_supported; + screen->base.context_create = softpipe_create_context; softpipe_init_screen_texture_funcs(&screen->base); u_simple_screen_init(&screen->base); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 3da75364c5..b8590a8cc2 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -38,10 +38,8 @@ #include "sp_setup.h" #include "sp_state.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "pipe/p_shader_tokens.h" -#include "pipe/p_thread.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -395,6 +393,52 @@ static boolean setup_sort_vertices( struct setup_context *setup, } +/* Apply cylindrical wrapping to v0, v1, v2 coordinates, if enabled. + * Input coordinates must be in [0, 1] range, otherwise results are undefined. + * Some combinations of coordinates produce invalid results, + * but this behaviour is acceptable. + */ +static void +tri_apply_cylindrical_wrap(float v0, + float v1, + float v2, + uint cylindrical_wrap, + float output[3]) +{ + if (cylindrical_wrap) { + float delta; + + delta = v1 - v0; + if (delta > 0.5f) { + v0 += 1.0f; + } + else if (delta < -0.5f) { + v1 += 1.0f; + } + + delta = v2 - v1; + if (delta > 0.5f) { + v1 += 1.0f; + } + else if (delta < -0.5f) { + v2 += 1.0f; + } + + delta = v0 - v2; + if (delta > 0.5f) { + v2 += 1.0f; + } + else if (delta < -0.5f) { + v0 += 1.0f; + } + } + + output[0] = v0; + output[1] = v1; + output[2] = v2; +} + + /** * Compute a0 for a constant-valued coefficient (GL_FLAT shading). * The value value comes from vertex[slot][i]. @@ -420,13 +464,16 @@ static void const_coeff( struct setup_context *setup, /** * Compute a0, dadx and dady for a linearly interpolated coefficient, * for a triangle. + * v[0], v[1] and v[2] are vmin, vmid and vmax, respectively. */ -static void tri_linear_coeff( struct setup_context *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) +static void +tri_linear_coeff(struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint i, + const float v[3]) { - float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; - float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + float botda = v[1] - v[0]; + float majda = v[2] - v[0]; float a = setup->ebot.dy * majda - botda * setup->emaj.dy; float b = setup->emaj.dx * botda - majda * setup->ebot.dx; float dadx = a * setup->oneoverarea; @@ -449,7 +496,7 @@ static void tri_linear_coeff( struct setup_context *setup, * to define a0 as the sample at a pixel center somewhere near vmin * instead - i'll switch to this later. */ - coef->a0[i] = (setup->vmin[vertSlot][i] - + coef->a0[i] = (v[0] - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + dady * (setup->vmin[0][1] - setup->pixel_offset))); @@ -470,16 +517,19 @@ static void tri_linear_coeff( struct setup_context *setup, * the plane coefficients (a0, dadx, dady). * Later, when we compute the value at a particular fragment position we'll * divide the interpolated value by the interpolated W at that fragment. + * v[0], v[1] and v[2] are vmin, vmid and vmax, respectively. */ -static void tri_persp_coeff( struct setup_context *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) +static void +tri_persp_coeff(struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint i, + const float v[3]) { /* premultiply by 1/w (v[0][3] is always W): */ - float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; - float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + float mina = v[0] * setup->vmin[0][3]; + float mida = v[1] * setup->vmid[0][3]; + float maxa = v[2] * setup->vmax[0][3]; float botda = mida - mina; float majda = maxa - mina; float a = setup->ebot.dy * majda - botda * setup->emaj.dy; @@ -506,21 +556,24 @@ static void tri_persp_coeff( struct setup_context *setup, /** * Special coefficient setup for gl_FragCoord. - * X and Y are trivial, though Y has to be inverted for OpenGL. + * X and Y are trivial, though Y may have to be inverted for OpenGL. * Z and W are copied from posCoef which should have already been computed. * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void setup_fragcoord_coeff(struct setup_context *setup, uint slot) { + struct sp_fragment_shader* spfs = setup->softpipe->fs; /*X*/ - setup->coef[slot].a0[0] = 0; + setup->coef[slot].a0[0] = spfs->pixel_center_integer ? 0.0 : 0.5; setup->coef[slot].dadx[0] = 1.0; setup->coef[slot].dady[0] = 0.0; /*Y*/ - setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].a0[1] = + (spfs->origin_lower_left ? setup->softpipe->framebuffer.height : 0) + + (spfs->pixel_center_integer ? 0.0 : 0.5); setup->coef[slot].dadx[1] = 0.0; - setup->coef[slot].dady[1] = 1.0; + setup->coef[slot].dady[1] = spfs->origin_lower_left ? -1.0 : 1.0; /*Z*/ setup->coef[slot].a0[2] = setup->posCoef.a0[2]; setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; @@ -543,11 +596,19 @@ static void setup_tri_coefficients( struct setup_context *setup ) const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; + float v[3]; /* z and w are done by linear interpolation: */ - tri_linear_coeff(setup, &setup->posCoef, 0, 2); - tri_linear_coeff(setup, &setup->posCoef, 0, 3); + v[0] = setup->vmin[0][2]; + v[1] = setup->vmid[0][2]; + v[2] = setup->vmax[0][2]; + tri_linear_coeff(setup, &setup->posCoef, 2, v); + + v[0] = setup->vmin[0][3]; + v[1] = setup->vmid[0][3]; + v[2] = setup->vmax[0][3]; + tri_linear_coeff(setup, &setup->posCoef, 3, v); /* setup interpolation for all the remaining attributes: */ @@ -561,12 +622,24 @@ static void setup_tri_coefficients( struct setup_context *setup ) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + for (j = 0; j < NUM_CHANNELS; j++) { + tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], + setup->vmid[vertSlot][j], + setup->vmax[vertSlot][j], + spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + v); + tri_linear_coeff(setup, &setup->coef[fragSlot], j, v); + } break; case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + for (j = 0; j < NUM_CHANNELS; j++) { + tri_apply_cylindrical_wrap(setup->vmin[vertSlot][j], + setup->vmid[vertSlot][j], + setup->vmax[vertSlot][j], + spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + v); + tri_persp_coeff(setup, &setup->coef[fragSlot], j, v); + } break; case INTERP_POS: setup_fragcoord_coeff(setup, fragSlot); @@ -776,22 +849,49 @@ void sp_setup_tri( struct setup_context *setup, } +/* Apply cylindrical wrapping to v0, v1 coordinates, if enabled. + * Input coordinates must be in [0, 1] range, otherwise results are undefined. + */ +static void +line_apply_cylindrical_wrap(float v0, + float v1, + uint cylindrical_wrap, + float output[2]) +{ + if (cylindrical_wrap) { + float delta; + + delta = v1 - v0; + if (delta > 0.5f) { + v0 += 1.0f; + } + else if (delta < -0.5f) { + v1 += 1.0f; + } + } + + output[0] = v0; + output[1] = v1; +} + /** * Compute a0, dadx and dady for a linearly interpolated coefficient, * for a line. + * v[0] and v[1] are vmin and vmax, respectively. */ static void line_linear_coeff(const struct setup_context *setup, struct tgsi_interp_coef *coef, - uint vertSlot, uint i) + uint i, + const float v[2]) { - const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + const float da = v[1] - v[0]; const float dadx = da * setup->emaj.dx * setup->oneoverarea; const float dady = da * setup->emaj.dy * setup->oneoverarea; coef->dadx[i] = dadx; coef->dady[i] = dady; - coef->a0[i] = (setup->vmin[vertSlot][i] - + coef->a0[i] = (v[0] - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + dady * (setup->vmin[0][1] - setup->pixel_offset))); } @@ -800,21 +900,22 @@ line_linear_coeff(const struct setup_context *setup, /** * Compute a0, dadx and dady for a perspective-corrected interpolant, * for a line. + * v[0] and v[1] are vmin and vmax, respectively. */ static void line_persp_coeff(const struct setup_context *setup, struct tgsi_interp_coef *coef, - uint vertSlot, uint i) + uint i, + const float v[2]) { - /* XXX double-check/verify this arithmetic */ - const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; - const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + const float a0 = v[0] * setup->vmin[0][3]; + const float a1 = v[1] * setup->vmax[0][3]; const float da = a1 - a0; const float dadx = da * setup->emaj.dx * setup->oneoverarea; const float dady = da * setup->emaj.dy * setup->oneoverarea; coef->dadx[i] = dadx; coef->dady[i] = dady; - coef->a0[i] = (setup->vmin[vertSlot][i] - + coef->a0[i] = (a0 - (dadx * (setup->vmin[0][0] - setup->pixel_offset) + dady * (setup->vmin[0][1] - setup->pixel_offset))); } @@ -834,6 +935,7 @@ setup_line_coefficients(struct setup_context *setup, const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; float area; + float v[2]; /* use setup->vmin, vmax to point to vertices */ if (softpipe->rasterizer->flatshade_first) @@ -854,8 +956,13 @@ setup_line_coefficients(struct setup_context *setup, /* z and w are done by linear interpolation: */ - line_linear_coeff(setup, &setup->posCoef, 0, 2); - line_linear_coeff(setup, &setup->posCoef, 0, 3); + v[0] = setup->vmin[0][2]; + v[1] = setup->vmax[0][2]; + line_linear_coeff(setup, &setup->posCoef, 2, v); + + v[0] = setup->vmin[0][3]; + v[1] = setup->vmax[0][3]; + line_linear_coeff(setup, &setup->posCoef, 3, v); /* setup interpolation for all the remaining attributes: */ @@ -869,12 +976,22 @@ setup_line_coefficients(struct setup_context *setup, const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + for (j = 0; j < NUM_CHANNELS; j++) { + line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], + setup->vmax[vertSlot][j], + spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + v); + line_linear_coeff(setup, &setup->coef[fragSlot], j, v); + } break; case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + for (j = 0; j < NUM_CHANNELS; j++) { + line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], + setup->vmax[vertSlot][j], + spfs->info.input_cylindrical_wrap[fragSlot] & (1 << j), + v); + line_persp_coeff(setup, &setup->coef[fragSlot], j, v); + } break; case INTERP_POS: setup_fragcoord_coeff(setup, fragSlot); diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 9b18dac67b..a83cae7361 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -68,6 +68,9 @@ struct sp_fragment_shader { struct tgsi_shader_info info; + boolean origin_lower_left; /**< fragment shader uses lower left position origin? */ + boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */ + void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler **samplers); @@ -139,7 +142,7 @@ void softpipe_set_clip_state( struct pipe_context *, void softpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, - const struct pipe_constant_buffer *buf); + struct pipe_buffer *buf); void *softpipe_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -200,6 +203,24 @@ softpipe_draw_range_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); void +softpipe_draw_arrays_instanced(struct pipe_context *pipe, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + +void +softpipe_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + +void softpipe_map_transfers(struct softpipe_context *sp); void diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index f6856a5f69..d2eda7324c 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -30,7 +30,6 @@ #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vertex.h" -#include "draw/draw_private.h" #include "sp_context.h" #include "sp_screen.h" #include "sp_state.h" @@ -67,7 +66,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) /* compute vertex layout now */ const struct sp_fragment_shader *spfs = softpipe->fs; struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; - const uint num = draw_current_shader_outputs(softpipe->draw); + const uint num = draw_num_shader_outputs(softpipe->draw); uint i; /* Tell draw_vbuf to simply emit the whole post-xform vertex diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index aa12bb215a..c88e213751 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -31,6 +31,7 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" #include "draw/draw_vs.h" #include "tgsi/tgsi_dump.h" @@ -44,6 +45,7 @@ softpipe_create_fs_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state; + unsigned i; /* debug */ if (softpipe->dump_fs) @@ -60,6 +62,13 @@ softpipe_create_fs_state(struct pipe_context *pipe, /* get/save the summary info for this shader */ tgsi_scan_shader(templ->tokens, &state->info); + for (i = 0; i < state->info.num_properties; ++i) { + if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN) + state->origin_lower_left = state->info.properties[i].data[0]; + else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER) + state->pixel_center_integer = state->info.properties[i].data[0]; + } + return state; } @@ -159,18 +168,17 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) void softpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct softpipe_context *softpipe = softpipe_context(pipe); assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); + assert(index < PIPE_MAX_CONSTANT_BUFFERS); draw_flush(softpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&softpipe->constants[shader].buffer, - buf ? buf->buffer : NULL); + pipe_buffer_reference(&softpipe->constants[shader][index], buf); softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index f6154109ea..2db6faeca4 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -30,12 +30,12 @@ #include "sp_context.h" #include "sp_state.h" -#include "sp_surface.h" #include "sp_tile_cache.h" #include "draw/draw_context.h" #include "util/u_format.h" +#include "util/u_inlines.h" /** diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 46b6991195..b491d92ed1 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -31,7 +31,6 @@ #include "sp_context.h" #include "sp_state.h" -#include "sp_surface.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 1ae8fecacf..473ec3e150 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -517,7 +517,6 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float rho = MAX2(dsdx, dsdy) * texture->width0; @@ -533,7 +532,6 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -553,7 +551,6 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index e50a76a73b..a0b95c8884 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -32,12 +32,11 @@ * Brian Paul */ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_tile.h" #include "util/u_math.h" #include "sp_context.h" -#include "sp_surface.h" #include "sp_texture.h" #include "sp_tex_tile_cache.h" diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index a9436a3394..371c4e2025 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -31,14 +31,13 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "sp_context.h" -#include "sp_state.h" #include "sp_texture.h" #include "sp_screen.h" #include "sp_winsys.h" @@ -57,13 +56,8 @@ softpipe_texture_layout(struct pipe_screen *screen, unsigned width = pt->width0; unsigned height = pt->height0; unsigned depth = pt->depth0; - unsigned buffer_size = 0; - pt->width0 = width; - pt->height0 = height; - pt->depth0 = depth; - for (level = 0; level <= pt->last_level; level++) { spt->stride[level] = util_format_get_stride(pt->format, width); @@ -296,6 +290,10 @@ softpipe_get_tex_transfer(struct pipe_screen *screen, assert(texture); assert(level <= texture->last_level); + /* make sure the requested region is in the image bounds */ + assert(x + w <= u_minify(texture->width0, level)); + assert(y + h <= u_minify(texture->height0, level)); + spt = CALLOC_STRUCT(softpipe_transfer); if (spt) { struct pipe_transfer *pt = &spt->base; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 112a6fe0cf..1b50bd7ffe 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -32,7 +32,7 @@ * Brian Paul */ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_tile.h" diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index cfa2a0b2f1..d8b5b31e95 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -26,9 +26,8 @@ **************************************************************************/ #include "sp_video_context.h" -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_memory.h> -#include "softpipe/sp_winsys.h" #include "softpipe/sp_texture.h" static void @@ -185,17 +184,18 @@ init_pipe_state(struct sp_mpeg12_context *ctx) ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); - blend.blend_enable = 0; - blend.rgb_func = PIPE_BLEND_ADD; - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_func = PIPE_BLEND_ADD; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.independent_blend_enable = 0; + blend.rt[0].blend_enable = 0; + blend.rt[0].rgb_func = PIPE_BLEND_ADD; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_func = PIPE_BLEND_ADD; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; blend.logicop_enable = 0; blend.logicop_func = PIPE_LOGICOP_CLEAR; /* Needed to allow color writes to FB, even if blending disabled */ - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].colormask = PIPE_MASK_RGBA; blend.dither = 0; ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); @@ -249,7 +249,7 @@ sp_mpeg12_create(struct pipe_screen *screen, enum pipe_video_profile profile, ctx->base.set_decode_target = sp_mpeg12_set_decode_target; ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix; - ctx->pipe = softpipe_create(screen); + ctx->pipe = screen->context_create(screen, NULL); if (!ctx->pipe) { FREE(ctx); return NULL; diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c new file mode 100644 index 0000000000..f6598927d3 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_winsys.c @@ -0,0 +1,245 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Malloc softpipe winsys. Uses malloc for all memory allocations. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "util/u_simple_screen.h"/* port to just p_screen */ +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "softpipe/sp_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_buffer); + if(!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +static struct pipe_buffer * +st_softpipe_surface_buffer_create(struct pipe_winsys *winsys, + unsigned width, unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride) +{ + const unsigned alignment = 64; + unsigned nblocksy; + + nblocksy = util_format_get_nblocksy(format, height); + *stride = align(util_format_get_stride(format, width), alignment); + + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_destroy(struct pipe_winsys *winsys) +{ + FREE(winsys); +} + + +struct pipe_screen * +softpipe_create_screen_malloc(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->destroy = st_softpipe_destroy; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_buffer_create = st_softpipe_surface_buffer_create; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + st_softpipe_destroy(winsys); + + return screen; +} diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index f203ded29e..6e3920c49b 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -47,12 +47,18 @@ struct pipe_texture; struct pipe_buffer; -struct pipe_context *softpipe_create( struct pipe_screen * ); +/** + * Create a softpipe screen that uses the + * given winsys for allocating buffers. + */ +struct pipe_screen *softpipe_create_screen( struct pipe_winsys * ); -struct pipe_screen * -softpipe_create_screen(struct pipe_winsys *); - +/** + * Create a softpipe screen that uses + * regular malloc to create all its buffers. + */ +struct pipe_screen *softpipe_create_screen_malloc(void); boolean softpipe_get_texture_buffer( struct pipe_texture *texture, diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index af99c9de37..d499ae6acc 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -26,7 +26,7 @@ #include "svga_cmd.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_memory.h" #include "util/u_bitmask.h" @@ -126,7 +126,8 @@ svga_is_buffer_referenced( struct pipe_context *pipe, } -struct pipe_context *svga_context_create( struct pipe_screen *screen ) +struct pipe_context *svga_context_create( struct pipe_screen *screen, + void *priv ) { struct svga_screen *svgascreen = svga_screen(screen); struct svga_context *svga = NULL; @@ -138,6 +139,7 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen ) svga->pipe.winsys = screen->winsys; svga->pipe.screen = screen; + svga->pipe.priv = priv; svga->pipe.destroy = svga_destroy; svga->pipe.clear = svga_clear; @@ -215,7 +217,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen ) svga->state.hw_draw.num_views = 0; svga->dirty = ~0; - svga->state.white_fs_id = SVGA3D_INVALID_ID; LIST_INITHEAD(&svga->dirty_buffers); diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index e2a96034d1..f9a641c6df 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -326,10 +326,6 @@ struct svga_context unsigned texture_timestamp; - /* Internally generated shaders: - */ - unsigned white_fs_id; - /* */ struct svga_sw_state sw; @@ -429,6 +425,10 @@ void svga_context_flush( struct svga_context *svga, void svga_hwtnl_flush_retry( struct svga_context *svga ); +struct pipe_context * +svga_context_create(struct pipe_screen *screen, + void *priv); + /*********************************************************************** * Inline conversion functions. These are better-typed than the diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index ca73cf9d5a..f4d2d8992c 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -24,7 +24,7 @@ **********************************************************/ #include "pipe/p_compiler.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c index 75492dffca..6192aa96b1 100644 --- a/src/gallium/drivers/svga/svga_draw_arrays.c +++ b/src/gallium/drivers/svga/svga_draw_arrays.c @@ -25,8 +25,7 @@ #include "svga_cmd.h" -#include "pipe/p_inlines.h" -#include "util/u_prim.h" +#include "util/u_inlines.h" #include "indices/u_indices.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index 167d817831..e8097d82f1 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -23,8 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" -#include "util/u_prim.h" +#include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "indices/u_indices.h" diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c index 855d228755..9dd6fb068c 100644 --- a/src/gallium/drivers/svga/svga_pipe_blend.c +++ b/src/gallium/drivers/svga/svga_pipe_blend.c @@ -23,13 +23,12 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" @@ -182,15 +181,15 @@ svga_create_blend_state(struct pipe_context *pipe, } } else { - blend->rt[i].blend_enable = templ->blend_enable; + blend->rt[i].blend_enable = templ->rt[0].blend_enable; - if (templ->blend_enable) { - blend->rt[i].srcblend = svga_translate_blend_factor(templ->rgb_src_factor); - blend->rt[i].dstblend = svga_translate_blend_factor(templ->rgb_dst_factor); - blend->rt[i].blendeq = svga_translate_blend_func(templ->rgb_func); - blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->alpha_src_factor); - blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->alpha_dst_factor); - blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->alpha_func); + if (templ->rt[0].blend_enable) { + blend->rt[i].srcblend = svga_translate_blend_factor(templ->rt[0].rgb_src_factor); + blend->rt[i].dstblend = svga_translate_blend_factor(templ->rt[0].rgb_dst_factor); + blend->rt[i].blendeq = svga_translate_blend_func(templ->rt[0].rgb_func); + blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_src_factor); + blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_dst_factor); + blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->rt[0].alpha_func); if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend || blend->rt[i].dstblend_alpha != blend->rt[i].dstblend || @@ -201,7 +200,7 @@ svga_create_blend_state(struct pipe_context *pipe, } } - blend->rt[i].writemask = templ->colormask; + blend->rt[i].writemask = templ->rt[0].colormask; } return blend; diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c index 10e7a12189..73a0cd6b3a 100644 --- a/src/gallium/drivers/svga/svga_pipe_constants.c +++ b/src/gallium/drivers/svga/svga_pipe_constants.c @@ -23,16 +23,12 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" -#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "svga_context.h" -#include "svga_state.h" -#include "svga_hw_reg.h" -#include "svga_cmd.h" /*********************************************************************** * Constant buffers @@ -49,7 +45,7 @@ struct svga_constbuf static void svga_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - const struct pipe_constant_buffer *buf) + struct pipe_buffer *buf) { struct svga_context *svga = svga_context(pipe); @@ -57,7 +53,7 @@ static void svga_set_constant_buffer(struct pipe_context *pipe, assert(index == 0); pipe_buffer_reference( &svga->curr.cb[shader], - buf->buffer ); + buf ); if (shader == PIPE_SHADER_FRAGMENT) svga->dirty |= SVGA_NEW_FS_CONST_BUFFER; diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c index df636c08a0..12bbd233a5 100644 --- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c +++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c @@ -23,13 +23,12 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 0f24ef4ee8..f00cf23935 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -25,7 +25,7 @@ #include "svga_cmd.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_prim.h" #include "util/u_time.h" #include "indices/u_indices.h" @@ -33,7 +33,6 @@ #include "svga_hw_reg.h" #include "svga_context.h" #include "svga_screen.h" -#include "svga_winsys.h" #include "svga_draw.h" #include "svga_state.h" #include "svga_swtnl.h" @@ -217,11 +216,6 @@ svga_draw_range_elements( struct pipe_context *pipe, } if (SVGA_DEBUG & DEBUG_FLUSH) { - static unsigned id; - debug_printf("%s %d\n", __FUNCTION__, id++); - if (id > 1300) - util_time_sleep( 2000 ); - svga_hwtnl_flush_retry( svga ); svga_context_flush(svga, NULL); } diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c index 0becb0765a..7fa2205ae5 100644 --- a/src/gallium/drivers/svga/svga_pipe_flush.c +++ b/src/gallium/drivers/svga/svga_pipe_flush.c @@ -27,14 +27,8 @@ #include "svga_screen.h" #include "svga_screen_texture.h" #include "svga_context.h" -#include "svga_winsys.h" -#include "svga_draw.h" #include "svga_debug.h" -#include "svga_hw_reg.h" - - - static void svga_flush( struct pipe_context *pipe, unsigned flags, diff --git a/src/gallium/drivers/svga/svga_pipe_fs.c b/src/gallium/drivers/svga/svga_pipe_fs.c index 5f1213e46a..b71bc66552 100644 --- a/src/gallium/drivers/svga/svga_pipe_fs.c +++ b/src/gallium/drivers/svga/svga_pipe_fs.c @@ -23,20 +23,17 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_bitmask.h" #include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_text.h" #include "svga_screen.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_tgsi.h" #include "svga_hw_reg.h" #include "svga_cmd.h" -#include "svga_draw.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c index 58cb1e6e23..49b43bebc2 100644 --- a/src/gallium/drivers/svga/svga_pipe_misc.c +++ b/src/gallium/drivers/svga/svga_pipe_misc.c @@ -25,14 +25,10 @@ #include "svga_cmd.h" +#include "util/u_inlines.h" + #include "svga_context.h" #include "svga_screen_texture.h" -#include "svga_state.h" -#include "svga_winsys.h" - -#include "svga_hw_reg.h" - - static void svga_set_scissor_state( struct pipe_context *pipe, diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 01336b0a2c..08283e3731 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -32,7 +32,6 @@ #include "svga_screen.h" #include "svga_screen_buffer.h" #include "svga_winsys.h" -#include "svga_draw.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c index 09ccb71884..3571778867 100644 --- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c +++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c @@ -24,13 +24,12 @@ **********************************************************/ #include "draw/draw_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 460a101f8c..b70081343d 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -32,9 +32,6 @@ #include "svga_context.h" #include "svga_screen_texture.h" -#include "svga_state.h" - -#include "svga_hw_reg.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 42f290d162..ffc0f99565 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -23,19 +23,14 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" -#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "svga_screen.h" #include "svga_screen_buffer.h" #include "svga_context.h" -#include "svga_state.h" -#include "svga_winsys.h" - -#include "svga_hw_reg.h" static void svga_set_vertex_buffers(struct pipe_context *pipe, diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c index 7e6ab576ad..de8c919e12 100644 --- a/src/gallium/drivers/svga/svga_pipe_vs.c +++ b/src/gallium/drivers/svga/svga_pipe_vs.c @@ -24,7 +24,7 @@ **********************************************************/ #include "draw/draw_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_bitmask.h" @@ -33,7 +33,6 @@ #include "svga_screen.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_tgsi.h" #include "svga_hw_reg.h" #include "svga_cmd.h" diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 45b5d85ae2..8143be5024 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -24,7 +24,7 @@ **********************************************************/ #include "util/u_memory.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_string.h" #include "util/u_math.h" @@ -33,10 +33,8 @@ #include "svga_screen.h" #include "svga_screen_texture.h" #include "svga_screen_buffer.h" -#include "svga_cmd.h" #include "svga_debug.h" -#include "svga_hw_reg.h" #include "svga3d_shaderdefs.h" @@ -146,6 +144,13 @@ svga_get_paramf(struct pipe_screen *screen, int param) case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; + default: return 0; } @@ -361,6 +366,7 @@ svga_screen_create(struct svga_winsys_screen *sws) screen->get_param = svga_get_param; screen->get_paramf = svga_get_paramf; screen->is_format_supported = svga_is_format_supported; + screen->context_create = svga_context_create; screen->fence_reference = svga_fence_reference; screen->fence_signalled = svga_fence_signalled; screen->fence_finish = svga_fence_finish; @@ -393,8 +399,6 @@ svga_screen_create(struct svga_winsys_screen *sws) pipe_mutex_init(svgascreen->tex_mutex); pipe_mutex_init(svgascreen->swc_mutex); - LIST_INITHEAD(&svgascreen->cached_buffers); - svga_screen_cache_init(svgascreen); return screen; diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h index b94ca7fc1c..9dc229b0a8 100644 --- a/src/gallium/drivers/svga/svga_screen.h +++ b/src/gallium/drivers/svga/svga_screen.h @@ -28,7 +28,7 @@ #include "pipe/p_screen.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_double_list.h" @@ -68,12 +68,6 @@ struct svga_screen pipe_mutex tex_mutex; pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */ - /** - * List of buffers with cached GMR. Ordered from the most recently used to - * the least recently used - */ - struct list_head cached_buffers; - struct svga_host_surface_cache cache; }; diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c index 58a1aba464..c9e9bef540 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.c +++ b/src/gallium/drivers/svga/svga_screen_buffer.c @@ -27,8 +27,8 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_thread.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -113,68 +113,9 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) if(sbuf->hw.buf) { sws->buffer_destroy(sws, sbuf->hw.buf); sbuf->hw.buf = NULL; - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); -#ifdef DEBUG - sbuf->head.next = sbuf->head.prev = NULL; -#endif } } -static INLINE enum pipe_error -svga_buffer_backup(struct svga_screen *ss, struct svga_buffer *sbuf) -{ - if (sbuf->hw.buf && sbuf->hw.num_ranges) { - void *src; - - if (!sbuf->swbuf) - sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment); - if (!sbuf->swbuf) - return PIPE_ERROR_OUT_OF_MEMORY; - - src = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, - PIPE_BUFFER_USAGE_CPU_READ); - if (!src) - return PIPE_ERROR; - - memcpy(sbuf->swbuf, src, sbuf->base.size); - ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf); - } - - return PIPE_OK; -} - -/** - * Try to make GMR space available by freeing the hardware storage of - * unmapped - */ -boolean -svga_buffer_free_cached_hw_storage(struct svga_screen *ss) -{ - struct list_head *curr; - struct svga_buffer *sbuf; - enum pipe_error ret = PIPE_OK; - - curr = ss->cached_buffers.prev; - - /* free the least recently used buffer's hw storage which is not mapped */ - do { - if(curr == &ss->cached_buffers) - return FALSE; - - sbuf = LIST_ENTRY(struct svga_buffer, curr, head); - - curr = curr->prev; - if (sbuf->map.count == 0) - ret = svga_buffer_backup(ss, sbuf); - - } while(sbuf->map.count != 0 || ret != PIPE_OK); - - svga_buffer_destroy_hw_storage(ss, sbuf); - - return TRUE; -} - struct svga_winsys_buffer * svga_winsys_buffer_create( struct svga_screen *ss, unsigned alignment, @@ -195,12 +136,6 @@ svga_winsys_buffer_create( struct svga_screen *ss, svga_screen_flush(ss, NULL); buf = sws->buffer_create(sws, alignment, usage, size); - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "evicting buffers to find %d bytes GMR\n", - size); - - /* Try evicing all buffer storage */ - while(!buf && svga_buffer_free_cached_hw_storage(ss)) - buf = sws->buffer_create(sws, alignment, usage, size); } return buf; @@ -226,8 +161,6 @@ svga_buffer_create_hw_storage(struct svga_screen *ss, return PIPE_ERROR_OUT_OF_MEMORY; assert(!sbuf->needs_flush); - assert(!sbuf->head.prev && !sbuf->head.next); - LIST_ADD(&sbuf->head, &ss->cached_buffers); } return PIPE_OK; @@ -311,7 +244,6 @@ static void svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf) { - struct svga_screen *ss = svga_screen(svga->pipe.screen); SVGA3dCopyBox *boxes; unsigned i; @@ -348,13 +280,16 @@ svga_buffer_upload_flush(struct svga_context *svga, assert(sbuf->head.prev && sbuf->head.next); LIST_DEL(&sbuf->head); +#ifdef DEBUG + sbuf->head.next = sbuf->head.prev = NULL; +#endif sbuf->needs_flush = FALSE; - /* XXX: do we care about cached_buffers any more ?*/ - LIST_ADD(&sbuf->head, &ss->cached_buffers); sbuf->hw.svga = NULL; sbuf->hw.boxes = NULL; + sbuf->host_written = TRUE; + /* Decrement reference count */ pipe_reference(&(sbuf->base.reference), NULL); sbuf = NULL; @@ -437,17 +372,17 @@ svga_buffer_map_range( struct pipe_screen *screen, } else { if(!sbuf->hw.buf) { - struct svga_winsys_surface *handle = sbuf->handle; - if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) return NULL; /* Populate the hardware storage if the host surface pre-existed */ - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) { + if(sbuf->host_written) { SVGA3dSurfaceDMAFlags flags; enum pipe_error ret; struct pipe_fence_handle *fence = NULL; + assert(sbuf->handle); + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", sbuf->handle, 0, sbuf->base.size); @@ -478,17 +413,6 @@ svga_buffer_map_range( struct pipe_screen *screen, sws->fence_reference(sws, &fence, NULL); } } - else { - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) { - /* We already had the hardware storage but we would have to issue - * a download if we hadn't, so move the buffer to the begginning - * of the LRU list. - */ - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); - LIST_ADD(&sbuf->head, &ss->cached_buffers); - } - } map = sws->buffer_map(sws, sbuf->hw.buf, usage); } @@ -572,10 +496,8 @@ svga_buffer_destroy( struct pipe_buffer *buf ) assert(!sbuf->needs_flush); - if(sbuf->handle) { - SVGA_DBG(DEBUG_DMA, "release sid %p sz %d\n", sbuf->handle, sbuf->base.size); - svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle); - } + if(sbuf->handle) + svga_buffer_destroy_host_surface(ss, sbuf); if(sbuf->hw.buf) svga_buffer_destroy_hw_storage(ss, sbuf); @@ -595,6 +517,9 @@ svga_buffer_create(struct pipe_screen *screen, struct svga_screen *ss = svga_screen(screen); struct svga_buffer *sbuf; + assert(size); + assert(alignment); + sbuf = CALLOC_STRUCT(svga_buffer); if(!sbuf) goto error1; @@ -755,8 +680,7 @@ svga_buffer_handle(struct svga_context *svga, assert(sbuf->hw.svga == svga); sbuf->needs_flush = TRUE; - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); + assert(!sbuf->head.prev && !sbuf->head.next); LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers); } diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h index 5d7af5a7c5..448ac107c7 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.h +++ b/src/gallium/drivers/svga/svga_screen_buffer.h @@ -135,6 +135,11 @@ struct svga_buffer */ struct svga_winsys_surface *handle; + /** + * Whether the host has been ever written. + */ + boolean host_written; + struct { unsigned count; boolean writing; @@ -178,9 +183,6 @@ svga_buffer_handle(struct svga_context *svga, void svga_context_flush_buffers(struct svga_context *svga); -boolean -svga_buffer_free_cached_hw_storage(struct svga_screen *ss); - struct svga_winsys_buffer * svga_winsys_buffer_create(struct svga_screen *ss, unsigned alignment, diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h index f5aa740d40..62156e3f52 100644 --- a/src/gallium/drivers/svga/svga_screen_cache.h +++ b/src/gallium/drivers/svga/svga_screen_cache.h @@ -31,7 +31,7 @@ #include "svga_reg.h" #include "svga3d_reg.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_double_list.h" diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 2224c2d394..12f3531a1d 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -27,8 +27,8 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_thread.h" +#include "util/u_inlines.h" +#include "os/os_thread.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -205,7 +205,7 @@ svga_transfer_dma(struct svga_transfer *st, if(transfer == SVGA3D_READ_HOST_VRAM) { svga_screen_flush(screen, &fence); sws->fence_finish(sws, fence, 0); - //sws->fence_reference(sws, &fence, NULL); + sws->fence_reference(sws, &fence, NULL); } } else { @@ -235,7 +235,7 @@ svga_transfer_dma(struct svga_transfer *st, if(y) { svga_screen_flush(screen, &fence); sws->fence_finish(sws, fence, 0); - //sws->fence_reference(sws, &fence, NULL); + sws->fence_reference(sws, &fence, NULL); } hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -306,11 +306,19 @@ svga_texture_create(struct pipe_screen *screen, tex->key.numFaces = 1; } + tex->key.cachable = 1; + if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; - if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + tex->key.cachable = 0; + } + + if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) { tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; + tex->key.cachable = 0; + } /* * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot @@ -333,8 +341,6 @@ svga_texture_create(struct pipe_screen *screen, if(tex->key.format == SVGA3D_FORMAT_INVALID) goto error2; - tex->key.cachable = 1; - SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle); tex->handle = svga_screen_surface_create(svgascreen, &tex->key); if (tex->handle) @@ -416,6 +422,62 @@ svga_texture_blanket(struct pipe_screen * screen, } +struct pipe_texture * +svga_screen_texture_wrap_surface(struct pipe_screen *screen, + struct pipe_texture *base, + enum SVGA3dSurfaceFormat format, + struct svga_winsys_surface *srf) +{ + struct svga_texture *tex; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth0 != 1) { + return NULL; + } + + if (!srf) + return NULL; + + if (svga_translate_format(base->format) != format) { + unsigned f1 = svga_translate_format(base->format); + unsigned f2 = format; + + /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */ + if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) || + (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) || + (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) { + debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2); + return NULL; + } + } + + tex = CALLOC_STRUCT(svga_texture); + if (!tex) + return NULL; + + tex->base = *base; + + + if (format == 1) + tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM; + else if (format == 2) + tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM; + + pipe_reference_init(&tex->base.reference, 1); + tex->base.screen = screen; + + SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf); + + tex->key.cachable = 0; + tex->handle = srf; + + return &tex->base; +} + + static void svga_texture_destroy(struct pipe_texture *pt) { diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h index 89ae24219f..43853d48f8 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.h +++ b/src/gallium/drivers/svga/svga_screen_texture.h @@ -29,6 +29,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "util/u_inlines.h" #include "svga_screen_cache.h" struct pipe_context; diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index 6b0e511cec..bb92f818ea 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "svga_context.h" diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index cfdcae4ee4..b4cafb8f21 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -32,8 +32,6 @@ #include "svga_cmd.h" #include "svga_debug.h" -#include "svga_hw_reg.h" - /*********************************************************************** * Hardware state update diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index d29f3762d2..2973444d0a 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_bitmask.h" @@ -81,8 +81,10 @@ static enum pipe_error compile_fs( struct svga_context *svga, } result->id = util_bitmask_add(svga->fs_bm); - if(result->id == UTIL_BITMASK_INVALID_INDEX) + if(result->id == UTIL_BITMASK_INVALID_INDEX) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto fail; + } ret = SVGA3D_DefineShader(svga->swc, result->id, @@ -106,70 +108,6 @@ fail: return ret; } -/* The blend workaround for simulating logicop xor behaviour requires - * that the incoming fragment color be white. This change achieves - * that by hooking up a hard-wired fragment shader that just emits - * color 1,1,1,1 - * - * This is a slightly incomplete solution as it assumes that the - * actual bound shader has no other effects beyond generating a - * fragment color. In particular shaders containing TEXKIL and/or - * depth-write will not have the correct behaviour, nor will those - * expecting to use alphatest. - * - * These are avoidable issues, but they are not much worse than the - * unavoidable ones associated with this technique, so it's not clear - * how much effort should be expended trying to resolve them - the - * ultimate result will still not be correct in most cases. - * - * Shader below was generated with: - * SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt - */ -static int emit_white_fs( struct svga_context *svga ) -{ - int ret = PIPE_ERROR; - - /* ps_3_0 - * def c0, 1.000000, 0.000000, 0.000000, 1.000000 - * mov oC0, c0.x - * end - */ - static const unsigned white_tokens[] = { - 0xffff0300, - 0x05000051, - 0xa00f0000, - 0x3f800000, - 0x00000000, - 0x00000000, - 0x3f800000, - 0x02000001, - 0x800f0800, - 0xa0000000, - 0x0000ffff, - }; - - assert(SVGA3D_INVALID_ID == UTIL_BITMASK_INVALID_INDEX); - svga->state.white_fs_id = util_bitmask_add(svga->fs_bm); - if(svga->state.white_fs_id == SVGA3D_INVALID_ID) - goto no_fs_id; - - ret = SVGA3D_DefineShader(svga->swc, - svga->state.white_fs_id, - SVGA3D_SHADERTYPE_PS, - white_tokens, - sizeof(white_tokens)); - if (ret) - goto no_definition; - - return 0; - -no_definition: - util_bitmask_clear(svga->fs_bm, svga->state.white_fs_id); - svga->state.white_fs_id = SVGA3D_INVALID_ID; -no_fs_id: - return ret; -} - /* SVGA_NEW_TEXTURE_BINDING * SVGA_NEW_RAST @@ -197,6 +135,23 @@ static int make_fs_key( const struct svga_context *svga, PIPE_WINDING_CW); } + /* The blend workaround for simulating logicop xor behaviour + * requires that the incoming fragment color be white. This change + * achieves that by creating a varient of the current fragment + * shader that overrides all output colors with 1,1,1,1 + * + * This will work for most shaders, including those containing + * TEXKIL and/or depth-write. However, it will break on the + * combination of xor-logicop plus alphatest. + * + * Ultimately, we could implement alphatest in the shader using + * texkil prior to overriding the outgoing fragment color. + * + * SVGA_NEW_BLEND + */ + if (svga->curr.blend->need_white_fragments) { + key->white_fragments = 1; + } /* XXX: want to limit this to the textures that the shader actually * refers to. @@ -236,40 +191,29 @@ static int emit_hw_fs( struct svga_context *svga, unsigned id = SVGA3D_INVALID_ID; int ret = 0; + struct svga_fragment_shader *fs = svga->curr.fs; + struct svga_fs_compile_key key; + /* SVGA_NEW_BLEND + * SVGA_NEW_TEXTURE_BINDING + * SVGA_NEW_RAST + * SVGA_NEW_NEED_SWTNL + * SVGA_NEW_SAMPLER */ - if (svga->curr.blend->need_white_fragments) { - if (svga->state.white_fs_id == SVGA3D_INVALID_ID) { - ret = emit_white_fs( svga ); - if (ret) - return ret; - } - id = svga->state.white_fs_id; - } - else { - struct svga_fragment_shader *fs = svga->curr.fs; - struct svga_fs_compile_key key; - - /* SVGA_NEW_TEXTURE_BINDING - * SVGA_NEW_RAST - * SVGA_NEW_NEED_SWTNL - * SVGA_NEW_SAMPLER - */ - ret = make_fs_key( svga, &key ); + ret = make_fs_key( svga, &key ); + if (ret) + return ret; + + result = search_fs_key( fs, &key ); + if (!result) { + ret = compile_fs( svga, fs, &key, &result ); if (ret) return ret; - - result = search_fs_key( fs, &key ); - if (!result) { - ret = compile_fs( svga, fs, &key, &result ); - if (ret) - return ret; - } - - assert (result); - id = result->id; } + assert (result); + id = result->id; + assert(id != SVGA3D_INVALID_ID); if (result != svga->state.hw_draw.fs) { diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index 3c35a8579f..dd13a89d24 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index c582e44524..5ce9b4ef4f 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -31,9 +31,6 @@ #include "svga_state.h" #include "svga_cmd.h" -#include "svga_hw_reg.h" - - struct rs_queue { unsigned rs_count; diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index b313794520..17b4785978 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -33,8 +33,6 @@ #include "svga_state.h" #include "svga_cmd.h" -#include "svga_hw_reg.h" - void svga_cleanup_tss_binding(struct svga_context *svga) { diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index c534308f50..d1066ce13b 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_upload_mgr.h" diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c index ae1e77e7d4..d7999fe53d 100644 --- a/src/gallium/drivers/svga/svga_state_vs.c +++ b/src/gallium/drivers/svga/svga_state_vs.c @@ -23,7 +23,7 @@ * **********************************************************/ -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_defines.h" #include "util/u_format.h" #include "util/u_math.h" @@ -71,7 +71,7 @@ static enum pipe_error compile_vs( struct svga_context *svga, struct svga_shader_result **out_result ) { struct svga_shader_result *result; - enum pipe_error ret = PIPE_OK; + enum pipe_error ret = PIPE_ERROR; result = svga_translate_vertex_program( vs, key ); if (result == NULL) { @@ -80,8 +80,10 @@ static enum pipe_error compile_vs( struct svga_context *svga, } result->id = util_bitmask_add(svga->vs_bm); - if(result->id == UTIL_BITMASK_INVALID_INDEX) + if(result->id == UTIL_BITMASK_INVALID_INDEX) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto fail; + } ret = SVGA3D_DefineShader(svga->swc, result->id, @@ -200,10 +202,12 @@ static int update_zero_stride( struct svga_context *svga, key.output_stride = 4 * sizeof(float); key.nr_elements = 1; + key.element[0].type = TRANSLATE_ELEMENT_NORMAL; key.element[0].input_format = vel->src_format; key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; key.element[0].input_buffer = vel->vertex_buffer_index; key.element[0].input_offset = vel->src_offset; + key.element[0].instance_divisor = vel->instance_divisor; key.element[0].output_offset = const_idx * 4 * sizeof(float); translate_key_sanitize(&key); @@ -222,7 +226,7 @@ static int update_zero_stride( struct svga_context *svga, translate->set_buffer(translate, vel->vertex_buffer_index, mapped_buffer, vbuffer->stride); - translate->run(translate, 0, 1, + translate->run(translate, 0, 1, 0, svga->curr.zero_stride_constants); pipe_buffer_unmap(svga->pipe.screen, diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index b4f757a47a..e9d7942fb5 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -28,10 +28,9 @@ #include "draw/draw_vertex.h" #include "util/u_debug.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "util/u_simple_shaders.h" #include "svga_context.h" #include "svga_state.h" @@ -87,13 +86,13 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, if (!svga_render->vbuf) { svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); svga_render->vbuf = pipe_buffer_create(screen, - 0, + 16, PIPE_BUFFER_USAGE_VERTEX, svga_render->vbuf_size); if(!svga_render->vbuf) { svga_context_flush(svga, NULL); svga_render->vbuf = pipe_buffer_create(screen, - 0, + 16, PIPE_BUFFER_USAGE_VERTEX, svga_render->vbuf_size); assert(svga_render->vbuf); @@ -123,7 +122,9 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) char *ptr = (char*)pipe_buffer_map(screen, svga_render->vbuf, PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD | + PIPE_BUFFER_USAGE_UNSYNCHRONIZED); return ptr + svga_render->vbuf_offset; } @@ -259,14 +260,14 @@ svga_vbuf_render_draw( struct vbuf_render *render, if (!svga_render->ibuf) { svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); svga_render->ibuf = pipe_buffer_create(screen, - 0, + 2, PIPE_BUFFER_USAGE_VERTEX, svga_render->ibuf_size); svga_render->ibuf_offset = 0; } - pipe_buffer_write(screen, svga_render->ibuf, - svga_render->ibuf_offset, 2 * nr_indices, indices); + pipe_buffer_write_nooverlap(screen, svga_render->ibuf, + svga_render->ibuf_offset, 2 * nr_indices, indices); /* off to hardware */ diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index 7655121bec..da15be155c 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -25,9 +25,8 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "svga_context.h" #include "svga_swtnl.h" @@ -90,7 +89,7 @@ svga_swtnl_draw_range_elements(struct svga_context *svga, PIPE_BUFFER_USAGE_CPU_READ); assert(map); draw_set_mapped_constant_buffer( - draw, PIPE_SHADER_VERTEX, + draw, PIPE_SHADER_VERTEX, 0, map, svga->curr.cb[PIPE_SHADER_VERTEX]->size); } diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c index 94b6ccc62d..35f36a828f 100644 --- a/src/gallium/drivers/svga/svga_swtnl_state.c +++ b/src/gallium/drivers/svga/svga_swtnl_state.c @@ -25,9 +25,8 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "svga_context.h" #include "svga_swtnl.h" diff --git a/src/gallium/drivers/svga/svga_tgsi.h b/src/gallium/drivers/svga/svga_tgsi.h index 737a2213af..063c9cf422 100644 --- a/src/gallium/drivers/svga/svga_tgsi.h +++ b/src/gallium/drivers/svga/svga_tgsi.h @@ -49,6 +49,7 @@ struct svga_fs_compile_key { unsigned light_twoside:1; unsigned front_cw:1; + unsigned white_fragments:1; unsigned num_textures:8; unsigned num_unnormalized_coords:8; struct { diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c index 23b3ace7f3..1ae9906761 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c @@ -29,9 +29,6 @@ #include "util/u_memory.h" #include "svga_tgsi_emit.h" -#include "svga_context.h" - - static boolean ps20_input( struct svga_shader_emitter *emit, diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c index d1c7336dec..73102a72a8 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c @@ -29,7 +29,6 @@ #include "util/u_memory.h" #include "svga_tgsi_emit.h" -#include "svga_context.h" static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic, unsigned *usage, @@ -195,8 +194,19 @@ static boolean ps30_output( struct svga_shader_emitter *emit, switch (semantic.Name) { case TGSI_SEMANTIC_COLOR: - emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, - semantic.Index ); + if (emit->unit == PIPE_SHADER_FRAGMENT && + emit->key.fkey.white_fragments) { + + emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, + emit->nr_hw_temp++ ); + emit->temp_col[idx] = emit->output_map[idx]; + emit->true_col[idx] = dst_register( SVGA3DREG_COLOROUT, + semantic.Index ); + } + else { + emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, + semantic.Index ); + } break; case TGSI_SEMANTIC_POSITION: emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, diff --git a/src/gallium/drivers/svga/svga_tgsi_emit.h b/src/gallium/drivers/svga/svga_tgsi_emit.h index 2557824293..e8f75485d5 100644 --- a/src/gallium/drivers/svga/svga_tgsi_emit.h +++ b/src/gallium/drivers/svga/svga_tgsi_emit.h @@ -79,6 +79,8 @@ struct svga_shader_emitter int ps30_input_count; + int dynamic_branching_level; + boolean in_main_func; boolean created_zero_immediate; @@ -199,6 +201,23 @@ static INLINE boolean emit_op3( struct svga_shader_emitter *emit, } +static INLINE boolean emit_op4( struct svga_shader_emitter *emit, + SVGA3dShaderInstToken inst, + SVGA3dShaderDestToken dest, + struct src_register src0, + struct src_register src1, + struct src_register src2, + struct src_register src3) +{ + return (emit_instruction( emit, inst ) && + emit_dst( emit, dest ) && + emit_src( emit, src0 ) && + emit_src( emit, src1 ) && + emit_src( emit, src2 ) && + emit_src( emit, src3 )); +} + + #define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6)) #define SWIZZLE_XYZW \ TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W) diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index dc5eb8fc60..be821e9821 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -46,8 +46,6 @@ translate_opcode( case TGSI_OPCODE_ABS: return SVGA3DOP_ABS; case TGSI_OPCODE_ADD: return SVGA3DOP_ADD; case TGSI_OPCODE_BREAKC: return SVGA3DOP_BREAKC; - case TGSI_OPCODE_DDX: return SVGA3DOP_DSX; - case TGSI_OPCODE_DDY: return SVGA3DOP_DSY; case TGSI_OPCODE_DP2A: return SVGA3DOP_DP2ADD; case TGSI_OPCODE_DP3: return SVGA3DOP_DP3; case TGSI_OPCODE_DP4: return SVGA3DOP_DP4; @@ -415,6 +413,88 @@ static boolean submit_op3( struct svga_shader_emitter *emit, } + + +/* SVGA shaders may not refer to >1 constant register in a single + * instruction. This function checks for that usage and inserts a + * move to temporary if detected. + */ +static boolean submit_op4( struct svga_shader_emitter *emit, + SVGA3dShaderInstToken inst, + SVGA3dShaderDestToken dest, + struct src_register src0, + struct src_register src1, + struct src_register src2, + struct src_register src3) +{ + SVGA3dShaderDestToken temp0; + SVGA3dShaderDestToken temp3; + boolean need_temp0 = FALSE; + boolean need_temp3 = FALSE; + SVGA3dShaderRegType type0, type1, type2, type3; + + temp0.value = 0; + temp3.value = 0; + type0 = SVGA3dShaderGetRegType( src0.base.value ); + type1 = SVGA3dShaderGetRegType( src1.base.value ); + type2 = SVGA3dShaderGetRegType( src2.base.value ); + type3 = SVGA3dShaderGetRegType( src2.base.value ); + + /* Make life a little easier - this is only used by the TXD + * instruction which is guaranteed not to have a constant/input reg + * in one slot at least: + */ + assert(type1 == SVGA3DREG_SAMPLER); + + if (type0 == SVGA3DREG_CONST && + ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) || + (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num))) + need_temp0 = TRUE; + + if (type3 == SVGA3DREG_CONST && + (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num)) + need_temp3 = TRUE; + + if (type0 == SVGA3DREG_INPUT && + ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) || + (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num))) + need_temp0 = TRUE; + + if (type3 == SVGA3DREG_INPUT && + (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num)) + need_temp3 = TRUE; + + if (need_temp0) + { + temp0 = get_temp( emit ); + + if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 )) + return FALSE; + + src0 = src( temp0 ); + } + + if (need_temp3) + { + temp3 = get_temp( emit ); + + if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp3, src3 )) + return FALSE; + + src3 = src( temp3 ); + } + + if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 )) + return FALSE; + + if (need_temp3) + release_temp( emit, temp3 ); + if (need_temp0) + release_temp( emit, temp0 ); + return TRUE; +} + + static boolean emit_def_const( struct svga_shader_emitter *emit, SVGA3dShaderConstType type, unsigned idx, @@ -660,6 +740,8 @@ static boolean emit_if(struct svga_shader_emitter *emit, if_token.control = SVGA3DOPCOMPC_NE; zero = scalar(zero, TGSI_SWIZZLE_X); + emit->dynamic_branching_level++; + return (emit_instruction( emit, if_token ) && emit_src( emit, src ) && emit_src( emit, zero ) ); @@ -668,6 +750,8 @@ static boolean emit_if(struct svga_shader_emitter *emit, static boolean emit_endif(struct svga_shader_emitter *emit, const struct tgsi_full_instruction *insn) { + emit->dynamic_branching_level--; + return (emit_instruction( emit, inst_token( SVGA3DOP_ENDIF ))); } @@ -1011,10 +1095,10 @@ static boolean emit_kilp(struct svga_shader_emitter *emit, { SVGA3dShaderInstToken inst; SVGA3dShaderDestToken temp; - struct src_register one = get_zero_immediate( emit ); + struct src_register one = scalar( get_zero_immediate( emit ), + TGSI_SWIZZLE_W ); inst = inst_token( SVGA3DOP_TEXKILL ); - one = scalar( one, TGSI_SWIZZLE_W ); /* texkill doesn't allow negation on the operand so lets move * negation of {1} to a temp register */ @@ -1169,41 +1253,79 @@ static boolean emit_tex2(struct svga_shader_emitter *emit, SVGA3dShaderDestToken dst ) { SVGA3dShaderInstToken inst; - struct src_register src0; - struct src_register src1; - + struct src_register texcoord; + struct src_register sampler; + SVGA3dShaderDestToken tmp; + inst.value = 0; - inst.op = SVGA3DOP_TEX; switch (insn->Instruction.Opcode) { case TGSI_OPCODE_TEX: + inst.op = SVGA3DOP_TEX; break; case TGSI_OPCODE_TXP: + inst.op = SVGA3DOP_TEX; inst.control = SVGA3DOPCONT_PROJECT; break; case TGSI_OPCODE_TXB: + inst.op = SVGA3DOP_TEX; inst.control = SVGA3DOPCONT_BIAS; break; + case TGSI_OPCODE_TXL: + inst.op = SVGA3DOP_TEXLDL; + break; default: assert(0); return FALSE; } - src0 = translate_src_register( emit, &insn->Src[0] ); - src1 = translate_src_register( emit, &insn->Src[1] ); + texcoord = translate_src_register( emit, &insn->Src[0] ); + sampler = translate_src_register( emit, &insn->Src[1] ); - if (emit->key.fkey.tex[src1.base.num].unnormalized) { - struct src_register wh = get_tex_dimensions( emit, src1.base.num ); - SVGA3dShaderDestToken tmp = get_temp( emit ); + if (emit->key.fkey.tex[sampler.base.num].unnormalized || + emit->dynamic_branching_level > 0) + tmp = get_temp( emit ); + + /* Can't do mipmapping inside dynamic branch constructs. Force LOD + * zero in that case. + */ + if (emit->dynamic_branching_level > 0 && + inst.op == SVGA3DOP_TEX && + SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) { + struct src_register zero = get_zero_immediate( emit ); + + /* MOV tmp, texcoord */ + if (!submit_op1( emit, + inst_token( SVGA3DOP_MOV ), + tmp, + texcoord )) + return FALSE; + + /* MOV tmp.w, zero */ + if (!submit_op1( emit, + inst_token( SVGA3DOP_MOV ), + writemask( tmp, TGSI_WRITEMASK_W ), + scalar( zero, TGSI_SWIZZLE_X ))) + return FALSE; + + texcoord = src( tmp ); + inst.op = SVGA3DOP_TEXLDL; + } + + /* Explicit normalization of texcoords: + */ + if (emit->key.fkey.tex[sampler.base.num].unnormalized) { + struct src_register wh = get_tex_dimensions( emit, sampler.base.num ); /* MUL tmp, SRC0, WH */ if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), - tmp, src0, wh )) + tmp, texcoord, wh )) return FALSE; - src0 = src( tmp ); + + texcoord = src( tmp ); } - return submit_op2( emit, inst, dst, src0, src1 ); + return submit_op2( emit, inst, dst, texcoord, sampler ); } @@ -1211,31 +1333,33 @@ static boolean emit_tex2(struct svga_shader_emitter *emit, /* Translate texture instructions to SVGA3D representation. */ -static boolean emit_tex3(struct svga_shader_emitter *emit, +static boolean emit_tex4(struct svga_shader_emitter *emit, const struct tgsi_full_instruction *insn, SVGA3dShaderDestToken dst ) { SVGA3dShaderInstToken inst; - struct src_register src0; - struct src_register src1; - struct src_register src2; + struct src_register texcoord; + struct src_register ddx; + struct src_register ddy; + struct src_register sampler; + + texcoord = translate_src_register( emit, &insn->Src[0] ); + ddx = translate_src_register( emit, &insn->Src[1] ); + ddy = translate_src_register( emit, &insn->Src[2] ); + sampler = translate_src_register( emit, &insn->Src[3] ); inst.value = 0; switch (insn->Instruction.Opcode) { case TGSI_OPCODE_TXD: - inst.op = SVGA3DOP_TEXLDD; - break; - case TGSI_OPCODE_TXL: - inst.op = SVGA3DOP_TEXLDL; + inst.op = SVGA3DOP_TEXLDD; /* 4 args! */ break; + default: + assert(0); + return FALSE; } - src0 = translate_src_register( emit, &insn->Src[0] ); - src1 = translate_src_register( emit, &insn->Src[1] ); - src2 = translate_src_register( emit, &insn->Src[2] ); - - return submit_op3( emit, inst, dst, src0, src1, src2 ); + return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy ); } @@ -1271,12 +1395,12 @@ static boolean emit_tex(struct svga_shader_emitter *emit, case TGSI_OPCODE_TEX: case TGSI_OPCODE_TXB: case TGSI_OPCODE_TXP: + case TGSI_OPCODE_TXL: if (!emit_tex2( emit, insn, tex_result )) return FALSE; break; - case TGSI_OPCODE_TXL: case TGSI_OPCODE_TXD: - if (!emit_tex3( emit, insn, tex_result )) + if (!emit_tex4( emit, insn, tex_result )) return FALSE; break; default: @@ -1330,6 +1454,8 @@ static boolean emit_bgnloop2( struct svga_shader_emitter *emit, struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 ); struct src_register const_int = get_loop_const( emit ); + emit->dynamic_branching_level++; + return (emit_instruction( emit, inst ) && emit_src( emit, loop_reg ) && emit_src( emit, const_int ) ); @@ -1339,6 +1465,9 @@ static boolean emit_endloop2( struct svga_shader_emitter *emit, const struct tgsi_full_instruction *insn ) { SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP ); + + emit->dynamic_branching_level--; + return emit_instruction( emit, inst ); } @@ -1398,6 +1527,46 @@ static boolean emit_simple_instruction(struct svga_shader_emitter *emit, } } + +static boolean emit_deriv(struct svga_shader_emitter *emit, + const struct tgsi_full_instruction *insn ) +{ + if (emit->dynamic_branching_level > 0 && + insn->Src[0].Register.File == TGSI_FILE_TEMPORARY) + { + struct src_register zero = get_zero_immediate( emit ); + SVGA3dShaderDestToken dst = + translate_dst_register( emit, insn, 0 ); + + /* Deriv opcodes not valid inside dynamic branching, workaround + * by zeroing out the destination. + */ + if (!submit_op1(emit, + inst_token( SVGA3DOP_MOV ), + dst, + scalar(zero, TGSI_SWIZZLE_X))) + return FALSE; + + return TRUE; + } + else { + unsigned opcode; + + switch (insn->Instruction.Opcode) { + case TGSI_OPCODE_DDX: + opcode = SVGA3DOP_DSX; + break; + case TGSI_OPCODE_DDY: + opcode = SVGA3DOP_DSY; + break; + default: + return FALSE; + } + + return emit_simple_instruction( emit, opcode, insn ); + } +} + static boolean emit_arl(struct svga_shader_emitter *emit, const struct tgsi_full_instruction *insn) { @@ -2002,6 +2171,10 @@ static boolean svga_emit_instruction( struct svga_shader_emitter *emit, case TGSI_OPCODE_TXD: return emit_tex( emit, insn ); + case TGSI_OPCODE_DDX: + case TGSI_OPCODE_DDY: + return emit_deriv( emit, insn ); + case TGSI_OPCODE_BGNSUB: return emit_bgnsub( emit, position, insn ); @@ -2254,11 +2427,28 @@ static boolean emit_ps_postamble( struct svga_shader_emitter *emit ) for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) { - if (!submit_op1( emit, - inst_token(SVGA3DOP_MOV), - emit->true_col[i], - src(emit->temp_col[i]) )) - return FALSE; + /* Potentially override output colors with white for XOR + * logicop workaround. + */ + if (emit->unit == PIPE_SHADER_FRAGMENT && + emit->key.fkey.white_fragments) { + + struct src_register one = scalar( get_zero_immediate( emit ), + TGSI_SWIZZLE_W ); + + if (!submit_op1( emit, + inst_token(SVGA3DOP_MOV), + emit->true_col[i], + one )) + return FALSE; + } + else { + if (!submit_op1( emit, + inst_token(SVGA3DOP_MOV), + emit->true_col[i], + src(emit->temp_col[i]) )) + return FALSE; + } } } @@ -2467,6 +2657,9 @@ needs_to_create_zero( struct svga_shader_emitter *emit ) if (emit->key.fkey.light_twoside) return TRUE; + if (emit->key.fkey.white_fragments) + return TRUE; + if (emit->emit_frontface) return TRUE; @@ -2476,6 +2669,10 @@ needs_to_create_zero( struct svga_shader_emitter *emit ) } if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 || + emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 || + emit->info.opcode_count[TGSI_OPCODE_BGNFOR] >= 1 || + emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 || + emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 || emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 || emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 || emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 || @@ -2702,6 +2899,8 @@ boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit, goto done; } + assert(emit->dynamic_branching_level == 0); + /* Need to terminate the whole shader: */ ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) ); diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 59f299c185..b4e3af0eaf 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -272,9 +272,6 @@ struct svga_winsys_screen }; -struct pipe_context * -svga_context_create(struct pipe_screen *screen); - struct pipe_screen * svga_screen_create(struct svga_winsys_screen *sws); @@ -296,4 +293,10 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture, struct pipe_buffer **buffer, unsigned *stride); +struct pipe_texture * +svga_screen_texture_wrap_surface(struct pipe_screen *screen, + struct pipe_texture *base, + enum SVGA3dSurfaceFormat format, + struct svga_winsys_surface *srf); + #endif /* SVGA_WINSYS_H_ */ diff --git a/src/gallium/drivers/trace/tr_buffer.c b/src/gallium/drivers/trace/tr_buffer.c index 4f0eff6a5a..fa2ac068eb 100644 --- a/src/gallium/drivers/trace/tr_buffer.c +++ b/src/gallium/drivers/trace/tr_buffer.c @@ -26,6 +26,7 @@ **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_simple_list.h" diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 075e4f9a0b..34ceaa41c1 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -812,13 +812,13 @@ trace_context_set_clip_state(struct pipe_context *_pipe, static INLINE void trace_context_set_constant_buffer(struct pipe_context *_pipe, uint shader, uint index, - const struct pipe_constant_buffer *buffer) + struct pipe_buffer *buffer) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; if (buffer) - trace_screen_user_buffer_update(_pipe->screen, buffer->buffer); + trace_screen_user_buffer_update(_pipe->screen, buffer); trace_dump_call_begin("pipe_context", "set_constant_buffer"); @@ -827,10 +827,11 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, trace_dump_arg(uint, index); trace_dump_arg(constant_buffer, buffer); + /* XXX hmm? */ if (buffer) { - struct pipe_constant_buffer _buffer; - _buffer.buffer = trace_buffer_unwrap(tr_ctx, buffer->buffer); - pipe->set_constant_buffer(pipe, shader, index, &_buffer); + struct pipe_buffer *_buffer; + _buffer = trace_buffer_unwrap(tr_ctx, buffer); + pipe->set_constant_buffer(pipe, shader, index, _buffer); } else { pipe->set_constant_buffer(pipe, shader, index, buffer); } @@ -1235,12 +1236,10 @@ static const struct debug_named_value rbug_blocker_flags[] = { }; struct pipe_context * -trace_context_create(struct pipe_screen *_screen, +trace_context_create(struct trace_screen *tr_scr, struct pipe_context *pipe) { - struct trace_screen *tr_scr; struct trace_context *tr_ctx; - struct pipe_screen *screen; if(!pipe) goto error1; @@ -1248,13 +1247,13 @@ trace_context_create(struct pipe_screen *_screen, if(!trace_enabled()) goto error1; - tr_scr = trace_screen(_screen); - screen = tr_scr->screen; - tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) goto error1; + tr_ctx->base.winsys = NULL; + tr_ctx->base.priv = pipe->priv; /* expose wrapped priv data */ + tr_ctx->base.screen = &tr_scr->base; tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK", rbug_blocker_flags, 0); @@ -1263,8 +1262,6 @@ trace_context_create(struct pipe_screen *_screen, pipe_mutex_init(tr_ctx->list_mutex); make_empty_list(&tr_ctx->shaders); - tr_ctx->base.winsys = _screen->winsys; - tr_ctx->base.screen = _screen; tr_ctx->base.destroy = trace_context_destroy; tr_ctx->base.draw_arrays = trace_context_draw_arrays; tr_ctx->base.draw_elements = trace_context_draw_elements; @@ -1315,11 +1312,6 @@ trace_context_create(struct pipe_screen *_screen, tr_ctx->pipe = pipe; - trace_dump_call_begin("", "pipe_context_create"); - trace_dump_arg(ptr, screen); - trace_dump_ret(ptr, pipe); - trace_dump_call_end(); - trace_screen_add_to_list(tr_scr, contexts, tr_ctx); return &tr_ctx->base; diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 852b480765..1428423248 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -40,6 +40,8 @@ extern "C" { #endif +struct trace_screen; + struct trace_context { struct pipe_context base; @@ -95,9 +97,8 @@ trace_context(struct pipe_context *pipe) } - struct pipe_context * -trace_context_create(struct pipe_screen *screen, +trace_context_create(struct trace_screen *tr_scr, struct pipe_context *pipe); void diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c index 48d1c4051c..919dc1b309 100644 --- a/src/gallium/drivers/trace/tr_drm.c +++ b/src/gallium/drivers/trace/tr_drm.c @@ -65,24 +65,6 @@ trace_drm_create_screen(struct drm_api *_api, int fd, return trace_screen_create(screen); } -static struct pipe_context * -trace_drm_create_context(struct drm_api *_api, - struct pipe_screen *_screen) -{ - struct trace_screen *tr_screen = trace_screen(_screen); - struct trace_drm_api *tr_api = trace_drm_api(_api); - struct pipe_screen *screen = tr_screen->screen; - struct drm_api *api = tr_api->api; - struct pipe_context *pipe; - - /* TODO trace call */ - - pipe = api->create_context(api, screen); - - pipe = trace_context_create(_screen, pipe); - - return pipe; -} static struct pipe_texture * trace_drm_texture_from_shared_handle(struct drm_api *_api, @@ -173,8 +155,8 @@ trace_drm_create(struct drm_api *api) if (!tr_api) goto error; + tr_api->base.driver_name = api->driver_name; tr_api->base.create_screen = trace_drm_create_screen; - tr_api->base.create_context = trace_drm_create_context; tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle; tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture; tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 0f45e211a3..8de451c22c 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -45,11 +45,11 @@ #endif #include "pipe/p_compiler.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" +#include "os/os_stream.h" #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_string.h" -#include "util/u_stream.h" #include "tr_dump.h" #include "tr_screen.h" @@ -57,7 +57,7 @@ #include "tr_buffer.h" -static struct util_stream *stream = NULL; +static struct os_stream *stream = NULL; static unsigned refcount = 0; static pipe_mutex call_mutex; static long unsigned call_no = 0; @@ -69,7 +69,7 @@ static INLINE void trace_dump_write(const char *buf, size_t size) { if(stream) - util_stream_write(stream, buf, size); + os_stream_write(stream, buf, size); } @@ -220,7 +220,7 @@ trace_dump_trace_close(void) { if(stream) { trace_dump_writes("</trace>\n"); - util_stream_close(stream); + os_stream_close(stream); stream = NULL; refcount = 0; call_no = 0; @@ -250,7 +250,7 @@ boolean trace_dump_trace_begin() if(!stream) { - stream = util_stream_create(filename, 0); + stream = os_stream_create(filename, 0); if(!stream) return FALSE; @@ -367,7 +367,7 @@ void trace_dump_call_end_locked(void) trace_dump_indent(1); trace_dump_tag_end("call"); trace_dump_newline(); - util_stream_flush(stream); + os_stream_flush(stream); } void trace_dump_call_begin(const char *klass, const char *method) diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 720b6cd1ff..6648539a0f 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -49,7 +49,7 @@ static void trace_dump_reference(const struct pipe_reference *reference) return; trace_dump_struct_begin("pipe_reference"); - trace_dump_member(int, &reference->count, count); + trace_dump_member(int, reference, count); trace_dump_struct_end(); } @@ -227,7 +227,7 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) } -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) +void trace_dump_constant_buffer(const struct pipe_buffer *state) { if (!trace_dumping_enabled_locked()) return; @@ -239,7 +239,7 @@ void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) trace_dump_struct_begin("pipe_constant_buffer"); - trace_dump_member(buffer_ptr, state, buffer); + trace_dump_reference(&state->reference); trace_dump_struct_end(); } @@ -321,9 +321,23 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ trace_dump_struct_end(); } +static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state) +{ + trace_dump_member(uint, state, rgb_func); + trace_dump_member(uint, state, rgb_src_factor); + trace_dump_member(uint, state, rgb_dst_factor); + + trace_dump_member(uint, state, alpha_func); + trace_dump_member(uint, state, alpha_src_factor); + trace_dump_member(uint, state, alpha_dst_factor); + + trace_dump_member(uint, state, colormask); + +} void trace_dump_blend_state(const struct pipe_blend_state *state) { + unsigned valid_entries = 1; if (!trace_dumping_enabled_locked()) return; @@ -334,21 +348,17 @@ void trace_dump_blend_state(const struct pipe_blend_state *state) trace_dump_struct_begin("pipe_blend_state"); - trace_dump_member(bool, state, blend_enable); - - trace_dump_member(uint, state, rgb_func); - trace_dump_member(uint, state, rgb_src_factor); - trace_dump_member(uint, state, rgb_dst_factor); - - trace_dump_member(uint, state, alpha_func); - trace_dump_member(uint, state, alpha_src_factor); - trace_dump_member(uint, state, alpha_dst_factor); + trace_dump_member(bool, state, dither); trace_dump_member(bool, state, logicop_enable); trace_dump_member(uint, state, logicop_func); - trace_dump_member(uint, state, colormask); - trace_dump_member(bool, state, dither); + trace_dump_member(bool, state, independent_blend_enable); + + if (state->independent_blend_enable) + valid_entries = PIPE_MAX_COLOR_BUFS; + + trace_dump_struct_array(rt_blend_state, state->rt, valid_entries); trace_dump_struct_end(); } @@ -410,7 +420,6 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state) trace_dump_member(uint, state, compare_mode); trace_dump_member(uint, state, compare_func); trace_dump_member(bool, state, normalized_coords); - trace_dump_member(uint, state, prefilter); trace_dump_member(float, state, lod_bias); trace_dump_member(float, state, min_lod); trace_dump_member(float, state, max_lod); diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h index 07ad6fbb20..c7860fd6e1 100644 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -47,7 +47,7 @@ void trace_dump_scissor_state(const struct pipe_scissor_state *state); void trace_dump_clip_state(const struct pipe_clip_state *state); -void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); +void trace_dump_constant_buffer(const struct pipe_buffer *state); void trace_dump_token(const struct tgsi_token *token); diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index 0546aad9b5..691b83c63f 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -26,11 +26,13 @@ **************************************************************************/ +#include "os/os_thread.h" #include "util/u_format.h" #include "util/u_string.h" #include "util/u_memory.h" #include "util/u_simple_list.h" #include "util/u_network.h" +#include "util/u_time.h" #include "tgsi/tgsi_parse.h" @@ -43,15 +45,6 @@ #include <errno.h> -#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) -# define sleep Sleep -#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_APPLE) -void usleep(int); -# define sleep usleep -#else -# warning "No socket implementation" -#endif - #define U642VOID(x) ((void *)(unsigned long)(x)) #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) @@ -805,7 +798,7 @@ PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug) debug_printf("trace_rbug - remote debugging listening on port %u\n", --port); while(tr_rbug->running) { - sleep(1); + util_time_sleep(1); c = u_socket_accept(s); if (c < 0) diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 117503aaff..388d83eb5c 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -33,9 +33,10 @@ #include "tr_dump.h" #include "tr_dump_state.h" #include "tr_texture.h" +#include "tr_context.h" #include "tr_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_format.h" @@ -159,6 +160,29 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, } +static struct pipe_context * +trace_screen_context_create(struct pipe_screen *_screen, void *priv) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct pipe_screen *screen = tr_scr->screen; + struct pipe_context *result; + + trace_dump_call_begin("pipe_screen", "context_create"); + + trace_dump_arg(ptr, screen); + + result = screen->context_create(screen, priv); + + trace_dump_ret(ptr, result); + + trace_dump_call_end(); + + result = trace_context_create(tr_scr, result); + + return result; +} + + static void trace_screen_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_surface *_surface, @@ -904,6 +928,8 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.get_param = trace_screen_get_param; tr_scr->base.get_paramf = trace_screen_get_paramf; tr_scr->base.is_format_supported = trace_screen_is_format_supported; + assert(screen->context_create); + tr_scr->base.context_create = trace_screen_context_create; tr_scr->base.texture_create = trace_screen_texture_create; tr_scr->base.texture_blanket = trace_screen_texture_blanket; tr_scr->base.texture_destroy = trace_screen_texture_destroy; diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index dba8cd7c65..fe5a0fa190 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -30,7 +30,7 @@ #include "pipe/p_screen.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #ifdef __cplusplus diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index 1f25fe38d4..5321d68ec0 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "util/u_inlines.h" #include "util/u_hash_table.h" #include "util/u_memory.h" #include "util/u_simple_list.h" diff --git a/src/gallium/include/pipe/internal/p_winsys_screen.h b/src/gallium/include/pipe/internal/p_winsys_screen.h deleted file mode 100644 index a1542dada7..0000000000 --- a/src/gallium/include/pipe/internal/p_winsys_screen.h +++ /dev/null @@ -1,190 +0,0 @@ - /************************************************************************** - * - * Copyright 2007 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. - * - **************************************************************************/ - -/** - * \file - * This is the interface that Gallium3D requires any window system - * hosting it to implement. This is the only include file in Gallium3D - * which is public. - */ - -#ifndef P_WINSYS_H -#define P_WINSYS_H - - -#include "pipe/p_format.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** Opaque type */ -struct pipe_fence_handle; - -struct pipe_surface; - - -/** - * Gallium3D drivers are (meant to be!) independent of both GL and the - * window system. The window system provides a buffer manager and a - * set of additional hooks for things like command buffer submission, - * etc. - * - * There clearly has to be some agreement between the window system - * driver and the hardware driver about the format of command buffers, - * etc. - */ -struct pipe_winsys -{ - void (*destroy)( struct pipe_winsys *ws ); - - /** Returns name of this winsys interface */ - const char *(*get_name)( struct pipe_winsys *ws ); - - /** - * Do any special operations to ensure buffer size is correct - */ - void (*update_buffer)( struct pipe_winsys *ws, - void *context_private ); - /** - * Do any special operations to ensure frontbuffer contents are - * displayed, eg copy fake frontbuffer. - */ - void (*flush_frontbuffer)( struct pipe_winsys *ws, - struct pipe_surface *surf, - void *context_private ); - - - /** - * Buffer management. Buffer attributes are mostly fixed over its lifetime. - * - * Remember that gallium gets to choose the interface it needs, and the - * window systems must then implement that interface (rather than the - * other way around...). - * - * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This - * usage argument is only an optimization hint, not a guarantee, therefore - * proper behavior must be observed in all circumstances. - * - * alignment indicates the client's alignment requirements, eg for - * SSE instructions. - */ - struct pipe_buffer *(*buffer_create)( struct pipe_winsys *ws, - unsigned alignment, - unsigned usage, - unsigned size ); - - /** - * Create a buffer that wraps user-space data. - * - * Effectively this schedules a delayed call to buffer_create - * followed by an upload of the data at *some point in the future*, - * or perhaps never. Basically the allocate/upload is delayed - * until the buffer is actually passed to hardware. - * - * The intention is to provide a quick way to turn regular data - * into a buffer, and secondly to avoid a copy operation if that - * data subsequently turns out to be only accessed by the CPU. - * - * Common example is OpenGL vertex buffers that are subsequently - * processed either by software TNL in the driver or by passing to - * hardware. - * - * XXX: What happens if the delayed call to buffer_create() fails? - * - * Note that ptr may be accessed at any time upto the time when the - * buffer is destroyed, so the data must not be freed before then. - */ - struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *ws, - void *ptr, - unsigned bytes); - - /** - * Allocate storage for a display target surface. - * - * Often surfaces which are meant to be blitted to the front screen (i.e., - * display targets) must be allocated with special characteristics, memory - * pools, or obtained directly from the windowing system. - * - * This callback is invoked by the pipe_screenwhen creating a texture marked - * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying - * buffer storage. - */ - struct pipe_buffer *(*surface_buffer_create)(struct pipe_winsys *ws, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride); - - - /** - * Map the entire data store of a buffer object into the client's address. - * flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags. - */ - void *(*buffer_map)( struct pipe_winsys *ws, - struct pipe_buffer *buf, - unsigned usage ); - - void (*buffer_unmap)( struct pipe_winsys *ws, - struct pipe_buffer *buf ); - - void (*buffer_destroy)( struct pipe_buffer *buf ); - - - /** Set ptr = fence, with reference counting */ - void (*fence_reference)( struct pipe_winsys *ws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ); - - /** - * Checks whether the fence has been signalled. - * \param flags driver-specific meaning - * \return zero on success. - */ - int (*fence_signalled)( struct pipe_winsys *ws, - struct pipe_fence_handle *fence, - unsigned flag ); - - /** - * Wait for the fence to finish. - * \param flags driver-specific meaning - * \return zero on success. - */ - int (*fence_finish)( struct pipe_winsys *ws, - struct pipe_fence_handle *fence, - unsigned flag ); - -}; - -#ifdef __cplusplus -} -#endif - -#endif /* P_WINSYS_H */ diff --git a/src/gallium/include/pipe/p_atomic.h b/src/gallium/include/pipe/p_atomic.h deleted file mode 100644 index 0c3fbae428..0000000000 --- a/src/gallium/include/pipe/p_atomic.h +++ /dev/null @@ -1,353 +0,0 @@ -/** - * Many similar implementations exist. See for example libwsbm - * or the linux kernel include/atomic.h - * - * No copyright claimed on this file. - * - */ - -#ifndef P_ATOMIC_H -#define P_ATOMIC_H - -#include "p_compiler.h" -#include "p_defines.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Favor OS-provided implementations. - * - * Where no OS-provided implementation is available, fall back to - * locally coded assembly, compiler intrinsic or ultimately a - * mutex-based implementation. - */ -#if (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \ - defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)) -#define PIPE_ATOMIC_OS_UNLOCKED -#elif (defined(PIPE_CC_MSVC) && defined(PIPE_SUBSYSTEM_WINDOWS_USER)) -#define PIPE_ATOMIC_OS_MS_INTERLOCK -#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)) -#define PIPE_ATOMIC_ASM_MSVC_X86 -#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) -#define PIPE_ATOMIC_ASM_GCC_X86 -#elif defined(PIPE_CC_GCC) -#define PIPE_ATOMIC_GCC_INTRINSIC -#else -#define PIPE_ATOMIC_MUTEX -#endif - - - -#if defined(PIPE_ATOMIC_ASM_GCC_X86) - -#define PIPE_ATOMIC "GCC x86 assembly" - -struct pipe_atomic { - int32_t count; -}; - -#define p_atomic_set(_v, _i) ((_v)->count = (_i)) -#define p_atomic_read(_v) ((_v)->count) - - -static INLINE boolean -p_atomic_dec_zero(struct pipe_atomic *v) -{ - unsigned char c; - - __asm__ __volatile__("lock; decl %0; sete %1":"+m"(v->count), "=qm"(c) - ::"memory"); - - return c != 0; -} - -static INLINE void -p_atomic_inc(struct pipe_atomic *v) -{ - __asm__ __volatile__("lock; incl %0":"+m"(v->count)); -} - -static INLINE void -p_atomic_dec(struct pipe_atomic *v) -{ - __asm__ __volatile__("lock; decl %0":"+m"(v->count)); -} - -static INLINE int32_t -p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) -{ - return __sync_val_compare_and_swap(&v->count, old, _new); -} -#endif - - - -/* Implementation using GCC-provided synchronization intrinsics - */ -#if defined(PIPE_ATOMIC_GCC_INTRINSIC) - -#define PIPE_ATOMIC "GCC Sync Intrinsics" - -struct pipe_atomic { - int32_t count; -}; - -#define p_atomic_set(_v, _i) ((_v)->count = (_i)) -#define p_atomic_read(_v) ((_v)->count) - - -static INLINE boolean -p_atomic_dec_zero(struct pipe_atomic *v) -{ - return (__sync_sub_and_fetch(&v->count, 1) == 0); -} - -static INLINE void -p_atomic_inc(struct pipe_atomic *v) -{ - (void) __sync_add_and_fetch(&v->count, 1); -} - -static INLINE void -p_atomic_dec(struct pipe_atomic *v) -{ - (void) __sync_sub_and_fetch(&v->count, 1); -} - -static INLINE int32_t -p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) -{ - return __sync_val_compare_and_swap(&v->count, old, _new); -} -#endif - - - -/* Unlocked version for single threaded environments, such as some - * windows kernel modules. - */ -#if defined(PIPE_ATOMIC_OS_UNLOCKED) - -#define PIPE_ATOMIC "Unlocked" - -struct pipe_atomic -{ - int32_t count; -}; - -#define p_atomic_set(_v, _i) ((_v)->count = (_i)) -#define p_atomic_read(_v) ((_v)->count) -#define p_atomic_dec_zero(_v) ((boolean) --(_v)->count) -#define p_atomic_inc(_v) ((void) (_v)->count++) -#define p_atomic_dec(_v) ((void) (_v)->count--) -#define p_atomic_cmpxchg(_v, old, _new) ((_v)->count == old ? (_v)->count = (_new) : (_v)->count) - -#endif - - -/* Locally coded assembly for MSVC on x86: - */ -#if defined(PIPE_ATOMIC_ASM_MSVC_X86) - -#define PIPE_ATOMIC "MSVC x86 assembly" - -struct pipe_atomic -{ - int32_t count; -}; - -#define p_atomic_set(_v, _i) ((_v)->count = (_i)) -#define p_atomic_read(_v) ((_v)->count) - -static INLINE boolean -p_atomic_dec_zero(struct pipe_atomic *v) -{ - int32_t *pcount = &v->count; - unsigned char c; - - __asm { - mov eax, [pcount] - lock dec dword ptr [eax] - sete byte ptr [c] - } - - return c != 0; -} - -static INLINE void -p_atomic_inc(struct pipe_atomic *v) -{ - int32_t *pcount = &v->count; - - __asm { - mov eax, [pcount] - lock inc dword ptr [eax] - } -} - -static INLINE void -p_atomic_dec(struct pipe_atomic *v) -{ - int32_t *pcount = &v->count; - - __asm { - mov eax, [pcount] - lock dec dword ptr [eax] - } -} - -static INLINE int32_t -p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) -{ - int32_t *pcount = &v->count; - int32_t orig; - - __asm { - mov ecx, [pcount] - mov eax, [old] - mov edx, [_new] - lock cmpxchg [ecx], edx - mov [orig], eax - } - - return orig; -} -#endif - - -#if defined(PIPE_ATOMIC_OS_MS_INTERLOCK) - -#define PIPE_ATOMIC "MS userspace interlocks" - -#include <windows.h> - -struct pipe_atomic -{ - volatile long count; -}; - -#define p_atomic_set(_v, _i) ((_v)->count = (_i)) -#define p_atomic_read(_v) ((_v)->count) - -static INLINE boolean -p_atomic_dec_zero(struct pipe_atomic *v) -{ - return InterlockedDecrement(&v->count) == 0; -} - -static INLINE void -p_atomic_inc(struct pipe_atomic *v) -{ - InterlockedIncrement(&v->count); -} - -static INLINE void -p_atomic_dec(struct pipe_atomic *v) -{ - InterlockedDecrement(&v->count); -} - -static INLINE int32_t -p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) -{ - return InterlockedCompareExchange(&v->count, _new, old); -} - -#endif - - - -#if defined(PIPE_ATOMIC_MUTEX) - -#define PIPE_ATOMIC "mutex-based fallback" - -#include "pipe/p_thread.h" - -/** - * This implementation should really not be used. - * Add an assembly port instead. It may abort and - * doesn't destroy used mutexes. - */ - -struct pipe_atomic { - pipe_mutex mutex; - int32_t count; -}; - -static INLINE void -p_atomic_set(struct pipe_atomic *v, int32_t i) -{ - pipe_mutex_init(v->mutex); - pipe_mutex_lock(v->mutex); - v->count = i; - pipe_mutex_unlock(v->mutex); -} - -static INLINE int32_t -p_atomic_read(struct pipe_atomic *v) -{ - int32_t ret; - - pipe_mutex_lock(v->mutex); - ret = v->count; - pipe_mutex_unlock(v->mutex); - return ret; -} - -static INLINE void -p_atomic_inc(struct pipe_atomic *v) -{ - pipe_mutex_lock(v->mutex); - ++v->count; - pipe_mutex_unlock(v->mutex); -} - -static INLINE void -p_atomic_dec(struct pipe_atomic *v) -{ - pipe_mutex_lock(v->mutex); - --v->count; - pipe_mutex_unlock(v->mutex); -} - -static INLINE boolean -p_atomic_dec_zero(struct pipe_atomic *v) -{ - boolean ret; - - pipe_mutex_lock(v->mutex); - ret = (--v->count == 0); - pipe_mutex_unlock(v->mutex); - return ret; -} - -static INLINE int32_t -p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new) -{ - int32_t ret; - - pipe_mutex_lock(v->mutex); - ret = v->count; - if (ret == old) - v->count = _new; - pipe_mutex_unlock(v->mutex); - - return ret; -} - -#endif - - -#ifndef PIPE_ATOMIC -#error "No pipe_atomic implementation selected" -#endif - - - -#ifdef __cplusplus -} -#endif - -#endif /* P_ATOMIC_H */ diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 26a940593f..c7d3507494 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -38,6 +38,8 @@ #include "xf86_ansic.h" #include "xf86_libc.h" #endif +#include <stddef.h> +#include <stdarg.h> #if defined(_WIN32) && !defined(__WIN32__) @@ -63,7 +65,7 @@ #include <stdbool.h> -#ifndef __HAIKU__ +#if !defined(__HAIKU__) && !defined(__USE_MISC) typedef unsigned int uint; typedef unsigned short ushort; #endif @@ -104,7 +106,8 @@ typedef unsigned char boolean; /* Function visibility */ #ifndef PUBLIC -# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 +# if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PUBLIC __attribute__((visibility("default"))) # else # define PUBLIC @@ -124,6 +127,9 @@ typedef unsigned char boolean; # define __FUNCTION__ "<unknown>" # endif # endif +# if defined(_MSC_VER) && _MSC_VER < 1300 +# define __FUNCTION__ "<unknown>" +# endif #endif @@ -139,22 +145,48 @@ typedef unsigned char boolean; -#if defined(__GNUC__) -#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___aligned[SIZE] __attribute__(( aligned( 16 ) )) -#define ALIGN16_ASSIGN(NAME) NAME##___aligned -#define ALIGN16_ATTRIB __attribute__(( aligned( 16 ) )) -#define ALIGN8_ATTRIB __attribute__(( aligned( 8 ) )) +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define PIPE_DEPRECATED __attribute__((__deprecated__)) +#else +#define PIPE_DEPRECATED +#endif + + + +/* Macros for data alignment. */ +#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) + +/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */ +#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment))) + +/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */ +#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment))) + #if (__GNUC__ > 4 || (__GNUC__ == 4 &&__GNUC_MINOR__>1)) && !defined(PIPE_ARCH_X86_64) -#define ALIGN_STACK __attribute__((force_align_arg_pointer)) +#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer)) #else -#define ALIGN_STACK +#define PIPE_ALIGN_STACK #endif + +#elif defined(_MSC_VER) + +/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */ +#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type +#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment)) + +#define PIPE_ALIGN_STACK + +#elif defined(SWIG) + +#define PIPE_ALIGN_TYPE(_alignment, _type) _type +#define PIPE_ALIGN_VAR(_alignment) + +#define PIPE_ALIGN_STACK + #else -#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___unaligned[SIZE + 1] -#define ALIGN16_ASSIGN(NAME) align16(NAME##___unaligned) -#define ALIGN16_ATTRIB -#define ALIGN8_ATTRIB -#define ALIGN_STACK + +#error "Unsupported compiler" + #endif diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 064605a4a0..c5928dde47 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -115,8 +115,10 @@ #endif +#if !defined(PIPE_OS_EMBEDDED) + /* - * Operating system family. + * Auto-detect the operating system family. * * See subsystem below for a more fine-grained distinction. */ @@ -164,7 +166,7 @@ #endif /* - * Subsystem. + * Try to auto-detect the subsystem. * * NOTE: There is no way to auto-detect most of these. */ @@ -191,5 +193,7 @@ #endif #endif /* PIPE_OS_WINDOWS */ +#endif /* !PIPE_OS_EMBEDDED */ + #endif /* P_CONFIG_H_ */ diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index d2f8085b42..f1e6a60e04 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -69,6 +69,22 @@ struct pipe_context { unsigned indexSize, unsigned mode, unsigned start, unsigned count); + void (*draw_arrays_instanced)(struct pipe_context *pipe, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + + void (*draw_elements_instanced)(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, + unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); + /* XXX: this is (probably) a temporary entrypoint, as the range * information should be available from the vertex_buffer state. * Using this to quickly evaluate a specialized path in the draw @@ -87,7 +103,7 @@ struct pipe_context { /** * Predicate subsequent rendering on occlusion query result * \param query the query predicate, or NULL if no predicate - * \param mode one of PIPE_COND_RENDER_x + * \param mode one of PIPE_RENDER_COND_x */ void (*render_condition)( struct pipe_context *pipe, struct pipe_query *query, @@ -106,6 +122,11 @@ struct pipe_context { void (*begin_query)(struct pipe_context *pipe, struct pipe_query *q); void (*end_query)(struct pipe_context *pipe, struct pipe_query *q); + /** + * Get results of a query. + * \param wait if true, this query will block until the result is ready + * \return TRUE if results are ready, FALSE otherwise + */ boolean (*get_query_result)(struct pipe_context *pipe, struct pipe_query *q, boolean wait, @@ -170,7 +191,7 @@ struct pipe_context { void (*set_constant_buffer)( struct pipe_context *, uint shader, uint index, - const struct pipe_constant_buffer *buf ); + struct pipe_buffer *buf ); void (*set_framebuffer_state)( struct pipe_context *, const struct pipe_framebuffer_state * ); @@ -255,30 +276,30 @@ struct pipe_context { /** * Check whether a texture is referenced by an unflushed hw command. - * The state-tracker uses this function to optimize away unnecessary - * flushes. It is safe (but wasteful) to always return. + * The state-tracker uses this function to avoid unnecessary flushes. + * It is safe (but wasteful) to always return * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE. - * \param pipe The pipe context whose unflushed hw commands will be - * checked. - * \param level mipmap level. + * \param pipe context whose unflushed hw commands will be checked. * \param texture texture to check. * \param face cubemap face. Use 0 for non-cubemap texture. + * \param level mipmap level. + * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED */ - unsigned int (*is_texture_referenced) (struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level); + unsigned int (*is_texture_referenced)(struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level); /** * Check whether a buffer is referenced by an unflushed hw command. - * The state-tracker uses this function to optimize away unnecessary - * flushes. It is safe (but wasteful) to always return + * The state-tracker uses this function to avoid unnecessary flushes. + * It is safe (but wasteful) to always return * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE. - * \param pipe The pipe context whose unflushed hw commands will be - * checked. - * \param buf Buffer to check. + * \param pipe context whose unflushed hw commands will be checked. + * \param buf buffer to check. + * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED */ - unsigned int (*is_buffer_referenced) (struct pipe_context *pipe, - struct pipe_buffer *buf); + unsigned int (*is_buffer_referenced)(struct pipe_context *pipe, + struct pipe_buffer *buf); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index a85a170153..5cebd43ace 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -376,7 +376,7 @@ enum pipe_transfer_usage { #define PIPE_CAP_NPOT_TEXTURES 2 #define PIPE_CAP_TWO_SIDED_STENCIL 3 #define PIPE_CAP_GLSL 4 /* XXX need something better */ -#define PIPE_CAP_S3TC 5 /* XXX: deprecated; cap determined via supported sampler formats */ +#define PIPE_CAP_DUAL_SOURCE_BLEND 5 #define PIPE_CAP_ANISOTROPIC_FILTER 6 #define PIPE_CAP_POINT_SPRITE 7 #define PIPE_CAP_MAX_RENDER_TARGETS 8 @@ -404,6 +404,14 @@ enum pipe_transfer_usage { #define PIPE_CAP_MAX_PREDICATE_REGISTERS 30 #define PIPE_CAP_MAX_COMBINED_SAMPLERS 31 /*< Maximum texture image units accessible from vertex and fragment shaders combined */ +#define PIPE_CAP_MAX_CONST_BUFFERS 32 +#define PIPE_CAP_MAX_CONST_BUFFER_SIZE 33 /*< In bytes */ +#define PIPE_CAP_INDEP_BLEND_ENABLE 34 /*< blend enables and write masks per rendertarget */ +#define PIPE_CAP_INDEP_BLEND_FUNC 35 /*< different blend funcs per rendertarget */ +#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT 36 +#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT 37 +#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 38 +#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER 39 /** diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 6bfff1cc59..2894e13e7d 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -31,10 +31,6 @@ #include "p_compiler.h" -/* FIXME: remove these header dependencies */ -#include "util/u_debug.h" -#include "util/u_string.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/src/gallium/include/pipe/p_refcnt.h b/src/gallium/include/pipe/p_refcnt.h deleted file mode 100644 index c1c7415e02..0000000000 --- a/src/gallium/include/pipe/p_refcnt.h +++ /dev/null @@ -1,95 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -#ifndef P_REFCNT_H -#define P_REFCNT_H - - -#include "p_defines.h" -#include "p_atomic.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -struct pipe_reference -{ - struct pipe_atomic count; -}; - - -static INLINE void -pipe_reference_init(struct pipe_reference *reference, unsigned count) -{ - p_atomic_set(&reference->count, count); -} - - -static INLINE boolean -pipe_is_referenced(struct pipe_reference *reference) -{ - return p_atomic_read(&reference->count) != 0; -} - - -/** - * Update reference counting. - * The old thing pointed to, if any, will be unreferenced. - * Both 'ptr' and 'reference' may be NULL. - * \return TRUE if the object's refcount hits zero and should be destroyed. - */ -static INLINE boolean -pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) -{ - boolean destroy = FALSE; - - if(ptr != reference) { - /* bump the reference.count first */ - if (reference) { - assert(pipe_is_referenced(reference)); - p_atomic_inc(&reference->count); - } - - if (ptr) { - assert(pipe_is_referenced(ptr)); - if (p_atomic_dec_zero(&ptr->count)) { - destroy = TRUE; - } - } - } - - return destroy; -} - - -#ifdef __cplusplus -} -#endif - -#endif /* P_REFCNT_H */ diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index b8e001a6b0..48625bf312 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -86,6 +86,9 @@ struct pipe_screen { */ float (*get_paramf)( struct pipe_screen *, int param ); + struct pipe_context * (*context_create)( struct pipe_screen *, + void *priv ); + /** * Check if the given pipe_format is supported as a texture or * drawing surface. diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 550e2abc32..c5c480f1f0 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -1,7 +1,7 @@ /************************************************************************** * * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 2009 VMware, Inc. + * Copyright 2009-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -102,6 +102,11 @@ enum tgsi_file_type { #define TGSI_INTERPOLATE_PERSPECTIVE 2 #define TGSI_INTERPOLATE_COUNT 3 +#define TGSI_CYLINDRICAL_WRAP_X (1 << 0) +#define TGSI_CYLINDRICAL_WRAP_Y (1 << 1) +#define TGSI_CYLINDRICAL_WRAP_Z (1 << 2) +#define TGSI_CYLINDRICAL_WRAP_W (1 << 3) + struct tgsi_declaration { unsigned Type : 4; /**< TGSI_TOKEN_TYPE_DECLARATION */ @@ -109,10 +114,11 @@ struct tgsi_declaration unsigned File : 4; /**< one of TGSI_FILE_x */ unsigned UsageMask : 4; /**< bitmask of TGSI_WRITEMASK_x flags */ unsigned Interpolate : 4; /**< one of TGSI_INTERPOLATE_x */ + unsigned Dimension : 1; /**< any extra dimension info? */ unsigned Semantic : 1; /**< BOOL, any semantic info? */ unsigned Centroid : 1; /**< centroid sampling? */ unsigned Invariant : 1; /**< invariant optimization? */ - unsigned Padding : 5; + unsigned CylindricalWrap:4; /**< TGSI_CYLINDRICAL_WRAP_x flags */ }; struct tgsi_declaration_range @@ -121,17 +127,24 @@ struct tgsi_declaration_range unsigned Last : 16; /**< UINT */ }; -#define TGSI_SEMANTIC_POSITION 0 -#define TGSI_SEMANTIC_COLOR 1 -#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */ -#define TGSI_SEMANTIC_FOG 3 -#define TGSI_SEMANTIC_PSIZE 4 -#define TGSI_SEMANTIC_GENERIC 5 -#define TGSI_SEMANTIC_NORMAL 6 -#define TGSI_SEMANTIC_FACE 7 -#define TGSI_SEMANTIC_EDGEFLAG 8 -#define TGSI_SEMANTIC_PRIMID 9 -#define TGSI_SEMANTIC_COUNT 10 /**< number of semantic values */ +struct tgsi_declaration_dimension +{ + unsigned Index2D:16; /**< UINT */ + unsigned Padding:16; +}; + +#define TGSI_SEMANTIC_POSITION 0 +#define TGSI_SEMANTIC_COLOR 1 +#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */ +#define TGSI_SEMANTIC_FOG 3 +#define TGSI_SEMANTIC_PSIZE 4 +#define TGSI_SEMANTIC_GENERIC 5 +#define TGSI_SEMANTIC_NORMAL 6 +#define TGSI_SEMANTIC_FACE 7 +#define TGSI_SEMANTIC_EDGEFLAG 8 +#define TGSI_SEMANTIC_PRIMID 9 +#define TGSI_SEMANTIC_INSTANCEID 10 +#define TGSI_SEMANTIC_COUNT 11 /**< number of semantic values */ struct tgsi_declaration_semantic { @@ -162,7 +175,9 @@ union tgsi_immediate_data #define TGSI_PROPERTY_GS_INPUT_PRIM 0 #define TGSI_PROPERTY_GS_OUTPUT_PRIM 1 #define TGSI_PROPERTY_GS_MAX_VERTICES 2 -#define TGSI_PROPERTY_COUNT 3 +#define TGSI_PROPERTY_FS_COORD_ORIGIN 3 +#define TGSI_PROPERTY_FS_COORD_PIXEL_CENTER 4 +#define TGSI_PROPERTY_COUNT 5 struct tgsi_property { unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */ @@ -171,6 +186,12 @@ struct tgsi_property { unsigned Padding : 12; }; +#define TGSI_FS_COORD_ORIGIN_UPPER_LEFT 0 +#define TGSI_FS_COORD_ORIGIN_LOWER_LEFT 1 + +#define TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 0 +#define TGSI_FS_COORD_PIXEL_CENTER_INTEGER 1 + struct tgsi_property_data { unsigned Data; }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 4387b92be2..68369570b9 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -43,7 +43,6 @@ #include "p_compiler.h" #include "p_defines.h" #include "p_format.h" -#include "p_refcnt.h" #include "p_screen.h" @@ -58,7 +57,7 @@ extern "C" { #define PIPE_MAX_ATTRIBS 32 #define PIPE_MAX_CLIP_PLANES 6 #define PIPE_MAX_COLOR_BUFS 8 -#define PIPE_MAX_CONSTANT 32 +#define PIPE_MAX_CONSTANT_BUFFERS 32 #define PIPE_MAX_SAMPLERS 16 #define PIPE_MAX_VERTEX_SAMPLERS 16 #define PIPE_MAX_SHADER_INPUTS 16 @@ -66,8 +65,10 @@ extern "C" { #define PIPE_MAX_TEXTURE_LEVELS 16 -/* fwd decls */ -struct pipe_surface; +struct pipe_reference +{ + int32_t count; /* atomic */ +}; /** @@ -177,15 +178,6 @@ struct pipe_clip_state }; -/** - * Constants for vertex/fragment shaders - */ -struct pipe_constant_buffer -{ - struct pipe_buffer *buffer; -}; - - struct pipe_shader_state { const struct tgsi_token *tokens; @@ -229,7 +221,7 @@ struct pipe_depth_stencil_alpha_state }; -struct pipe_blend_state +struct pipe_rt_blend_state { unsigned blend_enable:1; @@ -241,11 +233,16 @@ struct pipe_blend_state unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */ unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ + unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */ +}; + +struct pipe_blend_state +{ + unsigned independent_blend_enable:1; unsigned logicop_enable:1; unsigned logicop_func:4; /**< PIPE_LOGICOP_x */ - - unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */ unsigned dither:1; + struct pipe_rt_blend_state rt[PIPE_MAX_COLOR_BUFS]; }; @@ -281,7 +278,6 @@ struct pipe_sampler_state unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ - unsigned prefilter:4; /**< Wierd sampling state exposed by some api's */ float lod_bias; /**< LOD/lambda bias */ float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; @@ -375,6 +371,11 @@ struct pipe_vertex_element /** Offset of this attribute, in bytes, from the start of the vertex */ unsigned src_offset; + /** Instance data rate divisor. 0 means this is per-vertex data, + * n means per-instance data used for n consecutive instances (n > 0). + */ + unsigned instance_divisor; + /** Which vertex_buffer (as given to pipe->set_vertex_buffer()) does * this attribute live in? */ @@ -385,38 +386,6 @@ struct pipe_vertex_element }; -/* Reference counting helper functions */ -static INLINE void -pipe_buffer_reference(struct pipe_buffer **ptr, struct pipe_buffer *buf) -{ - struct pipe_buffer *old_buf = *ptr; - - if (pipe_reference(&(*ptr)->reference, &buf->reference)) - old_buf->screen->buffer_destroy(old_buf); - *ptr = buf; -} - -static INLINE void -pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) -{ - struct pipe_surface *old_surf = *ptr; - - if (pipe_reference(&(*ptr)->reference, &surf->reference)) - old_surf->texture->screen->tex_surface_destroy(old_surf); - *ptr = surf; -} - -static INLINE void -pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex) -{ - struct pipe_texture *old_tex = *ptr; - - if (pipe_reference(&(*ptr)->reference, &tex->reference)) - old_tex->screen->texture_destroy(old_tex); - *ptr = tex; -} - - #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index b85f01c2b0..77e22d0a56 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -30,12 +30,12 @@ /* u_reduce_video_profile() needs these */ #include <pipe/p_compiler.h> -#include <util/u_debug.h> #include <pipe/p_defines.h> #include <pipe/p_format.h> -#include <pipe/p_refcnt.h> +#include <pipe/p_state.h> #include <pipe/p_screen.h> +#include <util/u_inlines.h> #ifdef __cplusplus extern "C" { diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h index 4d1259e1ee..e9fa9b4d2a 100644 --- a/src/gallium/include/state_tracker/drm_api.h +++ b/src/gallium/include/state_tracker/drm_api.h @@ -28,14 +28,19 @@ struct drm_create_screen_arg { struct drm_api { + const char *name; + + /** + * Kernel driver name, as accepted by drmOpenByName. + */ + const char *driver_name; + /** * Special buffer functions */ /*@{*/ struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd, struct drm_create_screen_arg *arg); - struct pipe_context* (*create_context)(struct drm_api *api, - struct pipe_screen *screen); /*@}*/ /** diff --git a/src/gallium/state_trackers/Makefile b/src/gallium/state_trackers/Makefile index 265ca468c2..0900efc664 100644 --- a/src/gallium/state_trackers/Makefile +++ b/src/gallium/state_trackers/Makefile @@ -21,5 +21,9 @@ clean: rm -f `find . -name depend` -# Dummy install target install: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $@) || exit 1 ; \ + fi \ + done diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index f2e5f3fb23..5033c3c85b 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -69,14 +69,12 @@ dri_create_context(const __GLcontextModes * visual, driParseConfigFiles(&ctx->optionCache, &screen->optionCache, sPriv->myNum, "dri"); - ctx->pipe = screen->api->create_context(screen->api, screen->pipe_screen); + ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen, + ctx ); if (ctx->pipe == NULL) goto fail; - /* used in dri_flush_frontbuffer */ - ctx->pipe->priv = ctx; - ctx->st = st_create_context(ctx->pipe, visual, st_share); if (ctx->st == NULL) goto fail; @@ -101,6 +99,12 @@ dri_destroy_context(__DRIcontext * cPriv) { struct dri_context *ctx = dri_context(cPriv); + /* note: we are freeing values and nothing more because + * driParseConfigFiles allocated values only - the rest + * is owned by screen optionCache. + */ + FREE(ctx->optionCache.values); + /* No particular reason to wait for command completion before * destroying a context, but it is probably worthwhile flushing it * to avoid having to add code elsewhere to cope with flushing a diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index f131e77ac5..f7ed6605bf 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -35,7 +35,6 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" #include "main/mtypes.h" #include "main/renderbuffer.h" #include "state_tracker/drm_api.h" @@ -47,6 +46,7 @@ #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_rect.h" +#include "util/u_inlines.h" static struct pipe_surface * dri_surface_from_handle(struct drm_api *api, @@ -123,11 +123,12 @@ dri_get_buffers(__DRIdrawable * dPriv) struct dri_drawable *drawable = dri_drawable(dPriv); struct pipe_surface *surface = NULL; - struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; + struct dri_screen *st_screen = dri_screen(drawable->sPriv); + struct pipe_screen *screen = st_screen->pipe_screen; __DRIbuffer *buffers = NULL; __DRIscreen *dri_screen = drawable->sPriv; __DRIdrawable *dri_drawable = drawable->dPriv; - struct drm_api *api = ((struct dri_screen*)(dri_screen->private))->api; + struct drm_api *api = st_screen->api; boolean have_depth = FALSE; int i, count; @@ -180,6 +181,9 @@ dri_get_buffers(__DRIdrawable * dPriv) switch (buffers[i].attachment) { case __DRI_BUFFER_FRONT_LEFT: + if (!st_screen->auto_fake_front) + continue; + /* fallthrough */ case __DRI_BUFFER_FAKE_FRONT_LEFT: index = ST_SURFACE_FRONT_LEFT; format = drawable->color_format; @@ -372,7 +376,8 @@ dri_create_buffer(__DRIscreen * sPriv, /* TODO incase of double buffer visual, delay fake creation */ i = 0; drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - + if (!screen->auto_fake_front) + drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; if (visual->doubleBufferMode) drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; if (visual->depthBits && visual->stencilBits) diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 8b014a2a8b..1259813a41 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -50,6 +50,7 @@ #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex +#define need_GL_EXT_draw_buffers2 #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_multi_draw_arrays @@ -98,6 +99,7 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, @@ -130,6 +132,9 @@ dri_init_extensions(struct dri_context *ctx) /* The card_extensions list should be pruned according to the * capabilities of the pipe_screen. This is actually something * that can/should be done inside st_create_context(). + * XXX Not pruning is very bogus. Always all these extensions above + * will be advertized, regardless what st_init_extensions + * (which depends on the pipe cap bits) does. */ driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE); } diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 793db087ee..2052867309 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -37,14 +37,12 @@ #include "dri_context.h" #include "dri_drawable.h" -#include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" #include "pipe/p_format.h" #include "state_tracker/drm_api.h" #include "state_tracker/dri1_api.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" + +#include "util/u_debug.h" PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE @@ -83,7 +81,7 @@ dri_fill_in_modes(struct dri_screen *screen, unsigned num_modes; uint8_t depth_bits_array[5]; uint8_t stencil_bits_array[5]; - uint8_t msaa_samples_array[1]; + uint8_t msaa_samples_array[2]; unsigned depth_buffer_factor; unsigned back_buffer_factor; unsigned msaa_samples_factor; @@ -147,8 +145,9 @@ dri_fill_in_modes(struct dri_screen *screen, } msaa_samples_array[0] = 0; + msaa_samples_array[1] = 4; back_buffer_factor = 3; - msaa_samples_factor = 1; + msaa_samples_factor = 2; num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; @@ -158,7 +157,7 @@ dri_fill_in_modes(struct dri_screen *screen, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, msaa_samples_factor); } else { __DRIconfig **configs_a8r8g8b8 = NULL; __DRIconfig **configs_x8r8g8b8 = NULL; @@ -170,7 +169,8 @@ dri_fill_in_modes(struct dri_screen *screen, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, + msaa_samples_factor); if (pf_x8r8g8b8) configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, depth_bits_array, @@ -178,7 +178,8 @@ dri_fill_in_modes(struct dri_screen *screen, depth_buffer_factor, back_buffer_modes, back_buffer_factor, - msaa_samples_array, 1); + msaa_samples_array, + msaa_samples_factor); if (configs_a8r8g8b8 && configs_x8r8g8b8) configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8); @@ -195,7 +196,7 @@ dri_fill_in_modes(struct dri_screen *screen, return NULL; } - return (const const __DRIconfig **)configs; + return (const __DRIconfig **)configs; } /** @@ -289,6 +290,8 @@ dri_init_screen2(__DRIscreen * sPriv) { struct dri_screen *screen; struct drm_create_screen_arg arg; + const __DRIdri2LoaderExtension *dri2_ext = + sPriv->dri2.loader; screen = CALLOC_STRUCT(dri_screen); if (!screen) @@ -314,6 +317,9 @@ dri_init_screen2(__DRIscreen * sPriv) driParseOptionInfo(&screen->optionCache, __driConfigOptions, __driNConfigOptions); + screen->auto_fake_front = dri2_ext->base.version >= 3 && + dri2_ext->getBuffersWithFormat != NULL; + return dri_fill_in_modes(screen, 32); fail: return NULL; @@ -323,8 +329,18 @@ static void dri_destroy_screen(__DRIscreen * sPriv) { struct dri_screen *screen = dri_screen(sPriv); + int i; screen->pipe_screen->destroy(screen->pipe_screen); + + for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { + FREE(screen->optionCache.info[i].name); + FREE(screen->optionCache.info[i].ranges); + } + + FREE(screen->optionCache.info); + FREE(screen->optionCache.values); + FREE(screen); sPriv->private = NULL; } diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index 03387a0e81..75a0ee4250 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -59,6 +59,7 @@ struct dri_screen struct pipe_screen *pipe_screen; boolean d_depth_bits_last; boolean sd_depth_bits_last; + boolean auto_fake_front; }; /** cast wrapper */ diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index e825aa718b..794785006f 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -1,19 +1,73 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = egldrm - -LIBRARY_INCLUDES = \ +common_INCLUDES = \ + -I. \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include \ -I$(TOP)/src/egl/main \ + -I$(TOP)/include + +common_SOURCES = $(wildcard common/*.c) +common_OBJECTS = $(common_SOURCES:.c=.o) + + +x11_INCLUDES = \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/glx \ + -I$(TOP)/src/mesa \ $(shell pkg-config --cflags-only-I libdrm) +x11_SOURCES = $(wildcard x11/*.c) \ + $(TOP)/src/glx/dri2.c +x11_OBJECTS = $(x11_SOURCES:.c=.o) + + +kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm) +kms_SOURCES = $(wildcard kms/*.c) +kms_OBJECTS = $(kms_SOURCES:.c=.o) + + +ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) +ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) +ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS) + +##### TARGETS ##### + +EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a) + +default: depend $(EGL_DISPLAYS_MODS) + + +libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile + $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS) + +libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile + $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS) + +depend: + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null + +clean: + rm -f $(ALL_OBJECTS) + rm -f $(EGL_DISPLAYS_MODS) + rm -f depend depend.bak + +# Dummy target +install: + @echo -n "" + +##### RULES ##### + +$(common_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ -C_SOURCES = $(wildcard ./*.c) +$(x11_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ +$(kms_OBJECTS): %.o: %.c + $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@ -include ../../Makefile.template +sinclude depend diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c new file mode 100644 index 0000000000..80dd126995 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -0,0 +1,1351 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <assert.h> +#include <stdio.h> +#include <string.h> +#include "pipe/p_screen.h" +#include "util/u_memory.h" +#include "util/u_rect.h" +#include "util/u_inlines.h" +#include "egldriver.h" +#include "eglcurrent.h" +#include "eglconfigutil.h" +#include "egllog.h" + +#include "native.h" +#include "egl_g3d.h" +#include "egl_st.h" + +/** + * Validate the draw/read surfaces of the context. + */ +static void +egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct pipe_screen *screen = gdpy->native->screen; + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { + ST_SURFACE_FRONT_LEFT, + ST_SURFACE_BACK_LEFT, + ST_SURFACE_FRONT_RIGHT, + ST_SURFACE_BACK_RIGHT, + }; + EGLint num_surfaces, s; + + /* validate draw and/or read buffers */ + num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2; + for (s = 0; s < num_surfaces; s++) { + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + struct egl_g3d_surface *gsurf; + struct egl_g3d_buffer *gbuf; + EGLint att; + + if (s == 0) { + gsurf = egl_g3d_surface(gctx->base.DrawSurface); + gbuf = &gctx->draw; + } + else { + gsurf = egl_g3d_surface(gctx->base.ReadSurface); + gbuf = &gctx->read; + } + + if (!gctx->force_validate) { + unsigned int seq_num; + + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, + &seq_num, NULL, NULL, NULL); + /* skip validation */ + if (gsurf->sequence_number == seq_num) + continue; + } + + pipe_surface_reference(&gsurf->render_surface, NULL); + memset(textures, 0, sizeof(textures)); + + gsurf->native->validate(gsurf->native, gbuf->attachment_mask, + &gsurf->sequence_number, textures, + &gsurf->base.Width, &gsurf->base.Height); + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct pipe_texture *pt = textures[att]; + struct pipe_surface *ps; + + if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) { + ps = screen->get_tex_surface(screen, pt, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb, + st_att_map[att], ps); + + if (gsurf->render_att == att) + pipe_surface_reference(&gsurf->render_surface, ps); + + pipe_surface_reference(&ps, NULL); + pipe_texture_reference(&pt, NULL); + } + } + + gctx->stapi->st_resize_framebuffer(gbuf->st_fb, + gsurf->base.Width, gsurf->base.Height); + } + + gctx->force_validate = EGL_FALSE; + +} + +/** + * Create a st_framebuffer. + */ +static struct st_framebuffer * +create_framebuffer(_EGLContext *ctx, _EGLSurface *surf) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); + + return gctx->stapi->st_create_framebuffer(&gconf->native->mode, + gconf->native->color_format, gconf->native->depth_format, + gconf->native->stencil_format, + gsurf->base.Width, gsurf->base.Height, &gsurf->base); +} + +/** + * Update the attachments of draw/read surfaces. + */ +static void +egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + EGLint s; + + /* route draw and read buffers' attachments */ + for (s = 0; s < 2; s++) { + struct egl_g3d_surface *gsurf; + struct egl_g3d_buffer *gbuf; + + if (s == 0) { + gsurf = egl_g3d_surface(gctx->base.DrawSurface); + gbuf = &gctx->draw; + } + else { + gsurf = egl_g3d_surface(gctx->base.ReadSurface); + gbuf = &gctx->read; + } + + gbuf->attachment_mask = (1 << gsurf->render_att); + + /* FIXME OpenGL defaults to draw the front or back buffer when the + * context is single-buffered or double-buffered respectively. In EGL, + * however, the buffer to be drawn is determined by the surface, instead + * of the context. As a result, rendering to a pixmap surface with a + * double-buffered context does not work as expected. + * + * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt == + * NATIVE_ATTACHMENT_FRONT_LEFT); + */ + + /* + * FIXME If the back buffer is asked for here, and the front buffer is + * later needed by the client API (e.g. glDrawBuffer is called to draw + * the front buffer), it will create a new pipe texture and draw there. + * One fix is to ask for both buffers here, but it would be a waste if + * the front buffer is never used. A better fix is to add a callback to + * the pipe screen with context private (just like flush_frontbuffer). + */ + } +} + +/** + * Reallocate the context's framebuffers after draw/read surfaces change. + */ +static EGLBoolean +egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface); + struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface); + + /* unreference the old framebuffers */ + if (gctx->draw.st_fb) { + EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb); + void *priv; + + priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb); + if (!gdraw || priv != (void *) &gdraw->base) { + gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); + gctx->draw.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + + if (is_equal) { + gctx->read.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + else { + priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb); + if (!gread || priv != (void *) &gread->base) { + gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb); + gctx->read.st_fb = NULL; + gctx->draw.attachment_mask = 0x0; + } + } + } + + if (!gdraw) + return EGL_TRUE; + + /* create the draw fb */ + if (!gctx->draw.st_fb) { + gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base); + if (!gctx->draw.st_fb) + return EGL_FALSE; + } + + /* create the read fb */ + if (!gctx->read.st_fb) { + if (gread != gdraw) { + gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base); + if (!gctx->read.st_fb) { + gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); + gctx->draw.st_fb = NULL; + return EGL_FALSE; + } + } + else { + /* there is no st_reference_framebuffer... */ + gctx->read.st_fb = gctx->draw.st_fb; + } + } + + egl_g3d_route_context(dpy, &gctx->base); + gctx->force_validate = EGL_TRUE; + + return EGL_TRUE; +} + +/** + * Return the state tracker for the given context. + */ +static const struct egl_g3d_st * +egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + const struct egl_g3d_st *stapi; + EGLint idx = -1; + + switch (ctx->ClientAPI) { + case EGL_OPENGL_ES_API: + switch (ctx->ClientVersion) { + case 1: + idx = EGL_G3D_ST_OPENGL_ES; + break; + case 2: + idx = EGL_G3D_ST_OPENGL_ES2; + break; + default: + _eglLog(_EGL_WARNING, "unknown client version %d", + ctx->ClientVersion); + break; + } + break; + case EGL_OPENVG_API: + idx = EGL_G3D_ST_OPENVG; + break; + case EGL_OPENGL_API: + idx = EGL_G3D_ST_OPENGL; + break; + default: + _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI); + break; + } + + stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL; + return stapi; +} + +/** + * Initialize the state trackers. + */ +static void +egl_g3d_init_st(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + EGLint i; + + /* already initialized */ + if (gdrv->api_mask) + return; + + for (i = 0; i < NUM_EGL_G3D_STS; i++) { + gdrv->stapis[i] = egl_g3d_get_st(i); + if (gdrv->stapis[i]) + gdrv->api_mask |= gdrv->stapis[i]->api_bit; + } + + if (gdrv->api_mask) + _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); + else + _eglLog(_EGL_WARNING, "No supported client API"); +} + +/** + * Get the probe object of the display. + * + * Note that this function may be called before the display is initialized. + */ +static struct native_probe * +egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (!nprobe || nprobe->display != dpy->NativeDisplay) { + if (nprobe) + nprobe->destroy(nprobe); + nprobe = native_create_probe(dpy->NativeDisplay); + _eglSetProbeCache(gdrv->probe_key, (void *) nprobe); + } + + return nprobe; +} + +/** + * Destroy the probe object of the display. The display may be NULL. + * + * Note that this function may be called before the display is initialized. + */ +static void +egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct native_probe *nprobe; + + nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key); + if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) { + nprobe->destroy(nprobe); + _eglSetProbeCache(gdrv->probe_key, NULL); + } +} + +/** + * Return an API mask that consists of the state trackers that supports the + * given mode. + * + * FIXME add st_is_mode_supported()? + */ +static EGLint +get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask) +{ + EGLint check; + + /* OpenGL ES 1.x and 2.x are checked together */ + check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT; + if (api_mask & check) { + /* this is required by EGL, not by OpenGL ES */ + if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode) + api_mask &= ~check; + } + + check = EGL_OPENVG_BIT; + if (api_mask & check) { + /* vega st needs the depth/stencil rb */ + if (!mode->depthBits && !mode->stencilBits) + api_mask &= ~check; + } + + return api_mask; +} + +#ifdef EGL_MESA_screen_surface + +static void +egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + const struct native_connector **native_connectors; + EGLint num_connectors, i; + + native_connectors = + gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL); + if (!num_connectors) { + if (native_connectors) + free(native_connectors); + return; + } + + for (i = 0; i < num_connectors; i++) { + const struct native_connector *nconn = native_connectors[i]; + struct egl_g3d_screen *gscr; + const struct native_mode **native_modes; + EGLint num_modes, j; + + /* TODO support for hotplug */ + native_modes = + gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes); + if (!num_modes) { + if (native_modes) + free(native_modes); + continue; + } + + gscr = CALLOC_STRUCT(egl_g3d_screen); + if (!gscr) { + free(native_modes); + continue; + } + + _eglInitScreen(&gscr->base); + + for (j = 0; j < num_modes; j++) { + const struct native_mode *nmode = native_modes[j]; + _EGLMode *mode; + + mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height, + nmode->refresh_rate, nmode->desc); + if (!mode) + break; + /* gscr->native_modes and gscr->base.Modes should be consistent */ + assert(mode == &gscr->base.Modes[j]); + } + + gscr->native = nconn; + gscr->native_modes = native_modes; + + _eglAddScreen(dpy, &gscr->base); + } + + free(native_connectors); +} + +#endif /* EGL_MESA_screen_surface */ + +/** + * Add configs to display and return the next config ID. + */ +static EGLint +egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + const struct native_config **native_configs; + int num_configs, i; + + native_configs = gdpy->native->get_configs(gdpy->native, + &num_configs); + if (!num_configs) { + if (native_configs) + free(native_configs); + return id; + } + + for (i = 0; i < num_configs; i++) { + EGLint api_mask; + struct egl_g3d_config *gconf; + EGLBoolean valid; + + gconf = CALLOC_STRUCT(egl_g3d_config); + if (!gconf) + continue; + + _eglInitConfig(&gconf->base, dpy, id); + + api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask); + if (!api_mask) { + _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x", + native_configs[i]->mode.visualID); + } + + valid = _eglConfigFromContextModesRec(&gconf->base, + &native_configs[i]->mode, api_mask, api_mask); + if (valid) { +#ifdef EGL_MESA_screen_surface + /* check if scanout surface bit is set */ + if (native_configs[i]->scanout_bit) { + EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE); + val |= EGL_SCREEN_BIT_MESA; + SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val); + } +#endif + valid = _eglValidateConfig(&gconf->base, EGL_FALSE); + } + if (!valid) { + _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", + native_configs[i]->mode.visualID); + free(gconf); + continue; + } + + gconf->native = native_configs[i]; + _eglAddConfig(dpy, &gconf->base); + id++; + } + + free(native_configs); + return id; +} + +/** + * Flush the front buffer of the context's draw surface. + */ +static void +egl_g3d_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private) +{ + struct egl_g3d_context *gctx = egl_g3d_context(context_private); + struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface); + + if (gsurf) + gsurf->native->flush_frontbuffer(gsurf->native); +} + +/** + * Re-validate the context. + */ +static void +egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) +{ + struct egl_g3d_context *gctx = egl_g3d_context(context_private); + + /** + * It is likely that the surface has changed when this function is called. + * Set force_validate to skip an unnecessary check. + */ + gctx->force_validate = EGL_TRUE; + egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base); +} + +static EGLBoolean +egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + EGLint i; + + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); + + if (dpy->Screens) { + for (i = 0; i < dpy->NumScreens; i++) { + struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]); + free(gscr->native_modes); + free(gscr); + } + free(dpy->Screens); + } + + if (gdpy->native) + gdpy->native->destroy(gdpy->native); + + free(gdpy); + dpy->DriverData = NULL; + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, + EGLint *major, EGLint *minor) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + struct egl_g3d_display *gdpy; + + /* the probe object is unlikely to be needed again */ + egl_g3d_destroy_probe(drv, dpy); + + gdpy = CALLOC_STRUCT(egl_g3d_display); + if (!gdpy) { + _eglError(EGL_BAD_ALLOC, "eglInitialize"); + goto fail; + } + dpy->DriverData = gdpy; + + gdpy->native = native_create_display(dpy->NativeDisplay); + if (!gdpy->native) { + _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); + goto fail; + } + + gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; + gdpy->native->screen->update_buffer = egl_g3d_update_buffer; + + egl_g3d_init_st(&gdrv->base); + dpy->ClientAPIsMask = gdrv->api_mask; + + if (egl_g3d_add_configs(drv, dpy, 1) == 1) { + _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); + goto fail; + } + +#ifdef EGL_MESA_screen_surface + /* enable MESA_screen_surface */ + if (gdpy->native->modeset) { + dpy->Extensions.MESA_screen_surface = EGL_TRUE; + egl_g3d_add_screens(drv, dpy); + } +#endif + + *major = 1; + *minor = 4; + + return EGL_TRUE; + +fail: + if (gdpy) + egl_g3d_terminate(drv, dpy); + return EGL_FALSE; +} + +static _EGLContext * +egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + _EGLContext *share, const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_context *gshare = egl_g3d_context(share); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_context *gctx; + const __GLcontextModes *mode; + + gctx = CALLOC_STRUCT(egl_g3d_context); + if (!gctx) { + _eglError(EGL_BAD_ALLOC, "eglCreateContext"); + return NULL; + } + + if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) { + free(gctx); + return NULL; + } + + gctx->stapi = egl_g3d_choose_st(drv, &gctx->base); + if (!gctx->stapi) { + free(gctx); + return NULL; + } + + mode = &gconf->native->mode; + + gctx->pipe = gdpy->native->screen->context_create( + gdpy->native->screen, + (void *) &gctx->base); + + if (!gctx->pipe) { + free(gctx); + return NULL; + } + + gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode, + (gshare) ? gshare->st_ctx : NULL); + if (!gctx->st_ctx) { + gctx->pipe->destroy(gctx->pipe); + free(gctx); + return NULL; + } + + return &gctx->base; +} + +/** + * Destroy a context. + */ +static void +destroy_context(_EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + + /* FIXME a context might live longer than its display */ + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a context with an unitialized display"); + + egl_g3d_realloc_context(dpy, &gctx->base); + /* it will destroy the associated pipe context */ + gctx->stapi->st_destroy_context(gctx->st_ctx); + + free(gctx); +} + +static EGLBoolean +egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + if (!_eglIsContextBound(ctx)) + destroy_context(dpy, ctx); + return EGL_TRUE; +} + +static EGLBoolean +init_surface_geometry(_EGLSurface *surf) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + return gsurf->native->validate(gsurf->native, 0x0, + &gsurf->sequence_number, NULL, + &gsurf->base.Width, &gsurf->base.Height); +} + +static _EGLSurface * +egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, EGLNativeWindowType win, + const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_surface *gsurf; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); + return NULL; + } + + if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) { + free(gsurf); + return NULL; + } + + gsurf->native = + gdpy->native->create_window_surface(gdpy->native, win, gconf->native); + if (!gsurf->native) { + free(gsurf); + return NULL; + } + + if (!init_surface_geometry(&gsurf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + + gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || + !gconf->native->mode.doubleBufferMode) ? + NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + + return &gsurf->base; +} + +static _EGLSurface * +egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, EGLNativePixmapType pix, + const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_surface *gsurf; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface"); + return NULL; + } + + if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) { + free(gsurf); + return NULL; + } + + gsurf->native = + gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native); + if (!gsurf->native) { + free(gsurf); + return NULL; + } + + if (!init_surface_geometry(&gsurf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + + gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; + + return &gsurf->base; +} + +static _EGLSurface * +egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_surface *gsurf; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + return NULL; + } + + if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) { + free(gsurf); + return NULL; + } + + gsurf->native = + gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native, + gsurf->base.Width, gsurf->base.Height); + if (!gsurf->native) { + free(gsurf); + return NULL; + } + + if (!init_surface_geometry(&gsurf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + + gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? + NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + + return &gsurf->base; +} + +/** + * Destroy a surface. + */ +static void +destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + /* FIXME a surface might live longer than its display */ + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display"); + + pipe_surface_reference(&gsurf->render_surface, NULL); + gsurf->native->destroy(gsurf->native); + free(gsurf); +} + +static EGLBoolean +egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + if (!_eglIsSurfaceBound(surf)) + destroy_surface(dpy, surf); + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); + struct egl_g3d_context *old_gctx; + EGLBoolean ok = EGL_TRUE; + + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &draw, &read)) + return EGL_FALSE; + old_gctx = egl_g3d_context(ctx); + + if (old_gctx) { + /* flush old context */ + old_gctx->stapi->st_flush(old_gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + + /* + * The old context is no longer current, and egl_g3d_realloc_context() + * should be called to destroy the framebuffers. However, it is possible + * that it will be made current again with the same draw/read surfaces. + * It might be better to keep it around. + */ + } + + if (gctx) { + ok = egl_g3d_realloc_context(dpy, &gctx->base); + if (ok) { + ok = gctx->stapi->st_make_current(gctx->st_ctx, + gctx->draw.st_fb, gctx->read.st_fb); + if (ok) { + egl_g3d_validate_context(dpy, &gctx->base); + if (gdraw->base.Type == EGL_WINDOW_BIT) { + gctx->base.WindowRenderBuffer = + (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ? + EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; + } + } + } + } + else if (old_gctx) { + ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL); + old_gctx->base.WindowRenderBuffer = EGL_NONE; + } + + if (ctx && !_eglIsContextLinked(ctx)) + destroy_context(dpy, ctx); + if (draw && !_eglIsSurfaceLinked(draw)) + destroy_surface(dpy, draw); + if (read && read != draw && !_eglIsSurfaceLinked(read)) + destroy_surface(dpy, read); + + return ok; +} + +static EGLBoolean +egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); + struct egl_g3d_context *gctx = NULL; + + /* no-op for pixmap or pbuffer surface */ + if (gsurf->base.Type == EGL_PIXMAP_BIT || + gsurf->base.Type == EGL_PBUFFER_BIT) + return EGL_TRUE; + + /* or when the surface is single-buffered */ + if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) + return EGL_TRUE; + + if (ctx && ctx->DrawSurface == surf) + gctx = egl_g3d_context(ctx); + + /* flush if the surface is current */ + if (gctx) + gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb); + + /* + * We drew on the back buffer, unless there was no back buffer. + * In that case, we drew on the front buffer. Either case, we call + * swap_buffers. + */ + if (!gsurf->native->swap_buffers(gsurf->native)) + return EGL_FALSE; + + if (gctx) { + struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); + + /* force validation if the swap method is not copy */ + if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) { + gctx->force_validate = EGL_TRUE; + egl_g3d_validate_context(dpy, &gctx->base); + } + } + + return EGL_TRUE; +} + +/** + * Find a config that supports the pixmap. + */ +static _EGLConfig * +find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf; + EGLint i; + + for (i = 0; i < dpy->NumConfigs; i++) { + gconf = egl_g3d_config(dpy->Configs[i]); + if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) + break; + } + + return (i < dpy->NumConfigs) ? &gconf->base : NULL; +} + +/** + * Get the pipe surface of the given attachment of the native surface. + */ +static struct pipe_surface * +get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, + enum native_attachment natt) +{ + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + struct pipe_surface *psurf; + + textures[natt] = NULL; + nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); + if (!textures[natt]) + return NULL; + + psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], + 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE); + pipe_texture_reference(&textures[natt], NULL); + + return psurf; +} + +static EGLBoolean +egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + EGLNativePixmapType target) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *ctx = _eglGetCurrentContext(); + struct egl_g3d_config *gconf; + struct native_surface *nsurf; + struct pipe_screen *screen = gdpy->native->screen; + struct pipe_surface *psurf; + + if (!gsurf->render_surface) + return EGL_TRUE; + + gconf = egl_g3d_config(find_pixmap_config(dpy, target)); + if (!gconf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + nsurf = gdpy->native->create_pixmap_surface(gdpy->native, + target, gconf->native); + if (!nsurf) + return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers"); + + /* flush if the surface is current */ + if (ctx && ctx->DrawSurface == &gsurf->base) { + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + gctx->stapi->st_flush(gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + if (psurf) { + struct pipe_context pipe; + + /** + * XXX This is hacky. If we might allow the EGLDisplay to create a pipe + * context of its own and use the blitter context for this. + */ + memset(&pipe, 0, sizeof(pipe)); + pipe.screen = screen; + + util_surface_copy(&pipe, FALSE, psurf, 0, 0, + gsurf->render_surface, 0, 0, psurf->width, psurf->height); + + pipe_surface_reference(&psurf, NULL); + nsurf->flush_frontbuffer(nsurf); + } + + nsurf->destroy(nsurf); + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + gctx->stapi->st_finish(gctx->st_ctx); + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) +{ + _EGLContext *ctx = _eglGetCurrentContext(); + + if (engine != EGL_CORE_NATIVE_ENGINE) + return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); + + if (ctx && ctx->DrawSurface) { + struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface); + gsurf->native->wait(gsurf->native); + } + + return EGL_TRUE; +} + +static _EGLProc +egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + _EGLProc proc; + EGLint i; + + /* in case this is called before a display is initialized */ + egl_g3d_init_st(&gdrv->base); + + for (i = 0; i < NUM_EGL_G3D_STS; i++) { + const struct egl_g3d_st *stapi = gdrv->stapis[i]; + if (stapi) { + proc = (_EGLProc) stapi->st_get_proc_address(procname); + if (proc) + return proc; + } + } + + return (_EGLProc) NULL; +} + +static EGLBoolean +egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surf, EGLint buffer) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API); + struct egl_g3d_context *gctx; + enum pipe_format target_format; + int target; + + if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT) + return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); + if (gsurf->base.BoundToTexture) + return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); + + switch (gsurf->base.TextureFormat) { + case EGL_TEXTURE_RGB: + target_format = PIPE_FORMAT_R8G8B8_UNORM; + break; + case EGL_TEXTURE_RGBA: + target_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + switch (gsurf->base.TextureTarget) { + case EGL_TEXTURE_2D: + target = ST_TEXTURE_2D; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); + } + + if (!es1) + return EGL_TRUE; + if (!gsurf->render_surface) + return EGL_FALSE; + + /* flush properly if the surface is bound */ + if (gsurf->base.CurrentContext) { + gctx = egl_g3d_context(gsurf->base.CurrentContext); + gctx->stapi->st_flush(gctx->st_ctx, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + gctx = egl_g3d_context(es1); + gctx->stapi->st_bind_texture_surface(gsurf->render_surface, + target, gsurf->base.MipmapLevel, target_format); + + gsurf->base.BoundToTexture = EGL_TRUE; + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLSurface *surf, EGLint buffer) +{ + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + + if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT || + !gsurf->base.BoundToTexture) + return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); + if (buffer != EGL_BACK_BUFFER) + return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); + + if (gsurf->render_surface) { + _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API); + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + + /* what if the context the surface binds to is no longer current? */ + if (gctx) + gctx->stapi->st_unbind_texture_surface(gsurf->render_surface, + ST_TEXTURE_2D, gsurf->base.MipmapLevel); + } + + gsurf->base.BoundToTexture = EGL_FALSE; + + return EGL_TRUE; +} + +#ifdef EGL_MESA_screen_surface + +static _EGLSurface * +egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLConfig *conf, const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + struct egl_g3d_surface *gsurf; + + gsurf = CALLOC_STRUCT(egl_g3d_surface); + if (!gsurf) { + _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + return NULL; + } + + if (!_eglInitSurface(&gsurf->base, dpy, + EGL_SCREEN_BIT_MESA, conf, attribs)) { + free(gsurf); + return NULL; + } + + gsurf->native = + gdpy->native->modeset->create_scanout_surface(gdpy->native, + gconf->native, gsurf->base.Width, gsurf->base.Height); + if (!gsurf->native) { + free(gsurf); + return NULL; + } + + gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? + NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; + + return &gsurf->base; +} + +static EGLBoolean +egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, + _EGLScreen *scr, _EGLSurface *surf, + _EGLMode *mode) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_screen *gscr = egl_g3d_screen(scr); + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + struct native_surface *nsurf; + const struct native_mode *nmode; + EGLBoolean changed; + + if (gsurf) { + EGLint idx; + + if (!mode) + return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); + if (gsurf->base.Type != EGL_SCREEN_BIT_MESA) + return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA"); + if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height) + return _eglError(EGL_BAD_MATCH, + "eglShowSurfaceMESA(surface smaller than mode size)"); + + /* find the index of the mode */ + for (idx = 0; idx < gscr->base.NumModes; idx++) + if (mode == &gscr->base.Modes[idx]) + break; + if (idx >= gscr->base.NumModes) { + return _eglError(EGL_BAD_MODE_MESA, + "eglShowSurfaceMESA(unknown mode)"); + } + + nsurf = gsurf->native; + nmode = gscr->native_modes[idx]; + } + else { + if (mode) + return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA"); + + /* disable the screen */ + nsurf = NULL; + nmode = NULL; + } + + /* TODO surface panning by CRTC choosing */ + changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf, + gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode); + if (changed) { + gscr->base.CurrentSurface = &gsurf->base; + gscr->base.CurrentMode = mode; + } + + return changed; +} + +#endif /* EGL_MESA_screen_surface */ + +static EGLint +egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct native_probe *nprobe; + enum native_probe_result res; + EGLint score; + + nprobe = egl_g3d_get_probe(drv, dpy); + res = native_get_probe_result(nprobe); + + switch (res) { + case NATIVE_PROBE_UNKNOWN: + default: + score = 0; + break; + case NATIVE_PROBE_FALLBACK: + score = 40; + break; + case NATIVE_PROBE_SUPPORTED: + score = 50; + break; + case NATIVE_PROBE_EXACT: + score = 100; + break; + } + + return score; +} + +static void +egl_g3d_unload(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + + egl_g3d_destroy_probe(drv, NULL); + free(gdrv); +} + +_EGLDriver * +_eglMain(const char *args) +{ + static char driver_name[64]; + struct egl_g3d_driver *gdrv; + + snprintf(driver_name, sizeof(driver_name), + "Gallium/%s", native_get_name()); + + gdrv = CALLOC_STRUCT(egl_g3d_driver); + if (!gdrv) + return NULL; + + _eglInitDriverFallbacks(&gdrv->base); + + gdrv->base.API.Initialize = egl_g3d_initialize; + gdrv->base.API.Terminate = egl_g3d_terminate; + gdrv->base.API.CreateContext = egl_g3d_create_context; + gdrv->base.API.DestroyContext = egl_g3d_destroy_context; + gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface; + gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface; + gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface; + gdrv->base.API.DestroySurface = egl_g3d_destroy_surface; + gdrv->base.API.MakeCurrent = egl_g3d_make_current; + gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers; + gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers; + gdrv->base.API.WaitClient = egl_g3d_wait_client; + gdrv->base.API.WaitNative = egl_g3d_wait_native; + gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; + + gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image; + gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image; + +#ifdef EGL_MESA_screen_surface + gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface; + gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface; +#endif + + gdrv->base.Name = driver_name; + gdrv->base.Probe = egl_g3d_probe; + gdrv->base.Unload = egl_g3d_unload; + + /* the key is " EGL G3D" */ + gdrv->probe_key = 0x0E61063D; + + return &gdrv->base; +} diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h new file mode 100644 index 0000000000..5d2d9c481a --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -0,0 +1,94 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _EGL_G3D_H_ +#define _EGL_G3D_H_ + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_format.h" +#include "egldriver.h" +#include "egldisplay.h" +#include "eglcontext.h" +#include "eglsurface.h" +#include "eglconfig.h" +#include "eglscreen.h" +#include "eglmode.h" + +#include "native.h" +#include "egl_st.h" + +struct egl_g3d_driver { + _EGLDriver base; + const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS]; + EGLint api_mask; + + EGLint probe_key; +}; + +struct egl_g3d_display { + struct native_display *native; +}; + +struct egl_g3d_buffer { + struct st_framebuffer *st_fb; + uint attachment_mask; +}; + +struct egl_g3d_context { + _EGLContext base; + + const struct egl_g3d_st *stapi; + struct pipe_context *pipe; + + struct st_context *st_ctx; + EGLBoolean force_validate; + struct egl_g3d_buffer draw, read; +}; + +struct egl_g3d_surface { + _EGLSurface base; + struct native_surface *native; + enum native_attachment render_att; + struct pipe_surface *render_surface; + unsigned int sequence_number; +}; + +struct egl_g3d_config { + _EGLConfig base; + const struct native_config *native; +}; + +struct egl_g3d_screen { + _EGLScreen base; + const struct native_connector *native; + const struct native_mode **native_modes; +}; + +/* standard typecasts */ +_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) +_EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj) + +#endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c new file mode 100644 index 0000000000..a88ff911cd --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_st.c @@ -0,0 +1,131 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <dlfcn.h> +#include "pipe/p_compiler.h" +#include "util/u_memory.h" +#include "egllog.h" +#include "EGL/egl.h" /* for EGL_api_BIT */ + +#include "egl_st.h" + +#ifndef HAVE_DLADDR +#define HAVE_DLADDR 1 +#endif + +#if HAVE_DLADDR + +static const char * +egl_g3d_st_names[] = { +#define ST_PUBLIC(name, ...) #name, +#include "st_public_tmp.h" + NULL +}; + +static boolean +egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +{ + st_proc *procs = (st_proc *) stapi; + void *handle; + Dl_info info; + const char **name; + + if (!dladdr(sym, &info)) + return FALSE; + handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE); + if (!handle) + return FALSE; + + for (name = egl_g3d_st_names; *name; name++) { + st_proc proc = (st_proc) dlsym(handle, *name); + if (!proc) { + _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname); + memset(stapi, 0, sizeof(*stapi)); + dlclose(handle); + return FALSE; + } + *procs++ = proc; + } + + dlclose(handle); + return TRUE; +} + +#else /* HAVE_DLADDR */ + +static boolean +egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +{ +#define ST_PUBLIC(name, ...) stapi->name = name; +#include "st_public_tmp.h" + return TRUE; +} + +#endif /* HAVE_DLADDR */ + +static boolean +egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api) +{ + void *handle, *sym; + boolean res = FALSE; + + /* already initialized */ + if (stapi->st_notify_swapbuffers != NULL) + return TRUE; + + handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); + if (!handle) + return FALSE; + + sym = dlsym(handle, api); + if (sym && egl_g3d_fill_st(stapi, sym)) + res = TRUE; + + dlclose(handle); + return res; +} + +static struct { + const char *symbol; + EGLint api_bit; +} egl_g3d_st_info[NUM_EGL_G3D_STS] = { + { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT }, + { "st_api_OpenVG", EGL_OPENVG_BIT }, + { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT }, + { "st_api_OpenGL", EGL_OPENGL_BIT }, +}; + +const struct egl_g3d_st * +egl_g3d_get_st(enum egl_g3d_st_api api) +{ + static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS]; + + if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) { + all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit; + return &all_trackers[api]; + } + else { + return NULL; + } +} diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h new file mode 100644 index 0000000000..8fb464bd3d --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_st.h @@ -0,0 +1,73 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _EGL_ST_H_ +#define _EGL_ST_H_ + +#include "GL/gl.h" /* for GL types */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" + +/* avoid calling st functions directly */ +#if 1 + +#define ST_SURFACE_FRONT_LEFT 0 +#define ST_SURFACE_BACK_LEFT 1 +#define ST_SURFACE_FRONT_RIGHT 2 +#define ST_SURFACE_BACK_RIGHT 3 + +#define ST_TEXTURE_2D 0x2 + +struct st_context; +struct st_framebuffer; +typedef void (*st_proc)(); + +#else +#include "state_tracker/st_public.h" +#endif + +/* remember to update egl_g3d_get_st() when update the enums */ +enum egl_g3d_st_api { + EGL_G3D_ST_OPENGL_ES = 0, + EGL_G3D_ST_OPENVG, + EGL_G3D_ST_OPENGL_ES2, + EGL_G3D_ST_OPENGL, + + NUM_EGL_G3D_STS +}; + +struct egl_g3d_st { +#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__); +#include "st_public_tmp.h" + /* fields must be added here */ + EGLint api_bit; +}; + +const struct egl_g3d_st * +egl_g3d_get_st(enum egl_g3d_st_api api); + +#endif /* _EGL_ST_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h new file mode 100644 index 0000000000..4f9758545a --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native.h @@ -0,0 +1,272 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _NATIVE_H_ +#define _NATIVE_H_ + +#include "EGL/egl.h" /* for EGL native types */ +#include "GL/gl.h" /* for GL types needed by __GLcontextModes */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" + +/** + * Only color buffers are listed. The others are allocated privately through, + * for example, st_renderbuffer_alloc_storage(). + */ +enum native_attachment { + NATIVE_ATTACHMENT_FRONT_LEFT, + NATIVE_ATTACHMENT_BACK_LEFT, + NATIVE_ATTACHMENT_FRONT_RIGHT, + NATIVE_ATTACHMENT_BACK_RIGHT, + + NUM_NATIVE_ATTACHMENTS +}; + +/** + * Enumerations for probe results. + */ +enum native_probe_result { + NATIVE_PROBE_UNKNOWN, + NATIVE_PROBE_FALLBACK, + NATIVE_PROBE_SUPPORTED, + NATIVE_PROBE_EXACT, +}; + +/** + * A probe object for display probe. + */ +struct native_probe { + int magic; + EGLNativeDisplayType display; + void *data; + + void (*destroy)(struct native_probe *nprobe); +}; + +struct native_surface { + void (*destroy)(struct native_surface *nsurf); + + /** + * Swap the front and back buffers so that the back buffer is visible. It + * is no-op if the surface is single-buffered. The contents of the back + * buffer after swapping may or may not be preserved. + */ + boolean (*swap_buffers)(struct native_surface *nsurf); + + /** + * Make the front buffer visible. In some native displays, changes to the + * front buffer might not be visible immediately and require manual flush. + */ + boolean (*flush_frontbuffer)(struct native_surface *nsurf); + + /** + * Validate the buffers of the surface. textures, if not NULL, points to an + * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned + * by the caller. A sequence number is also returned. The caller can use + * it to check if anything has changed since the last call. Any of the + * pointers may be NULL and it indicates the caller has no interest in those + * values. + * + * If this function is called multiple times with different attachment + * masks, those not listed in the latest call might be destroyed. This + * behavior might change in the future. + */ + boolean (*validate)(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height); + + /** + * Wait until all native commands affecting the surface has been executed. + */ + void (*wait)(struct native_surface *nsurf); +}; + +struct native_config { + /* __GLcontextModes should go away some day */ + __GLcontextModes mode; + enum pipe_format color_format; + enum pipe_format depth_format; + enum pipe_format stencil_format; + + /* treat it as an additional flag to mode.drawableType */ + boolean scanout_bit; +}; + +struct native_connector { + int dummy; +}; + +struct native_mode { + const char *desc; + int width, height; + int refresh_rate; +}; + +struct native_display_modeset; + +/** + * A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis + * hardware. A native display consists of a pipe winsys, a pipe screen, and + * the native display server. + */ +struct native_display { + /** + * The pipe screen of the native display. + * + * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be + * overridden. + */ + struct pipe_screen *screen; + + void (*destroy)(struct native_display *ndpy); + + /** + * Get the supported configs. The configs are owned by the display, but + * the returned array should be free()ed. + * + * The configs will be converted to EGL config by + * _eglConfigFromContextModesRec and validated by _eglValidateConfig. + * Those failing to pass the test will be skipped. + */ + const struct native_config **(*get_configs)(struct native_display *ndpy, + int *num_configs); + + /** + * Test if a pixmap is supported by the given config. Required unless no + * config has GLX_PIXMAP_BIT set. + * + * This function is usually called to find a config that supports a given + * pixmap. Thus, it is usually called with the same pixmap in a row. + */ + boolean (*is_pixmap_supported)(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf); + + + /** + * Create a window surface. Required unless no config has GLX_WINDOW_BIT + * set. + */ + struct native_surface *(*create_window_surface)(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf); + + /** + * Create a pixmap surface. Required unless no config has GLX_PIXMAP_BIT + * set. + */ + struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf); + + /** + * Create a pbuffer surface. Required unless no config has GLX_PBUFFER_BIT + * set. + */ + struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height); + + const struct native_display_modeset *modeset; +}; + +/** + * Mode setting interface of the native display. It exposes the mode setting + * capabilities of the underlying graphics hardware. + */ +struct native_display_modeset { + /** + * Get the available physical connectors and the number of CRTCs. + */ + const struct native_connector **(*get_connectors)(struct native_display *ndpy, + int *num_connectors, + int *num_crtcs); + + /** + * Get the current supported modes of a connector. The returned modes may + * change every time this function is called and those from previous calls + * might become invalid. + */ + const struct native_mode **(*get_modes)(struct native_display *ndpy, + const struct native_connector *nconn, + int *num_modes); + + /** + * Create a scan-out surface. Required unless no config has + * GLX_SCREEN_BIT_MESA set. + */ + struct native_surface *(*create_scanout_surface)(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height); + + /** + * Program the CRTC to output the surface to the given connectors with the + * given mode. When surface is not given, the CRTC is disabled. + * + * This interface does not export a way to query capabilities of the CRTCs. + * The native display usually needs to dynamically map the index to a CRTC + * that supports the given connectors. + */ + boolean (*program)(struct native_display *ndpy, int crtc_idx, + struct native_surface *nsurf, uint x, uint y, + const struct native_connector **nconns, int num_nconns, + const struct native_mode *nmode); +}; + +/** + * Test whether an attachment is set in the mask. + */ +static INLINE boolean +native_attachment_mask_test(uint mask, enum native_attachment att) +{ + return !!(mask & (1 << att)); +} + +/** + * Return a probe object for the given display. + * + * Note that the returned object may be cached and used by different native + * display modules. It allows fast probing when multiple modules probe the + * same display. + */ +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy); + +/** + * Probe the probe object. + */ +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe); + +const char * +native_get_name(void); + +struct native_display * +native_create_display(EGLNativeDisplayType dpy); + +#endif /* _NATIVE_H_ */ diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h new file mode 100644 index 0000000000..507a0ec402 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h @@ -0,0 +1,20 @@ +ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share) +ST_PUBLIC(st_destroy_context, void, struct st_context *st) +ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask) +ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData) +ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height) +ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf) +ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height) +ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface) +ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture) +ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb) +ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb) +ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read) +ST_PUBLIC(st_get_current, struct st_context *, void) +ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence) +ST_PUBLIC(st_finish, void, struct st_context *st) +ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb) +ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format) +ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level) +ST_PUBLIC(st_get_proc_address, st_proc, const char *procname) +#undef ST_PUBLIC diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c deleted file mode 100644 index fee186c601..0000000000 --- a/src/gallium/state_trackers/egl/egl_context.c +++ /dev/null @@ -1,105 +0,0 @@ - -#include "utils.h" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "egl_tracker.h" - -#include "egllog.h" - - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/drm_api.h" - -#include "GL/internal/glcore.h" - -_EGLContext * -drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_context *ctx; - struct drm_context *share = NULL; - struct st_context *st_share = NULL; - int i; - __GLcontextModes *visual; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context)); - if (!ctx) - goto err_c; - - _eglInitContext(drv, &ctx->base, conf, attrib_list); - - ctx->pipe = dev->api->create_context(dev->api, dev->screen); - if (!ctx->pipe) - goto err_pipe; - - if (share) - st_share = share->st; - - visual = drm_visual_from_config(conf); - ctx->st = st_create_context(ctx->pipe, visual, st_share); - drm_visual_modes_destroy(visual); - - if (!ctx->st) - goto err_gl; - - return &ctx->base; - -err_gl: - ctx->pipe->destroy(ctx->pipe); -err_pipe: - free(ctx); -err_c: - return NULL; -} - -EGLBoolean -drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) -{ - struct drm_context *c = lookup_drm_context(context); - if (!_eglIsContextBound(&c->base)) { - st_destroy_context(c->st); - free(c); - } - return EGL_TRUE; -} - -EGLBoolean -drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context) -{ - struct drm_surface *readSurf = lookup_drm_surface(read); - struct drm_surface *drawSurf = lookup_drm_surface(draw); - struct drm_context *ctx = lookup_drm_context(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - if (!drawSurf || !readSurf) - return EGL_FALSE; - - st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb); - - /* st_resize_framebuffer needs a bound context to work */ - st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h); - st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h); - } else { - st_make_current(NULL, NULL, NULL); - } - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c deleted file mode 100644 index d55aa51b82..0000000000 --- a/src/gallium/state_trackers/egl/egl_surface.c +++ /dev/null @@ -1,443 +0,0 @@ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "egl_tracker.h" - -#include "egllog.h" - -#include "pipe/p_inlines.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -#include "state_tracker/drm_api.h" - -#include "util/u_format.h" -#include "util/u_rect.h" - -/* - * Util functions - */ - -static drmModeModeInfoPtr -drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) -{ - int i; - drmModeModeInfoPtr m = NULL; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) - break; - m = &connector->modes[0]; /* if we can't find one, return first */ - } - - return m; -} - -static struct st_framebuffer * -drm_create_framebuffer(struct pipe_screen *screen, - const __GLcontextModes *visual, - unsigned width, - unsigned height, - void *priv) -{ - enum pipe_format color_format, depth_stencil_format; - boolean d_depth_bits_last; - boolean ds_depth_bits_last; - - d_depth_bits_last = - screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - ds_depth_bits_last = - screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - - if (visual->redBits == 8) { - if (visual->alphaBits == 8) - color_format = PIPE_FORMAT_A8R8G8B8_UNORM; - else - color_format = PIPE_FORMAT_X8R8G8B8_UNORM; - } else { - color_format = PIPE_FORMAT_R5G6B5_UNORM; - } - - switch(visual->depthBits) { - default: - case 0: - depth_stencil_format = PIPE_FORMAT_NONE; - break; - case 16: - depth_stencil_format = PIPE_FORMAT_Z16_UNORM; - break; - case 24: - if (visual->stencilBits == 0) { - depth_stencil_format = (d_depth_bits_last) ? - PIPE_FORMAT_X8Z24_UNORM: - PIPE_FORMAT_Z24X8_UNORM; - } else { - depth_stencil_format = (ds_depth_bits_last) ? - PIPE_FORMAT_S8Z24_UNORM: - PIPE_FORMAT_Z24S8_UNORM; - } - break; - case 32: - depth_stencil_format = PIPE_FORMAT_Z32_UNORM; - break; - } - - return st_create_framebuffer(visual, - color_format, - depth_stencil_format, - depth_stencil_format, - width, - height, - priv); -} - -static void -drm_create_texture(_EGLDisplay *dpy, - struct drm_screen *scrn, - unsigned w, unsigned h) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct pipe_screen *screen = dev->screen; - struct pipe_surface *surface; - struct pipe_texture *texture; - struct pipe_texture templat; - struct pipe_buffer *buf = NULL; - unsigned pitch = 0; - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; - templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth0 = 1; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width0 = w; - templat.height0 = h; - - texture = screen->texture_create(dev->screen, - &templat); - - if (!texture) - goto err_tex; - - surface = screen->get_tex_surface(screen, - texture, - 0, - 0, - 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - - if (!surface) - goto err_surf; - - scrn->tex = texture; - scrn->surface = surface; - scrn->front.width = w; - scrn->front.height = h; - scrn->front.pitch = pitch; - dev->api->local_handle_from_texture(dev->api, screen, texture, - &scrn->front.pitch, &scrn->front.handle); - if (0) - goto err_handle; - - return; - -err_handle: - pipe_surface_reference(&surface, NULL); -err_surf: - pipe_texture_reference(&texture, NULL); -err_tex: - pipe_buffer_reference(&buf, NULL); - return; -} - -/* - * Exported functions - */ - -void -drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen) -{ - struct drm_device *dev = lookup_drm_device(dpy); - - screen->surf = NULL; - - drmModeSetCrtc( - dev->drmFD, - screen->crtcID, - 0, /* FD */ - 0, 0, - NULL, 0, /* List of output ids */ - NULL); - - drmModeRmFB(dev->drmFD, screen->fbID); - drmModeFreeFB(screen->fb); - screen->fb = NULL; - - pipe_surface_reference(&screen->surface, NULL); - pipe_texture_reference(&screen->tex, NULL); - - screen->shown = 0; -} - -/** - * Called by libEGL's eglCreateWindowSurface(). - */ -_EGLSurface * -drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) -{ - return NULL; -} - - -/** - * Called by libEGL's eglCreatePixmapSurface(). - */ -_EGLSurface * -drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) -{ - return NULL; -} - - -/** - * Called by libEGL's eglCreatePbufferSurface(). - */ -_EGLSurface * -drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - struct drm_device *dev = lookup_drm_device(dpy); - int i; - int width = -1; - int height = -1; - struct drm_surface *surf = NULL; - __GLcontextModes *visual; - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width < 1 || height < 1) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return NULL; - } - - surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); - if (!surf) - goto err; - - if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list)) - goto err_surf; - - surf->w = width; - surf->h = height; - - visual = drm_visual_from_config(conf); - surf->stfb = drm_create_framebuffer(dev->screen, visual, - width, height, - (void*)surf); - drm_visual_modes_destroy(visual); - - return &surf->base; - -err_surf: - free(surf); -err: - return NULL; -} - -/** - * Called by libEGL's eglCreateScreenSurfaceMESA(). - */ -_EGLSurface * -drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg, - const EGLint *attrib_list) -{ - EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); - - return surf; -} - -/** - * Called by libEGL's eglShowScreenSurfaceMESA(). - */ -EGLBoolean -drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLScreen *screen, - _EGLSurface *surface, _EGLMode *mode) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_surface *surf = lookup_drm_surface(surface); - struct drm_screen *scrn = lookup_drm_screen(screen); - int ret; - unsigned int i, k; - - if (scrn->shown) - drm_takedown_shown_screen(dpy, scrn); - - - drm_create_texture(dpy, scrn, mode->Width, mode->Height); - if (!scrn->tex) - goto err_tex; - - ret = drmModeAddFB(dev->drmFD, - scrn->front.width, scrn->front.height, - 32, 32, scrn->front.pitch, - scrn->front.handle, - &scrn->fbID); - - if (ret) - goto err_bo; - - scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID); - if (!scrn->fb) - goto err_bo; - - /* find a fitting crtc */ - { - drmModeConnector *con = scrn->connector; - - scrn->mode = drm_find_mode(con, mode); - if (!scrn->mode) - goto err_fb; - - for (k = 0; k < con->count_encoders; k++) { - drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]); - for (i = 0; i < dev->res->count_crtcs; i++) { - if (enc->possible_crtcs & (1<<i)) { - /* save the ID */ - scrn->crtcID = dev->res->crtcs[i]; - - /* skip the rest */ - i = dev->res->count_crtcs; - k = dev->res->count_encoders; - } - } - drmModeFreeEncoder(enc); - } - } - - ret = drmModeSetCrtc(dev->drmFD, - scrn->crtcID, - scrn->fbID, - 0, 0, - &scrn->connectorID, 1, - scrn->mode); - - if (ret) - goto err_crtc; - - - if (scrn->dpms) - drmModeConnectorSetProperty(dev->drmFD, - scrn->connectorID, - scrn->dpms->prop_id, - DRM_MODE_DPMS_ON); - - surf->screen = scrn; - - scrn->surf = surf; - scrn->shown = 1; - - return EGL_TRUE; - -err_crtc: - scrn->crtcID = 0; - -err_fb: - drmModeRmFB(dev->drmFD, scrn->fbID); - drmModeFreeFB(scrn->fb); - scrn->fb = NULL; - -err_bo: - pipe_surface_reference(&scrn->surface, NULL); - pipe_texture_reference(&scrn->tex, NULL); - -err_tex: - return EGL_FALSE; -} - -/** - * Called by libEGL's eglDestroySurface(). - */ -EGLBoolean -drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - struct drm_surface *surf = lookup_drm_surface(surface); - if (!_eglIsSurfaceBound(&surf->base)) { - if (surf->screen) - drm_takedown_shown_screen(dpy, surf->screen); - st_unreference_framebuffer(surf->stfb); - free(surf); - } - return EGL_TRUE; -} - -/** - * Called by libEGL's eglSwapBuffers(). - */ -EGLBoolean -drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_surface *surf = lookup_drm_surface(draw); - struct pipe_surface *back_surf; - - if (!surf) - return EGL_FALSE; - - st_get_framebuffer_surface(surf->stfb, ST_SURFACE_BACK_LEFT, &back_surf); - - if (back_surf) { - struct drm_context *ctx = lookup_drm_context(draw->Binding); - - st_notify_swapbuffers(surf->stfb); - - if (ctx && surf->screen) { - if (ctx->pipe->surface_copy) { - ctx->pipe->surface_copy(ctx->pipe, - surf->screen->surface, - 0, 0, - back_surf, - 0, 0, - surf->w, surf->h); - } else { - util_surface_copy(ctx->pipe, FALSE, - surf->screen->surface, - 0, 0, - back_surf, - 0, 0, - surf->w, surf->h); - } - ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL); - -#ifdef DRM_MODE_FEATURE_DIRTYFB - /* TODO query connector property to see if this is needed */ - drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0); -#else - (void)dev; -#endif - - /* TODO more stuff here */ - } - } - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c deleted file mode 100644 index 9345b0f490..0000000000 --- a/src/gallium/state_trackers/egl/egl_tracker.c +++ /dev/null @@ -1,274 +0,0 @@ - -#include "utils.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "egl_tracker.h" - -#include <fcntl.h> - -#include "egllog.h" -#include "state_tracker/drm_api.h" - -#include "pipe/p_screen.h" -#include "pipe/internal/p_winsys_screen.h" - -/** HACK */ -void* driDriverAPI; - - -/* - * Exported functions - */ - -/** Called by libEGL just prior to unloading/closing the driver. - */ -static void -drm_unload(_EGLDriver *drv) -{ - free(drv); -} - -/** - * The bootstrap function. Return a new drm_driver object and - * plug in API functions. - * libEGL finds this function with dlopen()/dlsym() and calls it from - * "load driver" function. - */ -_EGLDriver * -_eglMain(const char *args) -{ - _EGLDriver *drv; - - drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver)); - if (!drv) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(drv); - /* then plug in our Drm-specific functions */ - drv->API.Initialize = drm_initialize; - drv->API.Terminate = drm_terminate; - drv->API.CreateContext = drm_create_context; - drv->API.MakeCurrent = drm_make_current; - drv->API.CreateWindowSurface = drm_create_window_surface; - drv->API.CreatePixmapSurface = drm_create_pixmap_surface; - drv->API.CreatePbufferSurface = drm_create_pbuffer_surface; - drv->API.DestroySurface = drm_destroy_surface; - drv->API.DestroyContext = drm_destroy_context; - drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; - drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; - drv->API.SwapBuffers = drm_swap_buffers; - - drv->Name = "DRM/Gallium/Win"; - drv->Unload = drm_unload; - - return drv; -} - -static void -drm_get_device_id(struct drm_device *device) -{ - char path[512]; - FILE *file; - char *ret; - - /* TODO get the real minor */ - int minor = 0; - - device->deviceID = 0; - - snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); - file = fopen(path, "r"); - if (!file) { - _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); - return; - } - - ret = fgets(path, sizeof( path ), file); - fclose(file); - if (!ret) - return; - - sscanf(path, "%x", &device->deviceID); -} - -static void -drm_update_res(struct drm_device *dev) -{ - drmModeFreeResources(dev->res); - dev->res = drmModeGetResources(dev->drmFD); -} - -static void -drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) -{ - drmModeModeInfoPtr m = NULL; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); - } -} - -static void -drm_find_dpms(struct drm_device *dev, struct drm_screen *screen) -{ - drmModeConnectorPtr c = screen->connector; - drmModePropertyPtr p; - int i; - - for (i = 0; i < c->count_props; i++) { - p = drmModeGetProperty(dev->drmFD, c->props[i]); - if (!strcmp(p->name, "DPMS")) - break; - - drmModeFreeProperty(p); - p = NULL; - } - - screen->dpms = p; -} - -static int drm_open_minor(int minor) -{ - char buf[64]; - - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); - return open(buf, O_RDWR, 0); -} - -EGLBoolean -drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) -{ - struct drm_device *dev; - struct drm_screen *screen = NULL; - drmModeConnectorPtr connector = NULL; - drmModeResPtr res = NULL; - unsigned count_connectors = 0; - int num_screens = 0; - EGLint i; - int fd; - _EGLConfig *config; - - dev = (struct drm_device *) calloc(1, sizeof(struct drm_device)); - if (!dev) - return EGL_FALSE; - dev->api = drm_api_create(); - - /* try the first node */ - fd = drm_open_minor(0); - if (fd < 0) - goto err_fd; - - dev->drmFD = fd; - drm_get_device_id(dev); - - dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL); - if (!dev->screen) - goto err_screen; - dev->winsys = dev->screen->winsys; - - driInitExtensions(NULL, NULL, GL_FALSE); - - drm_update_res(dev); - res = dev->res; - if (res) - count_connectors = res->count_connectors; - else - _eglLog(_EGL_WARNING, "Could not retrive kms information\n"); - - for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); - - if (!connector) - continue; - - if (connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - - screen = malloc(sizeof(struct drm_screen)); - memset(screen, 0, sizeof(*screen)); - screen->connector = connector; - screen->connectorID = connector->connector_id; - _eglInitScreen(&screen->base); - _eglAddScreen(disp, &screen->base); - drm_add_modes_from_connector(&screen->base, connector); - drm_find_dpms(dev, screen); - dev->screens[num_screens++] = screen; - } - dev->count_screens = num_screens; - - disp->DriverData = dev; - - /* for now we only have one config */ - config = calloc(1, sizeof(*config)); - memset(config, 1, sizeof(*config)); - _eglInitConfig(config, 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, config); - - disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - /* enable supported extensions */ - disp->Extensions.MESA_screen_surface = EGL_TRUE; - disp->Extensions.MESA_copy_context = EGL_TRUE; - - *major = 1; - *minor = 4; - - return EGL_TRUE; - -err_screen: - drmClose(fd); -err_fd: - free(dev); - return EGL_FALSE; -} - -EGLBoolean -drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct drm_device *dev = lookup_drm_device(dpy); - struct drm_screen *screen; - int i = 0; - - _eglReleaseDisplayResources(drv, dpy); - _eglCleanupDisplay(dpy); - - drmFreeVersion(dev->version); - - for (i = 0; i < dev->count_screens; i++) { - screen = dev->screens[i]; - - if (screen->shown) - drm_takedown_shown_screen(dpy, screen); - - drmModeFreeProperty(screen->dpms); - drmModeFreeConnector(screen->connector); - _eglDestroyScreen(&screen->base); - dev->screens[i] = NULL; - } - - dev->screen->destroy(dev->screen); - dev->winsys = NULL; - - drmClose(dev->drmFD); - - dev->api->destroy(dev->api); - free(dev); - dpy->DriverData = NULL; - - return EGL_TRUE; -} diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h deleted file mode 100644 index 73eb1a1226..0000000000 --- a/src/gallium/state_trackers/egl/egl_tracker.h +++ /dev/null @@ -1,195 +0,0 @@ - -#ifndef _EGL_TRACKER_H_ -#define _EGL_TRACKER_H_ - -#include <stdint.h> - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" - -#include "xf86drm.h" -#include "xf86drmMode.h" - -#include "pipe/p_compiler.h" - -#include "state_tracker/st_public.h" - -#define MAX_SCREENS 16 - -struct pipe_winsys; -struct pipe_screen; -struct pipe_context; -struct state_tracker; - -struct drm_screen; -struct drm_context; - -struct drm_device -{ - /* - * pipe - */ - - struct drm_api *api; - struct pipe_winsys *winsys; - struct pipe_screen *screen; - - /* - * drm - */ - - int drmFD; - drmVersionPtr version; - int deviceID; - - drmModeResPtr res; - - struct drm_screen *screens[MAX_SCREENS]; - size_t count_screens; -}; - -struct drm_surface -{ - _EGLSurface base; /* base class/object */ - - /* - * pipe - */ - - - struct st_framebuffer *stfb; - - /* - * drm - */ - - struct drm_screen *screen; - - int w; - int h; -}; - -struct drm_context -{ - _EGLContext base; /* base class/object */ - - /* pipe */ - - struct pipe_context *pipe; - struct st_context *st; -}; - -struct drm_screen -{ - _EGLScreen base; - - /* - * pipe - */ - - struct pipe_texture *tex; - struct pipe_surface *surface; - - /* - * drm - */ - - struct { - unsigned height; - unsigned width; - unsigned pitch; - unsigned handle; - } front; - - /* currently only support one connector */ - drmModeConnectorPtr connector; - uint32_t connectorID; - - /* dpms property */ - drmModePropertyPtr dpms; - - /* Has this screen been shown */ - int shown; - - /* Surface that is currently attached to this screen */ - struct drm_surface *surf; - - /* framebuffer */ - drmModeFBPtr fb; - uint32_t fbID; - - /* crtc and mode used */ - /*drmModeCrtcPtr crtc;*/ - uint32_t crtcID; - - drmModeModeInfoPtr mode; -}; - - -static INLINE struct drm_device * -lookup_drm_device(_EGLDisplay *d) -{ - return (struct drm_device *) d->DriverData; -} - - -static INLINE struct drm_context * -lookup_drm_context(_EGLContext *c) -{ - return (struct drm_context *) c; -} - - -static INLINE struct drm_surface * -lookup_drm_surface(_EGLSurface *s) -{ - return (struct drm_surface *) s; -} - -static INLINE struct drm_screen * -lookup_drm_screen(_EGLScreen *s) -{ - return (struct drm_screen *) s; -} - -/** - * egl_visual.h - */ -/*@{*/ -void drm_visual_modes_destroy(__GLcontextModes *modes); -__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size); -__GLcontextModes* drm_visual_from_config(_EGLConfig *conf); -/*@}*/ - -/** - * egl_surface.h - */ -/*@{*/ -void drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen); -/*@}*/ - -/** - * All function exported to the egl side. - */ -/*@{*/ -EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor); -EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy); -_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list); -EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context); -_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list); -_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list); -_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); -_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list); -EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode); -EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface); -EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context); -EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw); -/*@}*/ - -#endif diff --git a/src/gallium/state_trackers/egl/egl_visual.c b/src/gallium/state_trackers/egl/egl_visual.c deleted file mode 100644 index e59f893851..0000000000 --- a/src/gallium/state_trackers/egl/egl_visual.c +++ /dev/null @@ -1,85 +0,0 @@ - -#include "egl_tracker.h" - -#include "egllog.h" - -void -drm_visual_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} - -__GLcontextModes * -drm_visual_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - drm_visual_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - -__GLcontextModes * -drm_visual_from_config(_EGLConfig *conf) -{ - __GLcontextModes *visual; - (void)conf; - - visual = drm_visual_modes_create(1, sizeof(*visual)); - visual->redBits = 8; - visual->greenBits = 8; - visual->blueBits = 8; - visual->alphaBits = 8; - - visual->rgbBits = 32; - visual->doubleBufferMode = 1; - - visual->depthBits = 24; - visual->haveDepthBuffer = visual->depthBits > 0; - visual->stencilBits = 8; - visual->haveStencilBuffer = visual->stencilBits > 0; - - return visual; -} diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c new file mode 100644 index 0000000000..91cefc538d --- /dev/null +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -0,0 +1,856 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <stdio.h> +#include <string.h> + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "egllog.h" + +#include "native_kms.h" + +static boolean +kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + struct pipe_screen *screen = kdpy->base.screen; + struct pipe_texture templ, *ptex; + int att; + + if (attachment_mask) { + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = ksurf->width; + templ.height0 = ksurf->height; + templ.depth0 = 1; + templ.format = ksurf->color_format; + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT) + templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + } + + /* create textures */ + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) + continue; + + ptex = ksurf->textures[att]; + if (!ptex) { + ptex = screen->texture_create(screen, &templ); + ksurf->textures[att] = ptex; + } + + if (textures) { + textures[att] = NULL; + pipe_texture_reference(&textures[att], ptex); + } + } + + if (seq_num) + *seq_num = ksurf->sequence_number; + if (width) + *width = ksurf->width; + if (height) + *height = ksurf->height; + + return TRUE; +} + +/** + * Add textures as DRM framebuffers. + */ +static boolean +kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + int num_framebuffers = (need_back) ? 2 : 1; + int i, err; + + for (i = 0; i < num_framebuffers; i++) { + struct kms_framebuffer *fb; + enum native_attachment natt; + unsigned int handle, stride; + uint block_bits; + + if (i == 0) { + fb = &ksurf->front_fb; + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + } + else { + fb = &ksurf->back_fb; + natt = NATIVE_ATTACHMENT_BACK_LEFT; + } + + if (!fb->texture) { + /* make sure the texture has been allocated */ + kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL); + if (!ksurf->textures[natt]) + return FALSE; + + pipe_texture_reference(&fb->texture, ksurf->textures[natt]); + } + + /* already initialized */ + if (fb->buffer_id) + continue; + + /* TODO detect the real value */ + fb->is_passive = TRUE; + + if (!kdpy->api->local_handle_from_texture(kdpy->api, + kdpy->base.screen, fb->texture, &stride, &handle)) + return FALSE; + + block_bits = util_format_get_blocksizebits(ksurf->color_format); + err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height, + block_bits, block_bits, stride, handle, &fb->buffer_id); + if (err) { + fb->buffer_id = 0; + return FALSE; + } + } + + return TRUE; +} + +static boolean +kms_surface_flush_frontbuffer(struct native_surface *nsurf) +{ +#ifdef DRM_MODE_FEATURE_DIRTYFB + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_display *kdpy = ksurf->kdpy; + + /* pbuffer is private */ + if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) + return TRUE; + + if (ksurf->front_fb.is_passive) + drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0); +#endif + + return TRUE; +} + +static boolean +kms_surface_swap_buffers(struct native_surface *nsurf) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + struct kms_crtc *kcrtc = &ksurf->current_crtc; + struct kms_display *kdpy = ksurf->kdpy; + struct kms_framebuffer tmp_fb; + struct pipe_texture *tmp_texture; + int err; + + /* pbuffer is private */ + if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER) + return TRUE; + + if (!ksurf->back_fb.buffer_id) { + if (!kms_surface_init_framebuffers(&ksurf->base, TRUE)) + return FALSE; + } + + if (ksurf->is_shown && kcrtc->crtc) { + err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, + ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, + kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode); + if (err) + return FALSE; + } + + /* swap the buffers */ + tmp_fb = ksurf->front_fb; + ksurf->front_fb = ksurf->back_fb; + ksurf->back_fb = tmp_fb; + + tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT]; + ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] = + ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT]; + ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture; + + /* the front/back textures are swapped */ + ksurf->sequence_number++; + + return TRUE; +} + +static void +kms_surface_wait(struct native_surface *nsurf) +{ + /* no-op */ +} + +static void +kms_surface_destroy(struct native_surface *nsurf) +{ + struct kms_surface *ksurf = kms_surface(nsurf); + int i; + + if (ksurf->current_crtc.crtc) + drmModeFreeCrtc(ksurf->current_crtc.crtc); + + if (ksurf->front_fb.buffer_id) + drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id); + pipe_texture_reference(&ksurf->front_fb.texture, NULL); + + if (ksurf->back_fb.buffer_id) + drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id); + pipe_texture_reference(&ksurf->back_fb.texture, NULL); + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct pipe_texture *ptex = ksurf->textures[i]; + pipe_texture_reference(&ptex, NULL); + } + + free(ksurf); +} + +static struct kms_surface * +kms_display_create_surface(struct native_display *ndpy, + enum kms_surface_type type, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_config *kconf = kms_config(nconf); + struct kms_surface *ksurf; + + ksurf = CALLOC_STRUCT(kms_surface); + if (!ksurf) + return NULL; + + ksurf->kdpy = kdpy; + ksurf->type = type; + ksurf->color_format = kconf->base.color_format; + ksurf->width = width; + ksurf->height = height; + + ksurf->base.destroy = kms_surface_destroy; + ksurf->base.swap_buffers = kms_surface_swap_buffers; + ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer; + ksurf->base.validate = kms_surface_validate; + ksurf->base.wait = kms_surface_wait; + + return ksurf; +} + +/** + * Choose a CRTC that supports all given connectors. + */ +static uint32_t +kms_display_choose_crtc(struct native_display *ndpy, + uint32_t *connectors, int num_connectors) +{ + struct kms_display *kdpy = kms_display(ndpy); + int idx; + + for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) { + boolean found_crtc = TRUE; + int i, j; + + for (i = 0; i < num_connectors; i++) { + drmModeConnectorPtr connector; + int encoder_idx = -1; + + connector = drmModeGetConnector(kdpy->fd, connectors[i]); + if (!connector) { + found_crtc = FALSE; + break; + } + + /* find an encoder the CRTC supports */ + for (j = 0; j < connector->count_encoders; j++) { + drmModeEncoderPtr encoder = + drmModeGetEncoder(kdpy->fd, connector->encoders[j]); + if (encoder->possible_crtcs & (1 << idx)) { + encoder_idx = j; + break; + } + drmModeFreeEncoder(encoder); + } + + drmModeFreeConnector(connector); + if (encoder_idx < 0) { + found_crtc = FALSE; + break; + } + } + + if (found_crtc) + break; + } + + if (idx >= kdpy->resources->count_crtcs) { + _eglLog(_EGL_WARNING, + "failed to find a CRTC that supports the given %d connectors", + num_connectors); + return 0; + } + + return kdpy->resources->crtcs[idx]; +} + +/** + * Remember the original CRTC status and set the CRTC + */ +static boolean +kms_display_set_crtc(struct native_display *ndpy, int crtc_idx, + uint32_t buffer_id, uint32_t x, uint32_t y, + uint32_t *connectors, int num_connectors, + drmModeModeInfoPtr mode) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx]; + uint32_t crtc_id; + int err; + + if (kcrtc->crtc) { + crtc_id = kcrtc->crtc->crtc_id; + } + else { + int count = 0, i; + + /* + * Choose the CRTC once. It could be more dynamic, but let's keep it + * simple for now. + */ + crtc_id = kms_display_choose_crtc(&kdpy->base, + connectors, num_connectors); + + /* save the original CRTC status */ + kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); + if (!kcrtc->crtc) + return FALSE; + + for (i = 0; i < kdpy->num_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + drmModeConnectorPtr connector = kconn->connector; + drmModeEncoderPtr encoder; + + encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id); + if (encoder) { + if (encoder->crtc_id == crtc_id) { + kcrtc->connectors[count++] = connector->connector_id; + if (count >= Elements(kcrtc->connectors)) + break; + } + drmModeFreeEncoder(encoder); + } + } + + kcrtc->num_connectors = count; + } + + err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y, + connectors, num_connectors, mode); + if (err) { + drmModeFreeCrtc(kcrtc->crtc); + kcrtc->crtc = NULL; + kcrtc->num_connectors = 0; + + return FALSE; + } + + return TRUE; +} + +static boolean +kms_display_program(struct native_display *ndpy, int crtc_idx, + struct native_surface *nsurf, uint x, uint y, + const struct native_connector **nconns, int num_nconns, + const struct native_mode *nmode) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_surface *ksurf = kms_surface(nsurf); + const struct kms_mode *kmode = kms_mode(nmode); + uint32_t connector_ids[32]; + uint32_t buffer_id; + drmModeModeInfo mode_tmp, *mode; + int i; + + if (num_nconns > Elements(connector_ids)) { + _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns); + num_nconns = Elements(connector_ids); + } + + if (ksurf) { + if (!kms_surface_init_framebuffers(&ksurf->base, FALSE)) + return FALSE; + + buffer_id = ksurf->front_fb.buffer_id; + /* the mode argument of drmModeSetCrtc is not constified */ + mode_tmp = kmode->mode; + mode = &mode_tmp; + } + else { + /* disable the CRTC */ + buffer_id = 0; + mode = NULL; + num_nconns = 0; + } + + for (i = 0; i < num_nconns; i++) { + struct kms_connector *kconn = kms_connector(nconns[i]); + connector_ids[i] = kconn->connector->connector_id; + } + + if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y, + connector_ids, num_nconns, mode)) { + _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx); + + return FALSE; + } + + if (kdpy->shown_surfaces[crtc_idx]) + kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE; + kdpy->shown_surfaces[crtc_idx] = ksurf; + + /* remember the settings for buffer swapping */ + if (ksurf) { + uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id; + struct kms_crtc *kcrtc = &ksurf->current_crtc; + + if (kcrtc->crtc) + drmModeFreeCrtc(kcrtc->crtc); + kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id); + + assert(num_nconns < Elements(kcrtc->connectors)); + memcpy(kcrtc->connectors, connector_ids, + sizeof(*connector_ids) * num_nconns); + kcrtc->num_connectors = num_nconns; + + ksurf->is_shown = TRUE; + } + + return TRUE; +} + +static const struct native_mode ** +kms_display_get_modes(struct native_display *ndpy, + const struct native_connector *nconn, + int *num_modes) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct kms_connector *kconn = kms_connector(nconn); + const struct native_mode **nmodes_return; + int count, i; + + /* delete old data */ + if (kconn->connector) { + drmModeFreeConnector(kconn->connector); + free(kconn->kms_modes); + + kconn->connector = NULL; + kconn->kms_modes = NULL; + kconn->num_modes = 0; + } + + /* detect again */ + kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id); + if (!kconn->connector) + return NULL; + + count = kconn->connector->count_modes; + kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes)); + if (!kconn->kms_modes) { + drmModeFreeConnector(kconn->connector); + kconn->connector = NULL; + + return NULL; + } + + for (i = 0; i < count; i++) { + struct kms_mode *kmode = &kconn->kms_modes[i]; + drmModeModeInfoPtr mode = &kconn->connector->modes[i]; + + kmode->mode = *mode; + + kmode->base.desc = kmode->mode.name; + kmode->base.width = kmode->mode.hdisplay; + kmode->base.height = kmode->mode.vdisplay; + kmode->base.refresh_rate = kmode->mode.vrefresh / 1000; + } + + nmodes_return = malloc(count * sizeof(*nmodes_return)); + if (nmodes_return) { + for (i = 0; i < count; i++) + nmodes_return[i] = &kconn->kms_modes[i].base; + if (num_modes) + *num_modes = count; + } + + return nmodes_return; +} + +static const struct native_connector ** +kms_display_get_connectors(struct native_display *ndpy, int *num_connectors, + int *num_crtc) +{ + struct kms_display *kdpy = kms_display(ndpy); + const struct native_connector **connectors; + int i; + + if (!kdpy->connectors) { + kdpy->connectors = + calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors)); + if (!kdpy->connectors) + return NULL; + + for (i = 0; i < kdpy->resources->count_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + + kconn->connector_id = kdpy->resources->connectors[i]; + /* kconn->connector is allocated when the modes are asked */ + } + + kdpy->num_connectors = kdpy->resources->count_connectors; + } + + connectors = malloc(kdpy->num_connectors * sizeof(*connectors)); + if (connectors) { + for (i = 0; i < kdpy->num_connectors; i++) + connectors[i] = &kdpy->connectors[i].base; + if (num_connectors) + *num_connectors = kdpy->num_connectors; + } + + if (num_crtc) + *num_crtc = kdpy->resources->count_crtcs; + + return connectors; +} + +static struct native_surface * +kms_display_create_scanout_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_surface *ksurf; + + ksurf = kms_display_create_surface(ndpy, + KMS_SURFACE_TYPE_SCANOUT, nconf, width, height); + return &ksurf->base; +} + +static struct native_surface * +kms_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct kms_surface *ksurf; + + ksurf = kms_display_create_surface(ndpy, + KMS_SURFACE_TYPE_PBUFFER, nconf, width, height); + return &ksurf->base; +} + + +static boolean +kms_display_is_format_supported(struct native_display *ndpy, + enum pipe_format fmt, boolean is_color) +{ + return ndpy->screen->is_format_supported(ndpy->screen, + fmt, PIPE_TEXTURE_2D, + (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); +} + +static const struct native_config ** +kms_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct kms_display *kdpy = kms_display(ndpy); + const struct native_config **configs; + + /* first time */ + if (!kdpy->config) { + struct native_config *nconf; + enum pipe_format format; + + kdpy->config = calloc(1, sizeof(*kdpy->config)); + if (!kdpy->config) + return NULL; + + nconf = &kdpy->config->base; + + /* always double-buffered */ + nconf->mode.doubleBufferMode = TRUE; + + format = PIPE_FORMAT_A8R8G8B8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) { + format = PIPE_FORMAT_B8G8R8A8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) + format = PIPE_FORMAT_NONE; + } + if (format == PIPE_FORMAT_NONE) + return NULL; + + nconf->color_format = format; + nconf->mode.redBits = 8; + nconf->mode.greenBits = 8; + nconf->mode.blueBits = 8; + nconf->mode.alphaBits = 8; + nconf->mode.rgbBits = 32; + + format = PIPE_FORMAT_S8Z24_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) { + format = PIPE_FORMAT_Z24S8_UNORM; + if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) + format = PIPE_FORMAT_NONE; + } + if (format != PIPE_FORMAT_NONE) { + nconf->depth_format = format; + nconf->stencil_format = format; + + nconf->mode.depthBits = 24; + nconf->mode.stencilBits = 8; + nconf->mode.haveDepthBuffer = TRUE; + nconf->mode.haveStencilBuffer = TRUE; + } + + nconf->scanout_bit = TRUE; + nconf->mode.drawableType = GLX_PBUFFER_BIT; + nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML; + + nconf->mode.visualID = 0; + nconf->mode.visualType = EGL_NONE; + + nconf->mode.renderType = GLX_RGBA_BIT; + nconf->mode.rgbMode = TRUE; + nconf->mode.xRenderable = FALSE; + } + + configs = malloc(sizeof(*configs)); + if (configs) { + configs[0] = &kdpy->config->base; + if (num_configs) + *num_configs = 1; + } + + return configs; +} + +static void +kms_display_destroy(struct native_display *ndpy) +{ + struct kms_display *kdpy = kms_display(ndpy); + int i; + + if (kdpy->config) + free(kdpy->config); + + if (kdpy->connectors) { + for (i = 0; i < kdpy->num_connectors; i++) { + struct kms_connector *kconn = &kdpy->connectors[i]; + if (kconn->connector) { + drmModeFreeConnector(kconn->connector); + free(kconn->kms_modes); + } + } + free(kdpy->connectors); + } + + if (kdpy->shown_surfaces) + free(kdpy->shown_surfaces); + + if (kdpy->saved_crtcs) { + for (i = 0; i < kdpy->resources->count_crtcs; i++) { + struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i]; + + if (kcrtc->crtc) { + /* restore crtc */ + drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id, + kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y, + kcrtc->connectors, kcrtc->num_connectors, + &kcrtc->crtc->mode); + + drmModeFreeCrtc(kcrtc->crtc); + } + } + free(kdpy->saved_crtcs); + } + + if (kdpy->resources) + drmModeFreeResources(kdpy->resources); + + if (kdpy->base.screen) + kdpy->base.screen->destroy(kdpy->base.screen); + + if (kdpy->fd >= 0) + drmClose(kdpy->fd); + + if (kdpy->api) + kdpy->api->destroy(kdpy->api); + free(kdpy); +} + +/** + * Initialize KMS and pipe screen. + */ +static boolean +kms_display_init_screen(struct native_display *ndpy) +{ + struct kms_display *kdpy = kms_display(ndpy); + struct drm_create_screen_arg arg; + int fd; + + fd = drmOpen(kdpy->api->name, NULL); + if (fd < 0) { + _eglLog(_EGL_WARNING, "failed to open DRM device"); + return FALSE; + } + +#if 0 + if (drmSetMaster(fd)) { + _eglLog(_EGL_WARNING, "failed to become DRM master"); + return FALSE; + } +#endif + + memset(&arg, 0, sizeof(arg)); + arg.mode = DRM_CREATE_NORMAL; + kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg); + if (!kdpy->base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + drmClose(fd); + return FALSE; + } + + kdpy->fd = fd; + + return TRUE; +} + +static struct native_display_modeset kms_display_modeset = { + .get_connectors = kms_display_get_connectors, + .get_modes = kms_display_get_modes, + .create_scanout_surface = kms_display_create_scanout_surface, + .program = kms_display_program +}; + +static struct native_display * +kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api) +{ + struct kms_display *kdpy; + + kdpy = CALLOC_STRUCT(kms_display); + if (!kdpy) + return NULL; + + kdpy->api = api; + if (!kdpy->api) { + _eglLog(_EGL_WARNING, "failed to create DRM API"); + free(kdpy); + return NULL; + } + + kdpy->fd = -1; + if (!kms_display_init_screen(&kdpy->base)) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + /* resources are fixed, unlike crtc, connector, or encoder */ + kdpy->resources = drmModeGetResources(kdpy->fd); + if (!kdpy->resources) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->saved_crtcs = + calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs)); + if (!kdpy->saved_crtcs) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->shown_surfaces = + calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces)); + if (!kdpy->shown_surfaces) { + kms_display_destroy(&kdpy->base); + return NULL; + } + + kdpy->base.destroy = kms_display_destroy; + kdpy->base.get_configs = kms_display_get_configs; + kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface; + + kdpy->base.modeset = &kms_display_modeset; + + return &kdpy->base; +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + return NULL; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + return NATIVE_PROBE_UNKNOWN; +} + +/* the api is destroyed with the native display */ +static struct drm_api *drm_api; + +const char * +native_get_name(void) +{ + static char kms_name[32]; + + if (!drm_api) + drm_api = drm_api_create(); + + if (drm_api) + snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name); + else + snprintf(kms_name, sizeof(kms_name), "KMS"); + + return kms_name; +} + +struct native_display * +native_create_display(EGLNativeDisplayType dpy) +{ + struct native_display *ndpy = NULL; + + if (!drm_api) + drm_api = drm_api_create(); + + if (drm_api) + ndpy = kms_create_display(dpy, drm_api); + + return ndpy; +} diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h new file mode 100644 index 0000000000..095186e3cf --- /dev/null +++ b/src/gallium/state_trackers/egl/kms/native_kms.h @@ -0,0 +1,139 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _NATIVE_KMS_H_ +#define _NATIVE_KMS_H_ + +#include <xf86drm.h> +#include <xf86drmMode.h> + +#include "pipe/p_compiler.h" +#include "util/u_format.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_api.h" + +#include "common/native.h" + +enum kms_surface_type { + KMS_SURFACE_TYPE_PBUFFER, + KMS_SURFACE_TYPE_SCANOUT +}; + +struct kms_config; +struct kms_connector; +struct kms_mode; + +struct kms_crtc { + drmModeCrtcPtr crtc; + uint32_t connectors[32]; + int num_connectors; +}; + +struct kms_display { + struct native_display base; + + int fd; + struct drm_api *api; + drmModeResPtr resources; + struct kms_config *config; + + struct kms_connector *connectors; + int num_connectors; + + struct kms_surface **shown_surfaces; + /* save the original settings of the CRTCs */ + struct kms_crtc *saved_crtcs; +}; + +struct kms_framebuffer { + struct pipe_texture *texture; + boolean is_passive; + + uint32_t buffer_id; +}; + +struct kms_surface { + struct native_surface base; + enum kms_surface_type type; + enum pipe_format color_format; + struct kms_display *kdpy; + int width, height; + + struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; + unsigned int sequence_number; + struct kms_framebuffer front_fb, back_fb; + + boolean is_shown; + struct kms_crtc current_crtc; +}; + +struct kms_config { + struct native_config base; +}; + +struct kms_connector { + struct native_connector base; + + uint32_t connector_id; + drmModeConnectorPtr connector; + struct kms_mode *kms_modes; + int num_modes; +}; + +struct kms_mode { + struct native_mode base; + drmModeModeInfo mode; +}; + +static INLINE struct kms_display * +kms_display(const struct native_display *ndpy) +{ + return (struct kms_display *) ndpy; +} + +static INLINE struct kms_surface * +kms_surface(const struct native_surface *nsurf) +{ + return (struct kms_surface *) nsurf; +} + +static INLINE struct kms_config * +kms_config(const struct native_config *nconf) +{ + return (struct kms_config *) nconf; +} + +static INLINE struct kms_connector * +kms_connector(const struct native_connector *nconn) +{ + return (struct kms_connector *) nconn; +} + +static INLINE struct kms_mode * +kms_mode(const struct native_mode *nmode) +{ + return (struct kms_mode *) nmode; +} + +#endif /* _NATIVE_KMS_H_ */ diff --git a/src/egl/drivers/xdri/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c index 7775009394..1ed2afd345 100644 --- a/src/egl/drivers/xdri/glxinit.c +++ b/src/gallium/state_trackers/egl/x11/glxinit.c @@ -1,8 +1,10 @@ /** * GLX initialization. Code based on glxext.c, glx_query.c, and - * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI - * related code here. + * glcontextmodes.c under src/glx/. The major difference is that DRI + * related code is stripped out. * + * If the maintenance of this file takes too much time, we should consider + * refactoring glxext.c. */ #include <assert.h> @@ -31,8 +33,26 @@ typedef struct GLXGenericGetString static char *__glXExtensionName = GLX_EXTENSION_NAME; static XExtensionInfo *__glXExtensionInfo = NULL; -static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; -static +static int +__glXCloseDisplay(Display * dpy, XExtCodes * codes) +{ + return XextRemoveDisplay(__glXExtensionInfo, dpy); +} + +static /* const */ XExtensionHooks __glXExtensionHooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + __glXCloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, __glXExtensionName, &__glXExtensionHooks, __GLX_NUMBER_EVENTS, NULL) @@ -180,6 +200,30 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) priv->screenConfigs = NULL; } +/* +** Release the private memory referred to in a display private +** structure. The caller will free the extension structure. +*/ +static int +__glXFreeDisplayPrivate(XExtData * extension) +{ + __GLXdisplayPrivate *priv; + + priv = (__GLXdisplayPrivate *) extension->private_data; + FreeScreenConfigs(priv); + if (priv->serverGLXvendor) { + Xfree((char *) priv->serverGLXvendor); + priv->serverGLXvendor = 0x0; /* to protect against double free's */ + } + if (priv->serverGLXversion) { + Xfree((char *) priv->serverGLXversion); + priv->serverGLXversion = 0x0; /* to protect against double free's */ + } + + Xfree((char *) priv); + return 0; +} + /************************************************************************/ /* @@ -570,40 +614,40 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) return GL_TRUE; } -_X_HIDDEN void -__glXRelease(__GLXdisplayPrivate *dpyPriv) -{ - FreeScreenConfigs(dpyPriv); - - if (dpyPriv->serverGLXvendor) { - Xfree((char *) dpyPriv->serverGLXvendor); - dpyPriv->serverGLXvendor = NULL; - } - if (dpyPriv->serverGLXversion) { - Xfree((char *) dpyPriv->serverGLXversion); - dpyPriv->serverGLXversion = NULL; - } - - Xfree(dpyPriv); -} - _X_HIDDEN __GLXdisplayPrivate * __glXInitialize(Display * dpy) { XExtDisplayInfo *info = __glXFindDisplay(dpy); + XExtData **privList, *private, *found; __GLXdisplayPrivate *dpyPriv; + XEDataObject dataObj; int major, minor; if (!XextHasExtension(info)) return NULL; + /* See if a display private already exists. If so, return it */ + dataObj.display = dpy; + privList = XEHeadOfExtensionList(dataObj); + found = XFindOnExtensionList(privList, info->codes->extension); + if (found) + return (__GLXdisplayPrivate *) found->private_data; + /* See if the versions are compatible */ if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) return NULL; + /* + ** Allocate memory for all the pieces needed for this buffer. + */ + private = (XExtData *) Xmalloc(sizeof(XExtData)); + if (!private) + return NULL; dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); - if (!dpyPriv) + if (!dpyPriv) { + Xfree(private); return NULL; + } /* ** Init the display private and then read in the screen config @@ -619,8 +663,20 @@ __glXInitialize(Display * dpy) if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { Xfree(dpyPriv); + Xfree(private); return NULL; } + /* + ** Fill in the private structure. This is the actual structure that + ** hangs off of the Display structure. Our private structure is + ** referred to by this structure. Got that? + */ + private->number = info->codes->extension; + private->next = 0; + private->free_private = __glXFreeDisplayPrivate; + private->private_data = (char *) dpyPriv; + XAddToExtensionList(privList, private); + return dpyPriv; } diff --git a/src/egl/drivers/xdri/glxinit.h b/src/gallium/state_trackers/egl/x11/glxinit.h index 57206e627b..1cc7c460fe 100644 --- a/src/egl/drivers/xdri/glxinit.h +++ b/src/gallium/state_trackers/egl/x11/glxinit.h @@ -8,7 +8,4 @@ extern void _gl_context_modes_destroy(__GLcontextModes * modes); -extern void -__glXRelease(__GLXdisplayPrivate *dpyPriv); - #endif /* GLXINIT_INCLUDED */ diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c new file mode 100644 index 0000000000..5f2fd41260 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -0,0 +1,693 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "util/u_inlines.h" +#include "pipe/p_compiler.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/drm_api.h" +#include "egllog.h" + +#include "native_x11.h" +#include "x11_screen.h" + +enum dri2_surface_type { + DRI2_SURFACE_TYPE_WINDOW, + DRI2_SURFACE_TYPE_PIXMAP, + DRI2_SURFACE_TYPE_PBUFFER +}; + +struct dri2_display { + struct native_display base; + Display *dpy; + boolean own_dpy; + + struct drm_api *api; + struct x11_screen *xscr; + int xscr_number; + + struct dri2_config *configs; + int num_configs; +}; + +struct dri2_surface { + struct native_surface base; + Drawable drawable; + enum dri2_surface_type type; + enum pipe_format color_format; + struct dri2_display *dri2dpy; + + struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS]; + boolean have_back, have_fake; + int width, height; + unsigned int sequence_number; +}; + +struct dri2_config { + struct native_config base; +}; + +static INLINE struct dri2_display * +dri2_display(const struct native_display *ndpy) +{ + return (struct dri2_display *) ndpy; +} + +static INLINE struct dri2_surface * +dri2_surface(const struct native_surface *nsurf) +{ + return (struct dri2_surface *) nsurf; +} + +static INLINE struct dri2_config * +dri2_config(const struct native_config *nconf) +{ + return (struct dri2_config *) nconf; +} + +static boolean +dri2_surface_flush_frontbuffer(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + /* pbuffer is private */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) + return TRUE; + + /* copy to real front buffer */ + if (dri2surf->have_fake) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); + + return TRUE; +} + +static boolean +dri2_surface_swap_buffers(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + /* pbuffer is private */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) + return TRUE; + + /* copy to front buffer */ + if (dri2surf->have_back) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferBackLeft, DRI2BufferFrontLeft); + + /* and update fake front buffer */ + if (dri2surf->have_fake) + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + + return TRUE; +} + +static boolean +dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS]; + struct pipe_texture templ; + struct x11_drawable_buffer *xbufs; + int num_ins, num_outs, att, i; + + if (attachment_mask) { + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = dri2surf->width; + templ.height0 = dri2surf->height; + templ.depth0 = 1; + templ.format = dri2surf->color_format; + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + if (textures) + memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS); + } + + /* create textures for pbuffer */ + if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) { + struct pipe_screen *screen = dri2dpy->base.screen; + + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct pipe_texture *ptex = dri2surf->pbuffer_textures[att]; + + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) + continue; + + if (!ptex) { + ptex = screen->texture_create(screen, &templ); + dri2surf->pbuffer_textures[att] = ptex; + } + + if (textures) + pipe_texture_reference(&textures[att], ptex); + } + + if (seq_num) + *seq_num = dri2surf->sequence_number; + if (width) + *width = dri2surf->width; + if (height) + *height = dri2surf->height; + + return TRUE; + } + + /* prepare the attachments */ + num_ins = 0; + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + if (native_attachment_mask_test(attachment_mask, att)) { + unsigned int dri2att; + + switch (att) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + dri2att = DRI2BufferFrontLeft; + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + dri2att = DRI2BufferBackLeft; + break; + case NATIVE_ATTACHMENT_FRONT_RIGHT: + dri2att = DRI2BufferFrontRight; + break; + case NATIVE_ATTACHMENT_BACK_RIGHT: + dri2att = DRI2BufferBackRight; + break; + default: + assert(0); + dri2att = 0; + break; + } + + dri2atts[num_ins] = dri2att; + num_ins++; + } + } + + dri2surf->have_back = FALSE; + dri2surf->have_fake = FALSE; + + /* remember old geometry */ + templ.width0 = dri2surf->width; + templ.height0 = dri2surf->height; + + xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable, + &dri2surf->width, &dri2surf->height, + dri2atts, FALSE, num_ins, &num_outs); + if (!xbufs) + return FALSE; + + if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) { + /* are there cases where the buffers change and the geometry doesn't? */ + dri2surf->sequence_number++; + + templ.width0 = dri2surf->width; + templ.height0 = dri2surf->height; + } + + for (i = 0; i < num_outs; i++) { + struct x11_drawable_buffer *xbuf = &xbufs[i]; + const char *desc; + enum native_attachment natt; + + switch (xbuf->attachment) { + case DRI2BufferFrontLeft: + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + desc = "DRI2 Front Buffer"; + break; + case DRI2BufferFakeFrontLeft: + natt = NATIVE_ATTACHMENT_FRONT_LEFT; + desc = "DRI2 Fake Front Buffer"; + dri2surf->have_fake = TRUE; + break; + case DRI2BufferBackLeft: + natt = NATIVE_ATTACHMENT_BACK_LEFT; + desc = "DRI2 Back Buffer"; + dri2surf->have_back = TRUE; + break; + default: + desc = NULL; + break; + } + + if (!desc || !native_attachment_mask_test(attachment_mask, natt) || + (textures && textures[natt])) { + if (!desc) + _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment); + else if (!native_attachment_mask_test(attachment_mask, natt)) + _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment); + else + _eglLog(_EGL_WARNING, "both real and fake front buffers are listed"); + continue; + } + + if (textures) { + struct pipe_texture *ptex = + dri2dpy->api->texture_from_shared_handle(dri2dpy->api, + dri2dpy->base.screen, &templ, + desc, xbuf->pitch, xbuf->name); + if (ptex) { + /* the caller owns the textures */ + textures[natt] = ptex; + } + } + } + + free(xbufs); + + if (seq_num) + *seq_num = dri2surf->sequence_number; + if (width) + *width = dri2surf->width; + if (height) + *height = dri2surf->height; + + return TRUE; +} + +static void +dri2_surface_wait(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + struct dri2_display *dri2dpy = dri2surf->dri2dpy; + + if (dri2surf->have_fake) { + x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable, + 0, 0, dri2surf->width, dri2surf->height, + DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + } +} + +static void +dri2_surface_destroy(struct native_surface *nsurf) +{ + struct dri2_surface *dri2surf = dri2_surface(nsurf); + int i; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct pipe_texture *ptex = dri2surf->pbuffer_textures[i]; + pipe_texture_reference(&ptex, NULL); + } + + if (dri2surf->drawable) + x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr, + dri2surf->drawable, FALSE); + free(dri2surf); +} + +static struct dri2_surface * +dri2_display_create_surface(struct native_display *ndpy, + enum dri2_surface_type type, + Drawable drawable, + const struct native_config *nconf) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + struct dri2_config *dri2conf = dri2_config(nconf); + struct dri2_surface *dri2surf; + + dri2surf = CALLOC_STRUCT(dri2_surface); + if (!dri2surf) + return NULL; + + if (drawable) + x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE); + + dri2surf->dri2dpy = dri2dpy; + dri2surf->type = type; + dri2surf->drawable = drawable; + dri2surf->color_format = dri2conf->base.color_format; + + dri2surf->base.destroy = dri2_surface_destroy; + dri2surf->base.swap_buffers = dri2_surface_swap_buffers; + dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer; + dri2surf->base.validate = dri2_surface_validate; + dri2surf->base.wait = dri2_surface_wait; + + return dri2surf; +} + +static struct native_surface * +dri2_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW, + (Drawable) win, nconf); + return (dri2surf) ? &dri2surf->base : NULL; +} + +static struct native_surface * +dri2_display_create_pixmap_surface(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP, + (Drawable) pix, nconf); + return (dri2surf) ? &dri2surf->base : NULL; +} + +static struct native_surface * +dri2_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct dri2_surface *dri2surf; + + dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER, + (Drawable) None, nconf); + if (dri2surf) { + dri2surf->width = width; + dri2surf->height = height; + } + return (dri2surf) ? &dri2surf->base : NULL; +} + +static int +choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32]) +{ + int count = 0; + + switch (mode->rgbBits) { + case 32: + formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; + formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + case 24: + formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM; + formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM; + formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM; + formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + case 16: + formats[count++] = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + break; + } + + return count; +} + +static int +choose_depth_stencil_format(const __GLcontextModes *mode, + enum pipe_format formats[32]) +{ + int count = 0; + + switch (mode->depthBits) { + case 32: + formats[count++] = PIPE_FORMAT_Z32_UNORM; + break; + case 24: + if (mode->stencilBits) { + formats[count++] = PIPE_FORMAT_S8Z24_UNORM; + formats[count++] = PIPE_FORMAT_Z24S8_UNORM; + } + else { + formats[count++] = PIPE_FORMAT_X8Z24_UNORM; + formats[count++] = PIPE_FORMAT_Z24X8_UNORM; + } + break; + case 16: + formats[count++] = PIPE_FORMAT_Z16_UNORM; + break; + default: + break; + } + + return count; +} + +static boolean +is_format_supported(struct pipe_screen *screen, + enum pipe_format fmt, boolean is_color) +{ + return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, + (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET : + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); +} + +static boolean +dri2_display_convert_config(struct native_display *ndpy, + const __GLcontextModes *mode, + struct native_config *nconf) +{ + enum pipe_format formats[32]; + int num_formats, i; + + if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode) + return FALSE; + + /* skip single-buffered configs */ + if (!mode->doubleBufferMode) + return FALSE; + + nconf->mode = *mode; + nconf->mode.renderType = GLX_RGBA_BIT; + nconf->mode.rgbMode = TRUE; + /* pbuffer is allocated locally and is always supported */ + nconf->mode.drawableType |= GLX_PBUFFER_BIT; + /* the swap method is always copy */ + nconf->mode.swapMethod = GLX_SWAP_COPY_OML; + + /* fix up */ + nconf->mode.rgbBits = + nconf->mode.redBits + nconf->mode.greenBits + + nconf->mode.blueBits + nconf->mode.alphaBits; + if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) { + nconf->mode.visualID = 0; + nconf->mode.visualType = GLX_NONE; + } + if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) { + nconf->mode.bindToTextureRgb = FALSE; + nconf->mode.bindToTextureRgba = FALSE; + } + + nconf->color_format = PIPE_FORMAT_NONE; + nconf->depth_format = PIPE_FORMAT_NONE; + nconf->stencil_format = PIPE_FORMAT_NONE; + + /* choose color format */ + num_formats = choose_color_format(mode, formats); + for (i = 0; i < num_formats; i++) { + if (is_format_supported(ndpy->screen, formats[i], TRUE)) { + nconf->color_format = formats[i]; + break; + } + } + if (nconf->color_format == PIPE_FORMAT_NONE) + return FALSE; + + /* choose depth/stencil format */ + num_formats = choose_depth_stencil_format(mode, formats); + for (i = 0; i < num_formats; i++) { + if (is_format_supported(ndpy->screen, formats[i], FALSE)) { + nconf->depth_format = formats[i]; + nconf->stencil_format = formats[i]; + break; + } + } + if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) || + (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE)) + return FALSE; + + return TRUE; +} + +static const struct native_config ** +dri2_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + const struct native_config **configs; + int i; + + /* first time */ + if (!dri2dpy->configs) { + const __GLcontextModes *modes; + int num_modes, count; + + modes = x11_screen_get_glx_configs(dri2dpy->xscr); + if (!modes) + return NULL; + num_modes = x11_context_modes_count(modes); + + dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs)); + if (!dri2dpy->configs) + return NULL; + + count = 0; + for (i = 0; i < num_modes; i++) { + struct native_config *nconf = &dri2dpy->configs[count].base; + if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) + count++; + modes = modes->next; + } + + dri2dpy->num_configs = count; + } + + configs = malloc(dri2dpy->num_configs * sizeof(*configs)); + if (configs) { + for (i = 0; i < dri2dpy->num_configs; i++) + configs[i] = (const struct native_config *) &dri2dpy->configs[i]; + if (num_configs) + *num_configs = dri2dpy->num_configs; + } + + return configs; +} + +static boolean +dri2_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + uint depth, nconf_depth; + + depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix); + nconf_depth = util_format_get_blocksizebits(nconf->color_format); + + /* simple depth match for now */ + return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth)); +} + +static void +dri2_display_destroy(struct native_display *ndpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + + if (dri2dpy->configs) + free(dri2dpy->configs); + + if (dri2dpy->base.screen) + dri2dpy->base.screen->destroy(dri2dpy->base.screen); + + if (dri2dpy->xscr) + x11_screen_destroy(dri2dpy->xscr); + if (dri2dpy->own_dpy) + XCloseDisplay(dri2dpy->dpy); + if (dri2dpy->api && dri2dpy->api->destroy) + dri2dpy->api->destroy(dri2dpy->api); + free(dri2dpy); +} + +/** + * Initialize DRI2 and pipe screen. + */ +static boolean +dri2_display_init_screen(struct native_display *ndpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + const char *driver = dri2dpy->api->name; + struct drm_create_screen_arg arg; + int fd; + + if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || + !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) { + _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported"); + return FALSE; + } + + fd = x11_screen_enable_dri2(dri2dpy->xscr, driver); + if (fd < 0) + return FALSE; + + memset(&arg, 0, sizeof(arg)); + arg.mode = DRM_CREATE_NORMAL; + dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg); + if (!dri2dpy->base.screen) { + _eglLog(_EGL_WARNING, "failed to create DRM screen"); + return FALSE; + } + + return TRUE; +} + +struct native_display * +x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api) +{ + struct dri2_display *dri2dpy; + + dri2dpy = CALLOC_STRUCT(dri2_display); + if (!dri2dpy) + return NULL; + + dri2dpy->api = api; + if (!dri2dpy->api) { + _eglLog(_EGL_WARNING, "failed to create DRM API"); + free(dri2dpy); + return NULL; + } + + dri2dpy->dpy = dpy; + if (!dri2dpy->dpy) { + dri2dpy->dpy = XOpenDisplay(NULL); + if (!dri2dpy->dpy) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + dri2dpy->own_dpy = TRUE; + } + + dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy); + dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number); + if (!dri2dpy->xscr) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + + if (!dri2_display_init_screen(&dri2dpy->base)) { + dri2_display_destroy(&dri2dpy->base); + return NULL; + } + + dri2dpy->base.destroy = dri2_display_destroy; + dri2dpy->base.get_configs = dri2_display_get_configs; + dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; + dri2dpy->base.create_window_surface = dri2_display_create_window_surface; + dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; + dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface; + + return &dri2dpy->base; +} diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c new file mode 100644 index 0000000000..8eb542bd82 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -0,0 +1,150 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <stdio.h> +#include <string.h> +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "state_tracker/drm_api.h" +#include "egllog.h" + +#include "native_x11.h" +#include "x11_screen.h" + +#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */ + +static struct drm_api *api; + +static void +x11_probe_destroy(struct native_probe *nprobe) +{ + if (nprobe->data) + free(nprobe->data); + free(nprobe); +} + +struct native_probe * +native_create_probe(EGLNativeDisplayType dpy) +{ + struct native_probe *nprobe; + struct x11_screen *xscr; + int scr; + const char *driver_name = NULL; + Display *xdpy; + + nprobe = CALLOC_STRUCT(native_probe); + if (!nprobe) + return NULL; + + xdpy = dpy; + if (!xdpy) { + xdpy = XOpenDisplay(NULL); + if (!xdpy) { + free(nprobe); + return NULL; + } + } + + scr = DefaultScreen(xdpy); + xscr = x11_screen_create(xdpy, scr); + if (xscr) { + if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) { + driver_name = x11_screen_probe_dri2(xscr); + if (driver_name) + nprobe->data = strdup(driver_name); + } + + x11_screen_destroy(xscr); + } + + if (xdpy != dpy) + XCloseDisplay(xdpy); + + nprobe->magic = X11_PROBE_MAGIC; + nprobe->display = dpy; + + nprobe->destroy = x11_probe_destroy; + + return nprobe; +} + +enum native_probe_result +native_get_probe_result(struct native_probe *nprobe) +{ + if (!nprobe || nprobe->magic != X11_PROBE_MAGIC) + return NATIVE_PROBE_UNKNOWN; + + if (!api) + api = drm_api_create(); + + /* this is a software driver */ + if (!api) + return NATIVE_PROBE_SUPPORTED; + + /* the display does not support DRI2 or the driver mismatches */ + if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0) + return NATIVE_PROBE_FALLBACK; + + return NATIVE_PROBE_EXACT; +} + +const char * +native_get_name(void) +{ + static char x11_name[32]; + + if (!api) + api = drm_api_create(); + + if (api) + snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name); + else + snprintf(x11_name, sizeof(x11_name), "X11"); + + return x11_name; +} + +struct native_display * +native_create_display(EGLNativeDisplayType dpy) +{ + struct native_display *ndpy = NULL; + boolean force_sw; + + if (!api) + api = drm_api_create(); + + force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); + if (api && !force_sw) { + ndpy = x11_create_dri2_display(dpy, api); + } + + if (!ndpy) { + EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; + + _eglLog(level, "use software fallback"); + ndpy = x11_create_ximage_display(dpy, TRUE); + } + + return ndpy; +} diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h new file mode 100644 index 0000000000..622ddac5df --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -0,0 +1,37 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _NATIVE_X11_H_ +#define _NATIVE_X11_H_ + +#include "state_tracker/drm_api.h" +#include "common/native.h" + +struct native_display * +x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm); + +struct native_display * +x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api); + +#endif /* _NATIVE_X11_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c new file mode 100644 index 0000000000..92a62f230e --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -0,0 +1,684 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <assert.h> +#include <sys/ipc.h> +#include <sys/types.h> +#include <sys/shm.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/extensions/XShm.h> +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "pipe/p_compiler.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" +#include "softpipe/sp_winsys.h" +#include "egllog.h" + +#include "sw_winsys.h" +#include "native_x11.h" +#include "x11_screen.h" + +enum ximage_surface_type { + XIMAGE_SURFACE_TYPE_WINDOW, + XIMAGE_SURFACE_TYPE_PIXMAP, + XIMAGE_SURFACE_TYPE_PBUFFER +}; + +struct ximage_display { + struct native_display base; + Display *dpy; + boolean own_dpy; + + struct x11_screen *xscr; + int xscr_number; + + boolean use_xshm; + + struct pipe_winsys *winsys; + struct ximage_config *configs; + int num_configs; +}; + +struct ximage_buffer { + XImage *ximage; + + struct pipe_texture *texture; + XShmSegmentInfo *shm_info; + boolean xshm_attached; +}; + +struct ximage_surface { + struct native_surface base; + Drawable drawable; + enum ximage_surface_type type; + enum pipe_format color_format; + XVisualInfo visual; + struct ximage_display *xdpy; + + int width, height; + GC gc; + + struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; + unsigned int sequence_number; +}; + +struct ximage_config { + struct native_config base; + const XVisualInfo *visual; +}; + +static INLINE struct ximage_display * +ximage_display(const struct native_display *ndpy) +{ + return (struct ximage_display *) ndpy; +} + +static INLINE struct ximage_surface * +ximage_surface(const struct native_surface *nsurf) +{ + return (struct ximage_surface *) nsurf; +} + +static INLINE struct ximage_config * +ximage_config(const struct native_config *nconf) +{ + return (struct ximage_config *) nconf; +} + +static void +ximage_surface_free_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xbuf = &xsurf->buffers[which]; + + pipe_texture_reference(&xbuf->texture, NULL); + + if (xbuf->shm_info) { + if (xbuf->xshm_attached) + XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info); + if (xbuf->shm_info->shmaddr != (void *) -1) + shmdt(xbuf->shm_info->shmaddr); + if (xbuf->shm_info->shmid != -1) + shmctl(xbuf->shm_info->shmid, IPC_RMID, 0); + + xbuf->shm_info->shmaddr = (void *) -1; + xbuf->shm_info->shmid = -1; + } +} + +static boolean +ximage_surface_alloc_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xbuf = &xsurf->buffers[which]; + struct pipe_screen *screen = xsurf->xdpy->base.screen; + struct pipe_texture templ; + + /* free old data */ + if (xbuf->texture) + ximage_surface_free_buffer(&xsurf->base, which); + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = xsurf->color_format; + templ.width0 = xsurf->width; + templ.height0 = xsurf->height; + templ.depth0 = 1; + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + + if (xbuf->shm_info) { + struct pipe_buffer *pbuf; + unsigned stride, size; + void *addr = NULL; + + stride = util_format_get_stride(xsurf->color_format, xsurf->width); + /* alignment should depend on visual? */ + stride = align(stride, 4); + size = stride * xsurf->height; + + /* create and attach shm object */ + xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755); + if (xbuf->shm_info->shmid != -1) { + xbuf->shm_info->shmaddr = + shmat(xbuf->shm_info->shmid, NULL, 0); + if (xbuf->shm_info->shmaddr != (void *) -1) { + if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) { + addr = xbuf->shm_info->shmaddr; + xbuf->xshm_attached = TRUE; + } + } + } + + if (addr) { + pbuf = screen->user_buffer_create(screen, addr, size); + if (pbuf) { + xbuf->texture = + screen->texture_blanket(screen, &templ, &stride, pbuf); + pipe_buffer_reference(&pbuf, NULL); + } + } + } + else { + xbuf->texture = screen->texture_create(screen, &templ); + } + + /* clean up the buffer if allocation failed */ + if (!xbuf->texture) + ximage_surface_free_buffer(&xsurf->base, which); + + return (xbuf->texture != NULL); +} + +static boolean +ximage_surface_draw_buffer(struct native_surface *nsurf, + enum native_attachment which) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xbuf = &xsurf->buffers[which]; + struct pipe_screen *screen = xsurf->xdpy->base.screen; + struct pipe_transfer *transfer; + + if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) + return TRUE; + + assert(xsurf->drawable && xbuf->ximage && xbuf->texture); + + transfer = screen->get_tex_transfer(screen, xbuf->texture, + 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height); + if (!transfer) + return FALSE; + + xbuf->ximage->bytes_per_line = transfer->stride; + xbuf->ximage->data = screen->transfer_map(screen, transfer); + if (!xbuf->ximage->data) { + screen->tex_transfer_destroy(transfer); + return FALSE; + } + + + if (xbuf->shm_info) + XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc, + xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False); + else + XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc, + xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height); + + xbuf->ximage->data = NULL; + screen->transfer_unmap(screen, transfer); + + /* + * softpipe allows the pipe transfer to be re-used, but we don't want to + * rely on that behavior. + */ + screen->tex_transfer_destroy(transfer); + + XSync(xsurf->xdpy->dpy, FALSE); + + return TRUE; +} + +static boolean +ximage_surface_flush_frontbuffer(struct native_surface *nsurf) +{ + return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); +} + +static boolean +ximage_surface_swap_buffers(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + struct ximage_buffer *xfront, *xback, xtmp; + + xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT]; + xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT]; + + /* draw the back buffer directly if there is no front buffer */ + if (!xfront->texture) + return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT); + + /* swap the buffers */ + xtmp = *xfront; + *xfront = *xback; + *xback = xtmp; + + /* the front/back textures are swapped */ + xsurf->sequence_number++; + + return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); +} + +static void +ximage_surface_update_geometry(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + Status ok; + Window root; + int x, y; + unsigned int w, h, border, depth; + + /* pbuffer has fixed geometry */ + if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER) + return; + + ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable, + &root, &x, &y, &w, &h, &border, &depth); + if (ok) { + xsurf->width = w; + xsurf->height = h; + } +} + +static boolean +ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, + unsigned int *seq_num, struct pipe_texture **textures, + int *width, int *height) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + boolean new_buffers = FALSE; + int att; + + ximage_surface_update_geometry(&xsurf->base); + + for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { + struct ximage_buffer *xbuf = &xsurf->buffers[att]; + + /* delay the allocation */ + if (!native_attachment_mask_test(attachment_mask, att)) + continue; + + /* reallocate the texture */ + if (!xbuf->texture || + xsurf->width != xbuf->texture->width0 || + xsurf->height != xbuf->texture->height0) { + new_buffers = TRUE; + if (ximage_surface_alloc_buffer(&xsurf->base, att)) { + /* update ximage */ + if (xbuf->ximage) { + xbuf->ximage->width = xsurf->width; + xbuf->ximage->height = xsurf->height; + } + } + } + + if (textures) { + textures[att] = NULL; + pipe_texture_reference(&textures[att], xbuf->texture); + } + } + + /* increase the sequence number so that caller knows */ + if (new_buffers) + xsurf->sequence_number++; + + if (seq_num) + *seq_num = xsurf->sequence_number; + if (width) + *width = xsurf->width; + if (height) + *height = xsurf->height; + + return TRUE; +} + +static void +ximage_surface_wait(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + XSync(xsurf->xdpy->dpy, FALSE); + /* TODO XGetImage and update the front texture */ +} + +static void +ximage_surface_destroy(struct native_surface *nsurf) +{ + struct ximage_surface *xsurf = ximage_surface(nsurf); + int i; + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct ximage_buffer *xbuf = &xsurf->buffers[i]; + ximage_surface_free_buffer(&xsurf->base, i); + /* xbuf->shm_info is owned by xbuf->ximage? */ + if (xbuf->ximage) { + XDestroyImage(xbuf->ximage); + xbuf->ximage = NULL; + } + } + + if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) + XFreeGC(xsurf->xdpy->dpy, xsurf->gc); + free(xsurf); +} + +static struct ximage_surface * +ximage_display_create_surface(struct native_display *ndpy, + enum ximage_surface_type type, + Drawable drawable, + const struct native_config *nconf) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + struct ximage_config *xconf = ximage_config(nconf); + struct ximage_surface *xsurf; + int i; + + xsurf = CALLOC_STRUCT(ximage_surface); + if (!xsurf) + return NULL; + + xsurf->xdpy = xdpy; + xsurf->type = type; + xsurf->color_format = xconf->base.color_format; + xsurf->drawable = drawable; + + if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) { + xsurf->drawable = drawable; + xsurf->visual = *xconf->visual; + + xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL); + if (!xsurf->gc) { + free(xsurf); + return NULL; + } + + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { + struct ximage_buffer *xbuf = &xsurf->buffers[i]; + + if (xdpy->use_xshm) { + xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info)); + if (xbuf->shm_info) { + /* initialize shm info */ + xbuf->shm_info->shmid = -1; + xbuf->shm_info->shmaddr = (void *) -1; + xbuf->shm_info->readOnly = TRUE; + + xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy, + xsurf->visual.visual, + xsurf->visual.depth, + ZPixmap, NULL, + xbuf->shm_info, + 0, 0); + } + } + else { + xbuf->ximage = XCreateImage(xsurf->xdpy->dpy, + xsurf->visual.visual, + xsurf->visual.depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 8, /* bitmap_pad */ + 0); /* bytes_per_line */ + } + + if (!xbuf->ximage) { + XFreeGC(xdpy->dpy, xsurf->gc); + free(xsurf); + return NULL; + } + } + } + + xsurf->base.destroy = ximage_surface_destroy; + xsurf->base.swap_buffers = ximage_surface_swap_buffers; + xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer; + xsurf->base.validate = ximage_surface_validate; + xsurf->base.wait = ximage_surface_wait; + + return xsurf; +} + +static struct native_surface * +ximage_display_create_window_surface(struct native_display *ndpy, + EGLNativeWindowType win, + const struct native_config *nconf) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW, + (Drawable) win, nconf); + return (xsurf) ? &xsurf->base : NULL; +} + +static struct native_surface * +ximage_display_create_pixmap_surface(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP, + (Drawable) pix, nconf); + return (xsurf) ? &xsurf->base : NULL; +} + +static struct native_surface * +ximage_display_create_pbuffer_surface(struct native_display *ndpy, + const struct native_config *nconf, + uint width, uint height) +{ + struct ximage_surface *xsurf; + + xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER, + (Drawable) None, nconf); + if (xsurf) { + xsurf->width = width; + xsurf->height = height; + } + return (xsurf) ? &xsurf->base : NULL; +} + +static enum pipe_format +choose_format(const XVisualInfo *vinfo) +{ + enum pipe_format fmt; + /* TODO elaborate the formats */ + switch (vinfo->depth) { + case 32: + fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 24: + fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + case 16: + fmt = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + fmt = PIPE_FORMAT_NONE; + break; + } + + return fmt; +} + +static const struct native_config ** +ximage_display_get_configs(struct native_display *ndpy, int *num_configs) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + const struct native_config **configs; + int i; + + /* first time */ + if (!xdpy->configs) { + const XVisualInfo *visuals; + int num_visuals, count, j; + + visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals); + if (!visuals) + return NULL; + + /* + * Create two configs for each visual. + * One with depth/stencil buffer; one without + */ + xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs)); + if (!xdpy->configs) + return NULL; + + count = 0; + for (i = 0; i < num_visuals; i++) { + for (j = 0; j < 2; j++) { + struct ximage_config *xconf = &xdpy->configs[count]; + __GLcontextModes *mode = &xconf->base.mode; + + xconf->visual = &visuals[i]; + xconf->base.color_format = choose_format(xconf->visual); + if (xconf->base.color_format == PIPE_FORMAT_NONE) + continue; + + x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode); + /* support double buffer mode */ + mode->doubleBufferMode = TRUE; + + xconf->base.depth_format = PIPE_FORMAT_NONE; + xconf->base.stencil_format = PIPE_FORMAT_NONE; + /* create the second config with depth/stencil buffer */ + if (j == 1) { + xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM; + xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM; + mode->depthBits = 24; + mode->stencilBits = 8; + mode->haveDepthBuffer = TRUE; + mode->haveStencilBuffer = TRUE; + } + + mode->maxPbufferWidth = 4096; + mode->maxPbufferHeight = 4096; + mode->maxPbufferPixels = 4096 * 4096; + mode->drawableType = + GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + mode->swapMethod = GLX_SWAP_EXCHANGE_OML; + + if (mode->alphaBits) + mode->bindToTextureRgba = TRUE; + else + mode->bindToTextureRgb = TRUE; + + count++; + } + } + + xdpy->num_configs = count; + } + + configs = malloc(xdpy->num_configs * sizeof(*configs)); + if (configs) { + for (i = 0; i < xdpy->num_configs; i++) + configs[i] = (const struct native_config *) &xdpy->configs[i]; + if (num_configs) + *num_configs = xdpy->num_configs; + } + return configs; +} + +static boolean +ximage_display_is_pixmap_supported(struct native_display *ndpy, + EGLNativePixmapType pix, + const struct native_config *nconf) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + enum pipe_format fmt; + uint depth; + + depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix); + switch (depth) { + case 32: + fmt = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case 24: + fmt = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + case 16: + fmt = PIPE_FORMAT_R5G6B5_UNORM; + break; + default: + fmt = PIPE_FORMAT_NONE; + break; + } + + return (fmt == nconf->color_format); +} + +static void +ximage_display_destroy(struct native_display *ndpy) +{ + struct ximage_display *xdpy = ximage_display(ndpy); + + if (xdpy->configs) + free(xdpy->configs); + + xdpy->base.screen->destroy(xdpy->base.screen); + free(xdpy->winsys); + + x11_screen_destroy(xdpy->xscr); + if (xdpy->own_dpy) + XCloseDisplay(xdpy->dpy); + free(xdpy); +} + +struct native_display * +x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm) +{ + struct ximage_display *xdpy; + + xdpy = CALLOC_STRUCT(ximage_display); + if (!xdpy) + return NULL; + + xdpy->dpy = dpy; + if (!xdpy->dpy) { + xdpy->dpy = XOpenDisplay(NULL); + if (!xdpy->dpy) { + free(xdpy); + return NULL; + } + xdpy->own_dpy = TRUE; + } + + xdpy->xscr_number = DefaultScreen(xdpy->dpy); + xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); + if (!xdpy->xscr) { + free(xdpy); + return NULL; + } + + xdpy->use_xshm = + (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM)); + + xdpy->winsys = create_sw_winsys(); + xdpy->base.screen = softpipe_create_screen(xdpy->winsys); + + xdpy->base.destroy = ximage_display_destroy; + + xdpy->base.get_configs = ximage_display_get_configs; + xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported; + xdpy->base.create_window_surface = ximage_display_create_window_surface; + xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface; + xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface; + + return &xdpy->base; +} diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c index 6ee3ede38c..33328aadf2 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/state_trackers/egl/x11/sw_winsys.c @@ -35,9 +35,9 @@ */ -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h index f96c5a14b0..f96c5a14b0 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.h +++ b/src/gallium/state_trackers/egl/x11/sw_winsys.h diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c new file mode 100644 index 0000000000..d72bfc99d3 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -0,0 +1,453 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <X11/Xlibint.h> +#include <X11/extensions/XShm.h> +#include "util/u_memory.h" +#include "util/u_math.h" +#include "util/u_format.h" +#include "xf86drm.h" +#include "egllog.h" + +#include "x11_screen.h" +#include "dri2.h" +#include "glxinit.h" + +struct x11_screen { + Display *dpy; + int number; + + /* + * This is used to fetch GLX visuals/fbconfigs. It steals code from GLX. + * It might be better to rewrite the part in Xlib or XCB. + */ + __GLXdisplayPrivate *glx_dpy; + + int dri_major, dri_minor; + char *dri_driver; + char *dri_device; + int dri_fd; + + XVisualInfo *visuals; + int num_visuals; + + /* cached values for x11_drawable_get_depth */ + Drawable last_drawable; + unsigned int last_depth; +}; + + +/** + * Create a X11 screen. + */ +struct x11_screen * +x11_screen_create(Display *dpy, int screen) +{ + struct x11_screen *xscr; + + if (screen >= ScreenCount(dpy)) + return NULL; + + xscr = CALLOC_STRUCT(x11_screen); + if (xscr) { + xscr->dpy = dpy; + xscr->number = screen; + + xscr->dri_major = -1; + xscr->dri_fd = -1; + } + return xscr; +} + +/** + * Destroy a X11 screen. + */ +void +x11_screen_destroy(struct x11_screen *xscr) +{ + if (xscr->dri_fd >= 0) + close(xscr->dri_fd); + if (xscr->dri_driver) + Xfree(xscr->dri_driver); + if (xscr->dri_device) + Xfree(xscr->dri_device); + + /* xscr->glx_dpy will be destroyed with the X display */ + + if (xscr->visuals) + XFree(xscr->visuals); + free(xscr); +} + +static boolean +x11_screen_init_dri2(struct x11_screen *xscr) +{ + if (xscr->dri_major < 0) { + int eventBase, errorBase; + + if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) || + !DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor)) + xscr->dri_major = -1; + } + return (xscr->dri_major >= 0); +} + +static boolean +x11_screen_init_glx(struct x11_screen *xscr) +{ + if (!xscr->glx_dpy) + xscr->glx_dpy = __glXInitialize(xscr->dpy); + return (xscr->glx_dpy != NULL); +} + +/** + * Return true if the screen supports the extension. + */ +boolean +x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext) +{ + boolean supported = FALSE; + + switch (ext) { + case X11_SCREEN_EXTENSION_XSHM: + supported = XShmQueryExtension(xscr->dpy); + break; + case X11_SCREEN_EXTENSION_GLX: + supported = x11_screen_init_glx(xscr); + break; + case X11_SCREEN_EXTENSION_DRI2: + supported = x11_screen_init_dri2(xscr); + break; + default: + break; + } + + return supported; +} + +/** + * Return the X visuals. + */ +const XVisualInfo * +x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals) +{ + if (!xscr->visuals) { + XVisualInfo vinfo_template; + vinfo_template.screen = xscr->number; + xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask, + &vinfo_template, &xscr->num_visuals); + } + + if (num_visuals) + *num_visuals = xscr->num_visuals; + return xscr->visuals; +} + +void +x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, + __GLcontextModes *mode) +{ + int r, g, b, a; + int visual_type; + + r = util_bitcount(visual->red_mask); + g = util_bitcount(visual->green_mask); + b = util_bitcount(visual->blue_mask); + a = visual->depth - (r + g + b); +#if defined(__cplusplus) || defined(c_plusplus) + visual_type = visual->c_class; +#else + visual_type = visual->class; +#endif + + /* convert to GLX visual type */ + switch (visual_type) { + case TrueColor: + visual_type = GLX_TRUE_COLOR; + break; + case DirectColor: + visual_type = GLX_DIRECT_COLOR; + break; + case PseudoColor: + visual_type = GLX_PSEUDO_COLOR; + break; + case StaticColor: + visual_type = GLX_STATIC_COLOR; + break; + case GrayScale: + visual_type = GLX_GRAY_SCALE; + break; + case StaticGray: + visual_type = GLX_STATIC_GRAY; + break; + default: + visual_type = GLX_NONE; + break; + } + + mode->rgbBits = r + g + b + a; + mode->redBits = r; + mode->greenBits = g; + mode->blueBits = b; + mode->alphaBits = a; + mode->visualID = visual->visualid; + mode->visualType = visual_type; + + /* sane defaults */ + mode->renderType = GLX_RGBA_BIT; + mode->rgbMode = TRUE; + mode->visualRating = GLX_SLOW_CONFIG; + mode->xRenderable = TRUE; +} + +/** + * Return the GLX fbconfigs. + */ +const __GLcontextModes * +x11_screen_get_glx_configs(struct x11_screen *xscr) +{ + return (x11_screen_init_glx(xscr)) + ? xscr->glx_dpy->screenConfigs[xscr->number].configs + : NULL; +} + +/** + * Return the GLX visuals. + */ +const __GLcontextModes * +x11_screen_get_glx_visuals(struct x11_screen *xscr) +{ + return (x11_screen_init_glx(xscr)) + ? xscr->glx_dpy->screenConfigs[xscr->number].visuals + : NULL; +} + +static boolean +x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver) +{ + return (strcmp(xscr->dri_driver, driver) == 0); +} + +/** + * Probe the screen for the DRI2 driver name. + */ +const char * +x11_screen_probe_dri2(struct x11_screen *xscr) +{ + /* get the driver name and the device name */ + if (!xscr->dri_driver) { + if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number), + &xscr->dri_driver, &xscr->dri_device)) + xscr->dri_driver = xscr->dri_device = NULL; + } + + return xscr->dri_driver; +} + +/** + * Enable DRI2 and returns the file descriptor of the DRM device. The file + * descriptor will be closed automatically when the screen is destoryed. + */ +int +x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver) +{ + if (xscr->dri_fd < 0) { + int fd; + drm_magic_t magic; + + /* get the driver name and the device name first */ + if (!x11_screen_probe_dri2(xscr)) + return -1; + + if (!x11_screen_is_driver_equal(xscr, driver)) { + _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s", + xscr->dri_driver, driver); + return -1; + } + + fd = open(xscr->dri_device, O_RDWR); + if (fd < 0) { + _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device); + return -1; + } + + memset(&magic, 0, sizeof(magic)); + if (drmGetMagic(fd, &magic)) { + _eglLog(_EGL_WARNING, "failed to get magic"); + close(fd); + return -1; + } + + if (!DRI2Authenticate(xscr->dpy, + RootWindow(xscr->dpy, xscr->number), magic)) { + _eglLog(_EGL_WARNING, "failed to authenticate magic"); + close(fd); + return -1; + } + + xscr->dri_fd = fd; + } + + return xscr->dri_fd; +} + +/** + * Create/Destroy the DRI drawable. + */ +void +x11_drawable_enable_dri2(struct x11_screen *xscr, + Drawable drawable, boolean on) +{ + if (on) + DRI2CreateDrawable(xscr->dpy, drawable); + else + DRI2DestroyDrawable(xscr->dpy, drawable); +} + +/** + * Copy between buffers of the DRI2 drawable. + */ +void +x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, + int x, int y, int width, int height, + int src_buf, int dst_buf) +{ + XRectangle rect; + XserverRegion region; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + region = XFixesCreateRegion(xscr->dpy, &rect, 1); + DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf); + XFixesDestroyRegion(xscr->dpy, region); +} + +/** + * Get the buffers of the DRI2 drawable. The returned array should be freed. + */ +struct x11_drawable_buffer * +x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, + int *width, int *height, unsigned int *attachments, + boolean with_format, int num_ins, int *num_outs) +{ + DRI2Buffer *dri2bufs; + + if (with_format) + dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height, + attachments, num_ins, num_outs); + else + dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height, + attachments, num_ins, num_outs); + + return (struct x11_drawable_buffer *) dri2bufs; +} + +/** + * Return the depth of a drawable. + * + * Unlike other drawable functions, the drawable needs not be a DRI2 drawable. + */ +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable) +{ + unsigned int depth; + + if (drawable != xscr->last_drawable) { + Window root; + int x, y; + unsigned int w, h, border; + Status ok; + + ok = XGetGeometry(xscr->dpy, drawable, &root, + &x, &y, &w, &h, &border, &depth); + if (!ok) + depth = 0; + + xscr->last_drawable = drawable; + xscr->last_depth = depth; + } + else { + depth = xscr->last_depth; + } + + return depth; +} + +/** + * Create a mode list of the given size. + */ +__GLcontextModes * +x11_context_modes_create(unsigned count) +{ + const size_t size = sizeof(__GLcontextModes); + __GLcontextModes *base = NULL; + __GLcontextModes **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + x11_context_modes_destroy(base); + base = NULL; + break; + } + next = &((*next)->next); + } + + return base; +} + +/** + * Destroy a mode list. + */ +void +x11_context_modes_destroy(__GLcontextModes *modes) +{ + while (modes != NULL) { + __GLcontextModes *next = modes->next; + free(modes); + modes = next; + } +} + +/** + * Return the number of the modes in the mode list. + */ +unsigned +x11_context_modes_count(const __GLcontextModes *modes) +{ + const __GLcontextModes *mode; + int count = 0; + for (mode = modes; mode; mode = mode->next) + count++; + return count; +} diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h new file mode 100644 index 0000000000..5432858ac3 --- /dev/null +++ b/src/gallium/state_trackers/egl/x11/x11_screen.h @@ -0,0 +1,105 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> + * + * 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 + * BRIAN PAUL 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 _X11_SCREEN_H_ +#define _X11_SCREEN_H_ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/extensions/dri2tokens.h> +#include "pipe/p_compiler.h" +#include "common/native.h" + +enum x11_screen_extension { + X11_SCREEN_EXTENSION_XSHM, + X11_SCREEN_EXTENSION_GLX, + X11_SCREEN_EXTENSION_DRI2, +}; + +/* the same as DRI2Buffer */ +struct x11_drawable_buffer { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; +}; + +struct x11_screen; + +struct x11_screen * +x11_screen_create(Display *dpy, int screen); + +void +x11_screen_destroy(struct x11_screen *xscr); + +boolean +x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext); + +const XVisualInfo * +x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals); + +void +x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual, + __GLcontextModes *mode); + +const __GLcontextModes * +x11_screen_get_glx_configs(struct x11_screen *xscr); + +const __GLcontextModes * +x11_screen_get_glx_visuals(struct x11_screen *xscr); + +const char * +x11_screen_probe_dri2(struct x11_screen *xscr); + +int +x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver); + +__GLcontextModes * +x11_context_modes_create(unsigned count); + +void +x11_context_modes_destroy(__GLcontextModes *modes); + +unsigned +x11_context_modes_count(const __GLcontextModes *modes); + +void +x11_drawable_enable_dri2(struct x11_screen *xscr, + Drawable drawable, boolean on); + +void +x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable, + int x, int y, int width, int height, + int src_buf, int dst_buf); + +struct x11_drawable_buffer * +x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable, + int *width, int *height, unsigned int *attachments, + boolean with_format, int num_ins, int *num_outs); + +uint +x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable); + +#endif /* _X11_SCREEN_H_ */ diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile new file mode 100644 index 0000000000..b036551271 --- /dev/null +++ b/src/gallium/state_trackers/es/Makefile @@ -0,0 +1,84 @@ +# src/gallium/state_trackers/es/Makefile + +# Build the ES 1/2 state tracker libraries +# This consists of core Mesa ES, plus GL/gallium state tracker. + +TOP = ../../../.. +include $(TOP)/configs/current + +GLES_1_VERSION_MAJOR = 1 +GLES_1_VERSION_MINOR = 1 +GLES_1_VERSION_PATCH = 0 + +GLES_2_VERSION_MAJOR = 2 +GLES_2_VERSION_MINOR = 0 +GLES_2_VERSION_PATCH = 0 + + +# Maybe move these into configs/default: +GLES_1_LIB = GLESv1_CM +GLES_1_LIB_NAME = lib$(GLES_1_LIB).so +GLES_2_LIB = GLESv2 +GLES_2_LIB_NAME = lib$(GLES_2_LIB).so + + +ES1_OBJECTS = st_es1.o +ES2_OBJECTS = st_es2.o + + +ES1_LIBS = \ + $(TOP)/src/mesa/es/libes1gallium.a \ + $(TOP)/src/mesa/es/libes1api.a + +ES2_LIBS = \ + $(TOP)/src/mesa/es/libes2gallium.a \ + $(TOP)/src/mesa/es/libes2api.a + +SYS_LIBS = -lm -pthread + + +INCLUDE_DIRS = \ + -I$(TOP)/src/gallium/include + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ + + +# Default: make both GL ES 1.1 and GL ES 2.0 libraries +default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME) + +# Make the shared libs +$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) + $(MKLIB) -o $(GLES_1_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major $(GLES_1_VERSION_MAJOR) \ + -minor $(GLES_1_VERSION_MINOR) \ + -patch $(GLES_1_VERSION_PATCH) \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + $(ES1_OBJECTS) \ + -Wl,--whole-archive $(ES1_LIBS) -Wl,--no-whole-archive \ + $(GALLIUM_AUXILIARIES) $(SYS_LIBS) + +$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES) + $(MKLIB) -o $(GLES_2_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major $(GLES_2_VERSION_MAJOR) \ + -minor $(GLES_2_VERSION_MINOR) \ + -patch $(GLES_2_VERSION_PATCH) \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + $(ES2_OBJECTS) \ + -Wl,--whole-archive $(ES2_LIBS) -Wl,--no-whole-archive \ + $(GALLIUM_AUXILIARIES) $(SYS_LIBS) + +install: default + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES + $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES2 + $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES2 + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + +clean: + -rm -f *.o *~ + -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)* + +depend: diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c new file mode 100644 index 0000000000..25bc53b21e --- /dev/null +++ b/src/gallium/state_trackers/es/st_es1.c @@ -0,0 +1,3 @@ +#include "pipe/p_compiler.h" + +PUBLIC const int st_api_OpenGL_ES1 = 1; diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c new file mode 100644 index 0000000000..171ea62b97 --- /dev/null +++ b/src/gallium/state_trackers/es/st_es2.c @@ -0,0 +1,3 @@ +#include "pipe/p_compiler.h" + +PUBLIC const int st_api_OpenGL_ES2 = 1; diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c index 84d47b12ed..bd4a85caa0 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c +++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c @@ -193,7 +193,7 @@ _glxapi_get_proc_address(const char *funcName) } -__GLXextFuncPtr +PUBLIC __GLXextFuncPtr glXGetProcAddressARB(const GLubyte *procName) { __GLXextFuncPtr f; diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 1783bc504d..fb314f3b52 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -760,7 +760,6 @@ PUBLIC XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) { static GLboolean firstTime = GL_TRUE; - struct pipe_context *_pipe = NULL; struct pipe_context *pipe = NULL; XMesaContext c; GLcontext *mesaCtx; @@ -788,11 +787,12 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) if (screen == NULL) goto fail; - _pipe = driver.create_pipe_context(_screen, (void *) c); - if (_pipe == NULL) + /* Trace screen knows how to properly wrap context creation in the + * wrapped screen, so nothing special to do here: + */ + pipe = screen->context_create(screen, (void *) c); + if (pipe == NULL) goto fail; - pipe = trace_context_create(screen, _pipe); - pipe->priv = c; c->st = st_create_context(pipe, &v->mesa_visual, diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index d24971ca1c..63a329cbe0 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -60,7 +60,7 @@ and create a window, you must do the following to use the X/Mesa interface: #include "main/mtypes.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" # include <X11/Xlib.h> diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_winsys.h index 0e57605c34..4bd5b5c8d3 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h +++ b/src/gallium/state_trackers/glx/xlib/xm_winsys.h @@ -39,13 +39,6 @@ struct xm_driver { struct pipe_screen *(*create_pipe_screen)( void ); - /* The context_private argument needs to go away. Is currently used - * in a round-about way to associate a display-target surface with its - * Xlib window. - */ - struct pipe_context *(*create_pipe_context)( struct pipe_screen *, - void *context_private ); - void (*display_surface)( struct xmesa_buffer *, struct pipe_surface * ); diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 8498a90812..527e065cd9 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -21,6 +21,7 @@ if 'python' in env['statetrackers']: 'gdi32', 'user32', 'kernel32', + 'ws2_32', ]) else: env.Append(LIBS = [ diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 96b13c2258..99e177b0be 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -40,9 +40,9 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "cso_cache/cso_context.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_tile.h" #include "util/u_math.h" @@ -76,7 +76,6 @@ %rename(BlendColor) pipe_blend_color; %rename(Blend) pipe_blend_state; %rename(Clip) pipe_clip_state; -%rename(ConstantBuffer) pipe_constant_buffer; %rename(Depth) pipe_depth_state; %rename(Stencil) pipe_stencil_state; %rename(Alpha) pipe_alpha_state; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 84ce1a41e6..ce893dad45 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -142,10 +142,7 @@ struct st_context { void set_constant_buffer(unsigned shader, unsigned index, struct pipe_buffer *buffer ) { - struct pipe_constant_buffer state; - memset(&state, 0, sizeof(state)); - state.buffer = buffer; - $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); + $self->pipe->set_constant_buffer($self->pipe, shader, index, buffer); } void set_framebuffer(const struct pipe_framebuffer_state *state ) diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index bb61979d07..190db43b08 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -94,7 +94,7 @@ struct_factories = { "pipe_blend_color": gallium.BlendColor, "pipe_blend_state": gallium.Blend, #"pipe_clip_state": gallium.Clip, - #"pipe_constant_buffer": gallium.ConstantBuffer, + #"pipe_buffer": gallium.Buffer, "pipe_depth_state": gallium.Depth, "pipe_stencil_state": gallium.Stencil, "pipe_alpha_state": gallium.Alpha, @@ -462,10 +462,10 @@ class Context(Object): sys.stdout.flush() def set_constant_buffer(self, shader, index, buffer): - if buffer is not None and buffer.buffer is not None: - self.real.set_constant_buffer(shader, index, buffer.buffer) + if buffer is not None: + self.real.set_constant_buffer(shader, index, buffer) - self.dump_constant_buffer(buffer.buffer) + self.dump_constant_buffer(buffer) def set_framebuffer_state(self, state): _state = gallium.Framebuffer() @@ -534,6 +534,8 @@ class Context(Object): gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f', gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f', gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B', + gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B', + gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h', }[velem.src_format] data = vbuf.buffer.read() diff --git a/src/gallium/state_trackers/python/samples/gs.py b/src/gallium/state_trackers/python/samples/gs.py index a07cf557f2..cd68abac9a 100644 --- a/src/gallium/state_trackers/python/samples/gs.py +++ b/src/gallium/state_trackers/python/samples/gs.py @@ -72,11 +72,11 @@ def test(dev): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index e5e168bdc8..f0b5e3dc98 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -72,11 +72,11 @@ def test(dev): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index d144af2447..1146a8b0c3 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -29,7 +29,7 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -80,8 +80,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) { struct st_device *st_dev; - if(!st_ws->screen_create || - !st_ws->context_create) + if(!st_ws->screen_create) return NULL; st_dev = CALLOC_STRUCT(st_device); @@ -158,13 +157,7 @@ st_context_create(struct st_device *st_dev) st_device_reference(&st_ctx->st_dev, st_dev); - st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen); - if(!st_ctx->real_pipe) { - st_context_destroy(st_ctx); - return NULL; - } - - st_ctx->pipe = trace_context_create(st_dev->screen, st_ctx->real_pipe); + st_ctx->pipe = st_dev->screen->create_context(st_dev->screen, NULL); if(!st_ctx->pipe) { st_context_destroy(st_ctx); return NULL; @@ -180,11 +173,11 @@ st_context_create(struct st_device *st_dev) { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(st_ctx->cso, &blend); } diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index f786e13411..de9e0215d8 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -50,7 +50,6 @@ struct st_surface struct st_context { struct st_device *st_dev; - struct pipe_context *real_pipe; struct pipe_context *pipe; struct cso_context *cso; diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c index 43aaaabf2a..a3110a19d5 100644 --- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -217,21 +217,6 @@ st_hardpipe_screen_create(void) } -static struct pipe_context * -st_hardpipe_context_create(struct pipe_screen *screen) -{ - if(st_hardpipe_load()) { - if(screen == pfnGetGalliumScreenMESA()) - return pfnCreateGalliumContextMESA(); - else - return NULL; - } - else - return st_softpipe_winsys.context_create(screen); -} - - const struct st_winsys st_hardpipe_winsys = { - &st_hardpipe_screen_create, - &st_hardpipe_context_create + &st_hardpipe_screen_create }; diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c index 0096b18c99..5d83b5a9e1 100644 --- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c @@ -36,7 +36,7 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "llvmpipe/lp_winsys.h" @@ -135,14 +135,7 @@ no_winsys: } -static struct pipe_context * -st_llvmpipe_context_create(struct pipe_screen *screen) -{ - return llvmpipe_create(screen); -} - const struct st_winsys st_softpipe_winsys = { - &st_llvmpipe_screen_create, - &st_llvmpipe_context_create, + &st_llvmpipe_screen_create }; diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index 9637741421..32a6551a87 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -29,7 +29,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_tile.h" #include "util/u_math.h" diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index a3294e877a..81676bc3a4 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -35,225 +35,9 @@ * @author Jose Fonseca */ - -#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */ -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "st_winsys.h" - -struct st_softpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; -}; - - -/** Cast wrapper */ -static INLINE struct st_softpipe_buffer * -st_softpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct st_softpipe_buffer *)buf; -} - - -static void * -st_softpipe_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = st_softpipe_buf->data; - return st_softpipe_buf->mapped; -} - - -static void -st_softpipe_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = NULL; -} - - -static void -st_softpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); - - if (oldBuf->data) { - if (!oldBuf->userBuffer) - align_free(oldBuf->data); - - oldBuf->data = NULL; - } - - FREE(oldBuf); -} - - -static void -st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ -} - - - -static const char * -st_softpipe_get_name(struct pipe_winsys *winsys) -{ - return "softpipe"; -} - - -static struct pipe_buffer * -st_softpipe_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -st_softpipe_user_buffer_create(struct pipe_winsys *winsys, - void *ptr, - unsigned bytes) -{ - struct st_softpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(st_softpipe_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -static struct pipe_buffer * -st_softpipe_surface_buffer_create(struct pipe_winsys *winsys, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - const unsigned alignment = 64; - unsigned nblocksy; - - nblocksy = util_format_get_nblocksy(format, height); - *stride = align(util_format_get_stride(format, width), alignment); - - return winsys->buffer_create(winsys, alignment, - usage, - *stride * nblocksy); -} - - -static void -st_softpipe_fence_reference(struct pipe_winsys *winsys, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -st_softpipe_fence_signalled(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -st_softpipe_fence_finish(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static void -st_softpipe_destroy(struct pipe_winsys *winsys) -{ - FREE(winsys); -} - - -static struct pipe_screen * -st_softpipe_screen_create(void) -{ - static struct pipe_winsys *winsys; - struct pipe_screen *screen; - - winsys = CALLOC_STRUCT(pipe_winsys); - if(!winsys) - return NULL; - - winsys->destroy = st_softpipe_destroy; - - winsys->buffer_create = st_softpipe_buffer_create; - winsys->user_buffer_create = st_softpipe_user_buffer_create; - winsys->buffer_map = st_softpipe_buffer_map; - winsys->buffer_unmap = st_softpipe_buffer_unmap; - winsys->buffer_destroy = st_softpipe_buffer_destroy; - - winsys->surface_buffer_create = st_softpipe_surface_buffer_create; - - winsys->fence_reference = st_softpipe_fence_reference; - winsys->fence_signalled = st_softpipe_fence_signalled; - winsys->fence_finish = st_softpipe_fence_finish; - - winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; - winsys->get_name = st_softpipe_get_name; - - screen = softpipe_create_screen(winsys); - if(!screen) - st_softpipe_destroy(winsys); - - return screen; -} - - -static struct pipe_context * -st_softpipe_context_create(struct pipe_screen *screen) -{ - return softpipe_create(screen); -} - - const struct st_winsys st_softpipe_winsys = { - &st_softpipe_screen_create, - &st_softpipe_context_create, + &softpipe_create_screen_malloc }; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h index b8cb612d86..0c7b6a200e 100644 --- a/src/gallium/state_trackers/python/st_winsys.h +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -38,9 +38,6 @@ struct st_winsys { struct pipe_screen * (*screen_create)(void); - - struct pipe_context * - (*context_create)(struct pipe_screen *screen); }; diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore b/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore new file mode 100644 index 0000000000..e33609d251 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore @@ -0,0 +1 @@ +*.png diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh new file mode 100644 index 0000000000..85fb9ea4e7 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh @@ -0,0 +1,13 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR +DCL CONST[1] +DCL CONST[3] +DCL TEMP[0..1] + +ADD TEMP[0], IN[0], CONST[1] +RCP TEMP[1], CONST[3].xxxx +MUL OUT[0], TEMP[0], TEMP[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh new file mode 100644 index 0000000000..f70a5146f4 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh @@ -0,0 +1,9 @@ +FRAG + +DCL IN[0], COLOR, LINEAR +DCL OUT[0], COLOR +DCL CONST[1][1..2] + +MAD OUT[0], IN[0], CONST[1][2], CONST[1][1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh index f2a1521cbf..d58b7886a1 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh @@ -1,4 +1,4 @@ -FRAG1.1 +FRAG DCL IN[0], COLOR, LINEAR DCL OUT[0], COLOR diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py index 8d3bf9d4d7..41dd69d254 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py @@ -26,6 +26,7 @@ # ########################################################################## +import struct from gallium import * @@ -50,11 +51,11 @@ def test(dev, name): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha @@ -146,6 +147,42 @@ def test(dev, name): fs = Shader(file('frag-' + name + '.sh', 'rt').read()) ctx.set_fragment_shader(fs) + constbuf0 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0) + cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0) + cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0) + cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0) + + constbuf0.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT, + 0, + constbuf0) + + constbuf1 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1) + cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75) + + constbuf1.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT, + 1, + constbuf1) + xy = [ -0.8, -0.8, 0.8, -0.8, @@ -184,6 +221,8 @@ def main(): tests = [ 'abs', 'add', + 'cb-1d', + 'cb-2d', 'dp3', 'dp4', 'dst', diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore b/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore new file mode 100644 index 0000000000..e33609d251 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore @@ -0,0 +1 @@ +*.png diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh new file mode 100644 index 0000000000..b41fe5dd38 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh @@ -0,0 +1,16 @@ +VERT + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL CONST[1] +DCL CONST[3] +DCL TEMP[0..1] + +MOV OUT[0], IN[0] +ADD TEMP[0], IN[1], CONST[1] +RCP TEMP[1], CONST[3].xxxx +MUL OUT[1], TEMP[0], TEMP[1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh new file mode 100644 index 0000000000..45f5e6b729 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh @@ -0,0 +1,12 @@ +VERT + +DCL IN[0], POSITION +DCL IN[1], COLOR +DCL OUT[0], POSITION +DCL OUT[1], COLOR +DCL CONST[1][1..2] + +MOV OUT[0], IN[0] +MAD OUT[1], IN[1], CONST[1][2], CONST[1][1] + +END diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py index 01bf5a3210..2c44f872e1 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py +++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py @@ -27,6 +27,8 @@ ########################################################################## +import struct + from gallium import * def make_image(surface): @@ -50,11 +52,11 @@ def test(dev, name): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha @@ -143,6 +145,42 @@ def test(dev, name): ''') ctx.set_fragment_shader(fs) + constbuf0 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0) + cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0) + cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0) + cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0) + + constbuf0.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_VERTEX, + 0, + constbuf0) + + constbuf1 = dev.buffer_create(64, + (PIPE_BUFFER_USAGE_CONSTANT | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE), + 4 * 4 * 4) + + cbdata = '' + cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1) + cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25) + cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5) + cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75) + + constbuf1.write(cbdata, 0) + + ctx.set_constant_buffer(PIPE_SHADER_VERTEX, + 1, + constbuf1) + xy = [ 0.0, 0.8, -0.2, 0.4, @@ -213,6 +251,8 @@ def main(): 'add', 'arl', 'arr', + 'cb-1d', + 'cb-2d', 'dp3', 'dp4', 'dst', diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py index 79287f2cac..0fac1ea5ef 100755 --- a/src/gallium/state_trackers/python/tests/texture_render.py +++ b/src/gallium/state_trackers/python/tests/texture_render.py @@ -115,11 +115,11 @@ class TextureTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # no-op depth/stencil/alpha diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py index 520961c805..db32b537a1 100755 --- a/src/gallium/state_trackers/python/tests/texture_sample.py +++ b/src/gallium/state_trackers/python/tests/texture_sample.py @@ -140,11 +140,11 @@ class TextureColorSampleTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # no-op depth/stencil/alpha @@ -327,11 +327,11 @@ class TextureDepthSampleTest(TestCase): # disabled blending/masking blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.rt[0].colormask = PIPE_MASK_RGBA ctx.set_blend(blend) # depth/stencil/alpha diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile index fc97bf51f8..037d8dc911 100644 --- a/src/gallium/state_trackers/vega/Makefile +++ b/src/gallium/state_trackers/vega/Makefile @@ -1,8 +1,14 @@ -# src/mesa/Makefile +# src/gallium/state_trackers/vega/Makefile TOP = ../../../.. include $(TOP)/configs/current -GALLIUM = $(TOP) + +VG_LIB = OpenVG +VG_LIB_NAME = lib$(VG_LIB).so + +VG_MAJOR = 1 +VG_MINOR = 0 +VG_TINY = 0 ### Lists of source files, included by Makefiles @@ -34,88 +40,54 @@ VG_SOURCES = \ shader.c \ shaders_cache.c +VG_OBJECTS = $(VG_SOURCES:.c=.o) -### All the core C sources - -ALL_SOURCES = \ - $(VG_SOURCES) - - -### Object files -VG_OBJECTS = \ - $(VG_SOURCES:.c=.o) +VG_LIBS = $(GALLIUM_AUXILIARIES) -lm ### Include directories INCLUDE_DIRS = \ -I$(TOP)/include \ - -I$(GALLIUM)/include \ - -I$(GALLIUM)/src/gallium/include \ - -I$(GALLIUM)/src/gallium/auxiliary + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary -VG_LIB = OpenVG -VG_LIB_NAME = lib$(VG_LIB).so - -VG_MAJOR = 1 -VG_MINOR = 0 -VG_TINY = 0 - -GALLIUM_LIBS = \ - $(GALLIUM)/src/gallium/auxiliary/libgallium.a - -.SUFFIXES : .cpp .c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@ -.cpp.o: - $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - -default: depend subdirs $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) +default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) # Make the OpenVG library -$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(GALLIUM_LIBS) - $(TOP)/bin/mklib -o $(VG_LIB) \ +$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(VG_LIBS) + $(MKLIB) -o $(VG_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(VG_MAJOR) \ -minor $(VG_MINOR) \ -patch $(VG_TINY) \ -install $(TOP)/$(LIB_DIR) \ - $(VG_OBJECTS) $(GALLIUM_LIBS) \ - -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive $(SYS_LIBS) + $(VG_OBJECTS) $(VG_LIBS) ###################################################################### # Generic stuff -depend: $(ALL_SOURCES) +depend: $(VG_SOURCES) @ echo "running $(MKDEP)" @ rm -f depend # workaround oops on gutsy?!? @ touch depend - @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(VG_SOURCES) \ > /dev/null 2>/dev/null - -subdirs: - install: default - $(INSTALL) -d $(INSTALL_DIR)/include/VG - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(INSTALL_DIR)/include/VG - @if [ -e $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(INSTALL_DIR)/$(LIB_DIR); \ - fi + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/VG + $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(DESTDIR)$(INSTALL_DIR)/include/VG + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) # Emacs tags tags: etags `find . -name \*.[ch]` $(TOP)/include/VG/*.h clean: - -rm -f *.o - -rm -f */*.o - -rm -f */*/*.o - -rm -f depend depend.bak + rm -f $(VG_OBJECTS) + rm -f depend depend.bak -include depend +sinclude depend diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 2f984fb7b9..20c72c1ff5 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -34,7 +34,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_shader_tokens.h" @@ -127,19 +127,19 @@ static void setup_blend() struct vg_context *ctx = vg_current_context(); struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (ctx->state.vg.filter_channel_mask & VG_RED) - blend.colormask |= PIPE_MASK_R; + blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->state.vg.filter_channel_mask & VG_GREEN) - blend.colormask |= PIPE_MASK_G; + blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->state.vg.filter_channel_mask & VG_BLUE) - blend.colormask |= PIPE_MASK_B; + blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->state.vg.filter_channel_mask & VG_ALPHA) - blend.colormask |= PIPE_MASK_A; - blend.blend_enable = 1; + blend.rt[0].colormask |= PIPE_MASK_A; + blend.rt[0].blend_enable = 0; cso_set_blend(ctx->cso_context, &blend); } @@ -147,22 +147,22 @@ static void setup_constant_buffer(struct vg_context *ctx, const void *buffer, VGint param_bytes) { struct pipe_context *pipe = ctx->pipe; - struct pipe_constant_buffer *cbuf = &ctx->filter.buffer; + struct pipe_buffer **cbuf = &ctx->filter.buffer; /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ - pipe_buffer_reference(&cbuf->buffer, NULL); + pipe_buffer_reference(cbuf, NULL); - cbuf->buffer = pipe_buffer_create(pipe->screen, 16, - PIPE_BUFFER_USAGE_CONSTANT, - param_bytes); + *cbuf = pipe_buffer_create(pipe->screen, 16, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); - if (cbuf->buffer) { - st_no_flush_pipe_buffer_write(ctx, cbuf->buffer, + if (*cbuf) { + st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, buffer); } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf); } static void setup_samplers(struct vg_context *ctx, struct filter_info *info) diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c index c437553bc2..015241498e 100644 --- a/src/gallium/state_trackers/vega/api_images.c +++ b/src/gallium/state_trackers/vega/api_images.c @@ -35,7 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_blit.h" #include "util/u_tile.h" #include "util/u_memory.h" diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 4f9f3dae17..9c123a4cf9 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -31,8 +31,7 @@ #include "vg_context.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" /* for winsys->update_buffer */ +#include "util/u_inlines.h" #include "util/u_pack_color.h" #include "util/u_draw_quad.h" @@ -116,8 +115,8 @@ clear_with_quad(struct vg_context *st, float x0, float y0, x1, y1); */ - if (st->pipe->winsys && st->pipe->winsys->update_buffer) - st->pipe->winsys->update_buffer( st->pipe->winsys, + if (st->pipe->screen && st->pipe->screen->update_buffer) + st->pipe->screen->update_buffer( st->pipe->screen, st->pipe->priv ); cso_save_blend(st->cso_context); @@ -129,14 +128,11 @@ clear_with_quad(struct vg_context *st, float x0, float y0, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask |= PIPE_MASK_R; - blend.colormask |= PIPE_MASK_G; - blend.colormask |= PIPE_MASK_B; - blend.colormask |= PIPE_MASK_A; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(st->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c index 15ac1900f4..58ebb3b60e 100644 --- a/src/gallium/state_trackers/vega/api_path.c +++ b/src/gallium/state_trackers/vega/api_path.c @@ -32,7 +32,7 @@ #include "paint.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" VGPath vgCreatePath(VGint pathFormat, diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h index 2f394ad6c5..27773467fa 100644 --- a/src/gallium/state_trackers/vega/asm_fill.h +++ b/src/gallium/state_trackers/vega/asm_fill.h @@ -27,166 +27,375 @@ #ifndef ASM_FILL_H #define ASM_FILL_H -static const char solid_fill_asm[] = - "MOV %s, CONST[0]\n"; - - -static const char linear_grad_asm[] = - "MOV TEMP[0].xy, IN[0]\n" - "MOV TEMP[0].z, CONST[1].yyyy\n" - "DP3 TEMP[1], CONST[2], TEMP[0]\n" - "DP3 TEMP[2], CONST[3], TEMP[0]\n" - "DP3 TEMP[3], CONST[4], TEMP[0]\n" - "RCP TEMP[3], TEMP[3]\n" - "MUL TEMP[1], TEMP[1], TEMP[3]\n" - "MUL TEMP[2], TEMP[2], TEMP[3]\n" - "MOV TEMP[4].x, TEMP[1]\n" - "MOV TEMP[4].y, TEMP[2]\n" - "MUL TEMP[0], CONST[0].yyyy, TEMP[4].yyyy\n" - "MAD TEMP[1], CONST[0].xxxx, TEMP[4].xxxx, TEMP[0]\n" - "MUL TEMP[2], TEMP[1], CONST[0].zzzz\n" - "TEX %s, TEMP[2], SAMP[0], 1D\n"; - -static const char radial_grad_asm[] = - "MOV TEMP[0].xy, IN[0]\n" - "MOV TEMP[0].z, CONST[1].yyyy\n" - "DP3 TEMP[1], CONST[2], TEMP[0]\n" - "DP3 TEMP[2], CONST[3], TEMP[0]\n" - "DP3 TEMP[3], CONST[4], TEMP[0]\n" - "RCP TEMP[3], TEMP[3]\n" - "MUL TEMP[1], TEMP[1], TEMP[3]\n" - "MUL TEMP[2], TEMP[2], TEMP[3]\n" - "MOV TEMP[5].x, TEMP[1]\n" - "MOV TEMP[5].y, TEMP[2]\n" - "MUL TEMP[0], CONST[0].yyyy, TEMP[5].yyyy\n" - "MAD TEMP[1], CONST[0].xxxx, TEMP[5].xxxx, TEMP[0]\n" - "ADD TEMP[1], TEMP[1], TEMP[1]\n" - "MUL TEMP[3], TEMP[5].yyyy, TEMP[5].yyyy\n" - "MAD TEMP[4], TEMP[5].xxxx, TEMP[5].xxxx, TEMP[3]\n" - "MOV TEMP[4], -TEMP[4]\n" - "MUL TEMP[2], CONST[0].zzzz, TEMP[4]\n" - "MUL TEMP[0], CONST[1].wwww, TEMP[2]\n" - "MUL TEMP[3], TEMP[1], TEMP[1]\n" - "SUB TEMP[2], TEMP[3], TEMP[0]\n" - "RSQ TEMP[2], |TEMP[2]|\n" - "RCP TEMP[2], TEMP[2]\n" - "SUB TEMP[1], TEMP[2], TEMP[1]\n" - "ADD TEMP[0], CONST[0].zzzz, CONST[0].zzzz\n" - "RCP TEMP[0], TEMP[0]\n" - "MUL TEMP[2], TEMP[1], TEMP[0]\n" - "TEX %s, TEMP[2], SAMP[0], 1D\n"; - -static const char pattern_asm[] = - "MOV TEMP[0].xy, IN[0]\n" - "MOV TEMP[0].z, CONST[1].yyyy\n" - "DP3 TEMP[1], CONST[2], TEMP[0]\n" - "DP3 TEMP[2], CONST[3], TEMP[0]\n" - "DP3 TEMP[3], CONST[4], TEMP[0]\n" - "RCP TEMP[3], TEMP[3]\n" - "MUL TEMP[1], TEMP[1], TEMP[3]\n" - "MUL TEMP[2], TEMP[2], TEMP[3]\n" - "MOV TEMP[4].x, TEMP[1]\n" - "MOV TEMP[4].y, TEMP[2]\n" - "RCP TEMP[0], CONST[1].zwzw\n" - "MOV TEMP[1], TEMP[4]\n" - "MUL TEMP[1].x, TEMP[1], TEMP[0]\n" - "MUL TEMP[1].y, TEMP[1], TEMP[0]\n" - "TEX %s, TEMP[1], SAMP[0], 2D\n"; - - -static const char mask_asm[] = - "TEX TEMP[1], IN[0], SAMP[1], 2D\n" - "MUL TEMP[0].w, TEMP[0].wwww, TEMP[1].wwww\n" - "MOV %s, TEMP[0]\n"; - - -static const char image_normal_asm[] = - "TEX %s, IN[1], SAMP[3], 2D\n"; - -static const char image_multiply_asm[] = - "TEX TEMP[1], IN[1], SAMP[3], 2D\n" - "MUL %s, TEMP[0], TEMP[1]\n"; - -static const char image_stencil_asm[] = - "TEX TEMP[1], IN[1], SAMP[3], 2D\n" - "MUL %s, TEMP[0], TEMP[1]\n"; - - -#define EXTENDED_BLEND_OVER \ - "SUB TEMP[3], CONST[1].yyyy, TEMP[1].wwww\n" \ - "SUB TEMP[4], CONST[1].yyyy, TEMP[0].wwww\n" \ - "MUL TEMP[3], TEMP[0], TEMP[3]\n" \ - "MUL TEMP[4], TEMP[1], TEMP[4]\n" \ - "ADD TEMP[3], TEMP[3], TEMP[4]\n" - -static const char blend_multiply_asm[] = - "TEX TEMP[1], IN[0], SAMP[2], 2D\n" - EXTENDED_BLEND_OVER - "MUL TEMP[4], TEMP[0], TEMP[1]\n" - "ADD TEMP[1], TEMP[4], TEMP[3]\n"/*result.rgb*/ - "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n" - "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n" - "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" - "MOV %s, TEMP[1]\n"; -#if 1 -static const char blend_screen_asm[] = - "TEX TEMP[1], IN[0], SAMP[2], 2D\n" - "ADD TEMP[3], TEMP[0], TEMP[1]\n" - "MUL TEMP[2], TEMP[0], TEMP[1]\n" - "SUB %s, TEMP[3], TEMP[2]\n"; -#else -static const char blend_screen_asm[] = - "TEX TEMP[1], IN[0], SAMP[2], 2D\n" - "MOV %s, TEMP[1]\n"; -#endif - -static const char blend_darken_asm[] = - "TEX TEMP[1], IN[0], SAMP[2], 2D\n" - EXTENDED_BLEND_OVER - "MUL TEMP[4], TEMP[0], TEMP[1].wwww\n" - "MUL TEMP[5], TEMP[1], TEMP[0].wwww\n" - "MIN TEMP[4], TEMP[4], TEMP[5]\n" - "ADD TEMP[1], TEMP[3], TEMP[4]\n" - "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n" - "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n" - "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" - "MOV %s, TEMP[1]\n"; - -static const char blend_lighten_asm[] = - "TEX TEMP[1], IN[0], SAMP[2], 2D\n" - EXTENDED_BLEND_OVER - "MUL TEMP[4], TEMP[0], TEMP[1].wwww\n" - "MUL TEMP[5], TEMP[1], TEMP[0].wwww\n" - "MAX TEMP[4], TEMP[4], TEMP[5]\n" - "ADD TEMP[1], TEMP[3], TEMP[4]\n" - "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n" - "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n" - "SUB TEMP[1].w, TEMP[3], TEMP[2]\n" - "MOV %s, TEMP[1]\n"; - - -static const char premultiply_asm[] = - "MUL TEMP[0].xyz, TEMP[0], TEMP[0].wwww\n"; - -static const char unpremultiply_asm[] = - "TEX TEMP[0], IN[0], SAMP[1], 2D\n"; - - -static const char color_bw_asm[] = - "ADD TEMP[1], CONST[1].yyyy, CONST[1].yyyy\n" - "RCP TEMP[2], TEMP[1]\n" - "ADD TEMP[1], CONST[1].yyyy, TEMP[2]\n" - "ADD TEMP[2].x, TEMP[0].xxxx, TEMP[0].yyyy\n" - "ADD TEMP[2].x, TEMP[0].zzzz, TEMP[0].xxxx\n" - "SGE TEMP[0].xyz, TEMP[2].xxxx, TEMP[1]\n" - "SGE TEMP[0].w, TEMP[0].wwww, TEMP[2].yyyy\n" - "MOV %s, TEMP[0]\n"; +#include "tgsi/tgsi_ureg.h" + +typedef void (* ureg_func)( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant); + +static INLINE void +solid_fill( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_MOV(ureg, *out, constant[0]); +} + +static INLINE void +linear_grad( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + + ureg_MOV(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_XY), + in[0]); + ureg_MOV(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_Z), + ureg_scalar(constant[1], TGSI_SWIZZLE_Y)); + ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0])); + ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0])); + ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0])); + ureg_RCP(ureg, temp[3], ureg_src(temp[3])); + ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); + ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); + ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1])); + ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2])); + ureg_MUL(ureg, temp[0], + ureg_scalar(constant[0], TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp[1], + ureg_scalar(constant[0], TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X), + ureg_src(temp[0])); + ureg_MUL(ureg, temp[2], ureg_src(temp[1]), + ureg_scalar(constant[0], TGSI_SWIZZLE_Z)); + ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]); +} + +static INLINE void +radial_grad( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + + ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); + ureg_MOV(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_Z), + ureg_scalar(constant[1], TGSI_SWIZZLE_Y)); + ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0])); + ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0])); + ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0])); + ureg_RCP(ureg, temp[3], ureg_src(temp[3])); + ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); + ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); + ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_X), ureg_src(temp[1])); + ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_Y), ureg_src(temp[2])); + ureg_MUL(ureg, temp[0], ureg_scalar(constant[0], TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp[1], + ureg_scalar(constant[0], TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), ureg_src(temp[0])); + ureg_ADD(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[1])); + ureg_MUL(ureg, temp[3], + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp[4], + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), + ureg_src(temp[3])); + ureg_MOV(ureg, temp[4], ureg_negate(ureg_src(temp[4]))); + ureg_MUL(ureg, temp[2], + ureg_scalar(constant[0], TGSI_SWIZZLE_Z), + ureg_src(temp[4])); + ureg_MUL(ureg, temp[0], + ureg_scalar(constant[1], TGSI_SWIZZLE_W), + ureg_src(temp[2])); + ureg_MUL(ureg, temp[3], ureg_src(temp[1]), ureg_src(temp[1])); + + ureg_SUB(ureg, temp[2], ureg_src(temp[3]), ureg_src(temp[0])); + ureg_RSQ(ureg, temp[2], ureg_abs(ureg_src(temp[2]))); + ureg_RCP(ureg, temp[2], ureg_src(temp[2])); + ureg_SUB(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[1])); + ureg_ADD(ureg, temp[0], + ureg_scalar(constant[0], TGSI_SWIZZLE_Z), + ureg_scalar(constant[0], TGSI_SWIZZLE_Z)); + ureg_RCP(ureg, temp[0], ureg_src(temp[0])); + ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_src(temp[0])); + ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]); + +} + + +static INLINE void +pattern( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_MOV(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_XY), + in[0]); + ureg_MOV(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_Z), + ureg_scalar(constant[1], TGSI_SWIZZLE_Y)); + ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0])); + ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0])); + ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0])); + ureg_RCP(ureg, temp[3], ureg_src(temp[3])); + ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); + ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); + ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1])); + ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2])); + ureg_RCP(ureg, temp[0], + ureg_swizzle(constant[1], + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_W, + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_W)); + ureg_MOV(ureg, temp[1], ureg_src(temp[4])); + ureg_MUL(ureg, + ureg_writemask(temp[1], TGSI_WRITEMASK_X), + ureg_src(temp[1]), + ureg_src(temp[0])); + ureg_MUL(ureg, + ureg_writemask(temp[1], TGSI_WRITEMASK_Y), + ureg_src(temp[1]), + ureg_src(temp[0])); + ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]); +} + +static INLINE void +mask( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]); + ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_MOV(ureg, *out, ureg_src(temp[0])); +} + +static INLINE void +image_normal( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, in[1], sampler[3]); +} + + +static INLINE void +image_multiply( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]); + ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1])); +} + + +static INLINE void +image_stencil( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]); + ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1])); +} + +#define EXTENDED_BLENDER_OVER_FUNC \ + ureg_SUB(ureg, temp[3], \ + ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \ + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); \ + ureg_SUB(ureg, temp[3], \ + ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \ + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); \ + ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3])); \ + ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4])); \ + ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4])); + + +static INLINE void +blend_multiply( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]); + EXTENDED_BLENDER_OVER_FUNC + ureg_MUL(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[1])); + ureg_ADD(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[3])); + + ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W), + ureg_src(temp[3]), ureg_src(temp[2])); + + ureg_MOV(ureg, *out, ureg_src(temp[1])); +} + +static INLINE void +blend_screen( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]); + ureg_ADD(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[1])); + ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[1])); + ureg_SUB(ureg, *out, ureg_src(temp[3]), ureg_src(temp[2])); +} + +static INLINE void +blend_darken( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]); + EXTENDED_BLENDER_OVER_FUNC + ureg_MUL(ureg, temp[4], ureg_src(temp[0]), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_MUL(ureg, temp[5], ureg_src(temp[1]), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); + ureg_MIN(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5])); + ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4])); + + ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W), + ureg_src(temp[3]), ureg_src(temp[2])); + + ureg_MOV(ureg, *out, ureg_src(temp[1])); +} + +static INLINE void +blend_lighten( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]); + EXTENDED_BLENDER_OVER_FUNC + ureg_MUL(ureg, temp[4], ureg_src(temp[0]), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_MUL(ureg, temp[5], ureg_src(temp[1]), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); + ureg_MAX(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5])); + ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4])); + + ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); + ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W), + ureg_src(temp[3]), ureg_src(temp[2])); + + ureg_MOV(ureg, *out, ureg_src(temp[1])); +} + +static INLINE void +premultiply( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_MUL(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ), + ureg_src(temp[0]), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); +} + +static INLINE void +unpremultiply( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]); +} + + +static INLINE void +color_bw( struct ureg_program *ureg, + struct ureg_dst *out, + struct ureg_src *in, + struct ureg_src *sampler, + struct ureg_dst *temp, + struct ureg_src *constant) +{ + ureg_ADD(ureg, temp[1], + ureg_scalar(constant[1], TGSI_SWIZZLE_Y), + ureg_scalar(constant[1], TGSI_SWIZZLE_Y)); + ureg_RCP(ureg, temp[2], ureg_src(temp[1])); + ureg_ADD(ureg, temp[1], + ureg_scalar(constant[1], TGSI_SWIZZLE_Y), + ureg_src(temp[2])); + ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y)); + ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X)); + ureg_SGE(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ), + ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X), + ureg_src(temp[1])); + ureg_SGE(ureg, + ureg_writemask(temp[0], TGSI_WRITEMASK_W), + ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W), + ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y)); + ureg_MOV(ureg, *out, ureg_src(temp[0])); +} struct shader_asm_info { VGint id; - VGint num_tokens; - const char * txt; + ureg_func func; VGboolean needs_position; @@ -203,44 +412,44 @@ struct shader_asm_info { static const struct shader_asm_info shaders_asm[] = { /* fills */ - {VEGA_SOLID_FILL_SHADER, 40, solid_fill_asm, + {VEGA_SOLID_FILL_SHADER, solid_fill, VG_FALSE, 0, 1, 0, 0, 0, 0}, - {VEGA_LINEAR_GRADIENT_SHADER, 200, linear_grad_asm, + {VEGA_LINEAR_GRADIENT_SHADER, linear_grad, VG_TRUE, 0, 5, 0, 1, 0, 5}, - {VEGA_RADIAL_GRADIENT_SHADER, 200, radial_grad_asm, + {VEGA_RADIAL_GRADIENT_SHADER, radial_grad, VG_TRUE, 0, 5, 0, 1, 0, 6}, - {VEGA_PATTERN_SHADER, 100, pattern_asm, + {VEGA_PATTERN_SHADER, pattern, VG_TRUE, 1, 4, 0, 1, 0, 5}, /* image draw modes */ - {VEGA_IMAGE_NORMAL_SHADER, 200, image_normal_asm, + {VEGA_IMAGE_NORMAL_SHADER, image_normal, VG_TRUE, 0, 0, 3, 1, 0, 0}, - {VEGA_IMAGE_MULTIPLY_SHADER, 200, image_multiply_asm, + {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply, VG_TRUE, 0, 0, 3, 1, 0, 2}, - {VEGA_IMAGE_STENCIL_SHADER, 200, image_stencil_asm, + {VEGA_IMAGE_STENCIL_SHADER, image_stencil, VG_TRUE, 0, 0, 3, 1, 0, 2}, - {VEGA_MASK_SHADER, 100, mask_asm, + {VEGA_MASK_SHADER, mask, VG_TRUE, 0, 0, 1, 1, 0, 2}, /* extra blend modes */ - {VEGA_BLEND_MULTIPLY_SHADER, 200, blend_multiply_asm, + {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply, VG_TRUE, 1, 1, 2, 1, 0, 5}, - {VEGA_BLEND_SCREEN_SHADER, 200, blend_screen_asm, + {VEGA_BLEND_SCREEN_SHADER, blend_screen, VG_TRUE, 0, 0, 2, 1, 0, 4}, - {VEGA_BLEND_DARKEN_SHADER, 200, blend_darken_asm, + {VEGA_BLEND_DARKEN_SHADER, blend_darken, VG_TRUE, 1, 1, 2, 1, 0, 6}, - {VEGA_BLEND_LIGHTEN_SHADER, 200, blend_lighten_asm, + {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten, VG_TRUE, 1, 1, 2, 1, 0, 6}, /* premultiply */ - {VEGA_PREMULTIPLY_SHADER, 100, premultiply_asm, + {VEGA_PREMULTIPLY_SHADER, premultiply, VG_FALSE, 0, 0, 0, 0, 0, 1}, - {VEGA_UNPREMULTIPLY_SHADER, 100, unpremultiply_asm, + {VEGA_UNPREMULTIPLY_SHADER, unpremultiply, VG_FALSE, 0, 0, 0, 0, 0, 1}, /* color transform to black and white */ - {VEGA_BW_SHADER, 150, color_bw_asm, + {VEGA_BW_SHADER, color_bw, VG_FALSE, 1, 1, 0, 0, 0, 3}, }; #endif diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index 1112ad9839..2e10965be4 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_blit.h" #include "util/u_format.h" #include "util/u_tile.h" diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index 42300bb6d5..467b95b751 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -35,7 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" @@ -217,7 +217,7 @@ static void setup_mask_framebuffer(struct pipe_surface *surf, static void setup_mask_operation(VGMaskOperation operation) { struct vg_context *ctx = vg_current_context(); - struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf; + struct pipe_buffer **cbuf = &ctx->mask.cbuf; const VGint param_bytes = 4 * sizeof(VGfloat); const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f}; void *shader = 0; @@ -225,17 +225,17 @@ static void setup_mask_operation(VGMaskOperation operation) /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ - pipe_buffer_reference(&cbuf->buffer, NULL); + pipe_buffer_reference(cbuf, NULL); - cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 1, - PIPE_BUFFER_USAGE_CONSTANT, - param_bytes); - if (cbuf->buffer) { - st_no_flush_pipe_buffer_write(ctx, cbuf->buffer, + *cbuf = pipe_buffer_create(ctx->pipe->screen, 1, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); + if (*cbuf) { + st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, ones); } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf); switch (operation) { case VG_UNION_MASK: { if (!ctx->mask.union_fs) { @@ -320,22 +320,22 @@ static void setup_mask_samplers(struct pipe_texture *umask) static void setup_mask_fill(const VGfloat color[4]) { struct vg_context *ctx = vg_current_context(); - struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf; + struct pipe_buffer **cbuf = &ctx->mask.cbuf; const VGint param_bytes = 4 * sizeof(VGfloat); /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ - pipe_buffer_reference(&cbuf->buffer, NULL); + pipe_buffer_reference(cbuf, NULL); - cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 1, - PIPE_BUFFER_USAGE_CONSTANT, - param_bytes); - if (cbuf->buffer) { - st_no_flush_pipe_buffer_write(ctx, cbuf->buffer, 0, param_bytes, color); + *cbuf = pipe_buffer_create(ctx->pipe->screen, 1, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); + if (*cbuf) { + st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color); } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf); cso_set_fragment_shader_handle(ctx->cso_context, shaders_cache_fill(ctx->sc, VEGA_SOLID_FILL_SHADER)); @@ -354,15 +354,12 @@ static void setup_mask_blend() struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_R; - blend.colormask |= PIPE_MASK_G; - blend.colormask |= PIPE_MASK_B; - blend.colormask |= PIPE_MASK_A; - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].blend_enable = 0; + blend.rt[0].colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; cso_set_blend(ctx->cso_context, &blend); } diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c index cc73771d35..3405d635f0 100644 --- a/src/gallium/state_trackers/vega/paint.c +++ b/src/gallium/state_trackers/vega/paint.c @@ -32,7 +32,7 @@ #include "st_inlines.h" #include "pipe/p_compiler.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_memory.h" @@ -77,7 +77,8 @@ struct vg_paint { struct pipe_sampler_state sampler; } pattern; - struct pipe_constant_buffer cbuf; + /* XXX next 3 all unneded? */ + struct pipe_buffer *cbuf; struct pipe_shader_state fs_state; void *fs; }; diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index b6d282d803..f56ea0c8b4 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_draw_quad.h" @@ -248,12 +248,12 @@ VGboolean polygon_is_closed(struct polygon *p) static void set_blend_for_fill(struct pipe_blend_state *blend) { memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->colormask = 0; /*disable colorwrites*/ + blend->rt[0].colormask = 0; /*disable colorwrites*/ - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; } static void draw_polygon(struct vg_context *ctx, @@ -293,6 +293,7 @@ static void draw_polygon(struct vg_context *ctx, /* tell pipe about the vertex attributes */ velement.src_offset = 0; + velement.instance_divisor = 0; velement.vertex_buffer_index = 0; velement.src_format = PIPE_FORMAT_R32G32_FLOAT; velement.nr_components = COMPONENTS; diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 64e3a7c545..05620efa9c 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -30,7 +30,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_shader_tokens.h" @@ -317,11 +317,11 @@ void renderer_copy_texture(struct renderer *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } @@ -486,11 +486,11 @@ void renderer_copy_surface(struct renderer *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(ctx->cso, &blend); } diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c index d9074a377b..0e71a507bf 100644 --- a/src/gallium/state_trackers/vega/shader.c +++ b/src/gallium/state_trackers/vega/shader.c @@ -35,7 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #define MAX_CONSTANTS 20 @@ -51,7 +51,7 @@ struct shader { VGImageMode image_mode; float constants[MAX_CONSTANTS]; - struct pipe_constant_buffer cbuf; + struct pipe_buffer *cbuf; struct pipe_shader_state fs_state; void *fs; }; @@ -96,25 +96,25 @@ static void setup_constant_buffer(struct shader *shader) { struct vg_context *ctx = shader->context; struct pipe_context *pipe = shader->context->pipe; - struct pipe_constant_buffer *cbuf = &shader->cbuf; + struct pipe_buffer **cbuf = &shader->cbuf; VGint param_bytes = paint_constant_buffer_size(shader->paint); float temp_buf[MAX_CONSTANTS]; assert(param_bytes <= sizeof(temp_buf)); paint_fill_constant_buffer(shader->paint, temp_buf); - if (cbuf->buffer == NULL || + if (*cbuf == NULL || memcmp(temp_buf, shader->constants, param_bytes) != 0) { - pipe_buffer_reference(&cbuf->buffer, NULL); + pipe_buffer_reference(cbuf, NULL); memcpy(shader->constants, temp_buf, param_bytes); - cbuf->buffer = pipe_user_buffer_create(pipe->screen, - &shader->constants, - sizeof(shader->constants)); + *cbuf = pipe_user_buffer_create(pipe->screen, + &shader->constants, + sizeof(shader->constants)); } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf); } static VGint blend_bind_samplers(struct vg_context *ctx, @@ -135,8 +135,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx, textures[2] = stfb->blend_texture; if (!samplers[0] || !textures[0]) { - samplers[1] = samplers[2]; - textures[1] = textures[2]; + samplers[0] = samplers[2]; + textures[0] = textures[2]; } if (!samplers[1] || !textures[1]) { samplers[1] = samplers[0]; diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c index f620075d0b..f43fe6ee4c 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.c +++ b/src/gallium/state_trackers/vega/shaders_cache.c @@ -30,7 +30,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_shader_tokens.h" @@ -123,17 +123,23 @@ static INLINE VGint range_max(VGint max, VGint current) return MAX2(max, current); } -static void -create_preamble(char *txt, - const struct shader_asm_info *shaders[SHADER_STAGES], - int num_shaders) +static void * +combine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders, + struct pipe_context *pipe, + struct pipe_shader_state *shader) { VGboolean declare_input = VG_FALSE; VGint start_const = -1, end_const = 0; VGint start_temp = -1, end_temp = 0; VGint start_sampler = -1, end_sampler = 0; - VGint i; + VGint i, current_shader = 0; VGint num_consts, num_temps, num_samplers; + struct ureg_program *ureg; + struct ureg_src in[2]; + struct ureg_src *sampler = NULL; + struct ureg_src *constant = NULL; + struct ureg_dst out, *temp = NULL; + void *p = NULL; for (i = 0; i < num_shaders; ++i) { if (shaders[i]->num_consts) @@ -158,99 +164,94 @@ create_preamble(char *txt, if (start_temp < 0) start_temp = 0; if (start_sampler < 0) - start_sampler = 0; + start_sampler = 0; num_consts = end_const - start_const; num_temps = end_temp - start_temp; num_samplers = end_sampler - start_sampler; - /* end exclusive */ - --end_const; - --end_temp; - --end_sampler; - sprintf(txt, "FRAG\n"); + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!ureg) + return NULL; if (declare_input) { - sprintf(txt + strlen(txt), "DCL IN[0], POSITION, LINEAR\n"); - sprintf(txt + strlen(txt), "DCL IN[1], GENERIC[0], PERSPECTIVE\n"); + in[0] = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, + 0, + TGSI_INTERPOLATE_LINEAR); + in[1] = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_GENERIC, + 0, + TGSI_INTERPOLATE_PERSPECTIVE); } /* we always have a color output */ - sprintf(txt + strlen(txt), "DCL OUT[0], COLOR, CONSTANT\n"); - - if (num_consts > 1) - sprintf(txt + strlen(txt), "DCL CONST[%d..%d], CONSTANT\n", start_const, end_const); - else if (num_consts == 1) - sprintf(txt + strlen(txt), "DCL CONST[%d], CONSTANT\n", start_const); - - if (num_temps > 1) - sprintf(txt + strlen(txt), "DCL TEMP[%d..%d], CONSTANT\n", start_temp, end_temp); - else if (num_temps > 1) - sprintf(txt + strlen(txt), "DCL TEMP[%d], CONSTANT\n", start_temp); - - if (num_samplers > 1) - sprintf(txt + strlen(txt), "DCL SAMP[%d..%d], CONSTANT\n", start_sampler, end_sampler); - else if (num_samplers == 1) - sprintf(txt + strlen(txt), "DCL SAMP[%d], CONSTANT\n", start_sampler); -} + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); -static void * -combine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders, - struct pipe_context *pipe, - struct pipe_shader_state *shader) -{ - char *combined_txt; - int combined_len = MAX_PREAMBLE; - int combined_tokens = 0; - int i = 0; - int current_shader = 0; - int current_len; + if (num_consts >= 1) { + constant = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_const); + for (i = start_const; i < end_const; i++) { + constant[i] = ureg_DECL_constant(ureg, i); + } - for (i = 0; i < num_shaders; ++i) { - combined_len += strlen(shaders[i]->txt); - combined_tokens += shaders[i]->num_tokens; } - /* add for the %s->TEMP[0] substitutions */ - combined_len += num_shaders * 7 /*TEMP[0]*/ + 4 /*"END\n"*/; - combined_txt = (char*)malloc(combined_len); - combined_txt[0] = '\0'; + if (num_temps >= 1) { + temp = (struct ureg_dst *) malloc(sizeof(struct ureg_dst) * end_temp); + for (i = start_temp; i < end_temp; i++) { + temp[i] = ureg_DECL_temporary(ureg); + } + } - create_preamble(combined_txt, shaders, num_shaders); + if (num_samplers >= 1) { + sampler = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_sampler); + for (i = start_sampler; i < end_sampler; i++) { + sampler[i] = ureg_DECL_sampler(ureg, i); + } + } while (current_shader < num_shaders) { - const char temp[] = "TEMP[0]"; - const char out[] = "OUT[0]"; - const char *subst = temp; - - current_len = strlen(combined_txt); - - /* if the last shader then output */ - if (current_shader + 1 == num_shaders) - subst = out; - - snprintf(combined_txt + current_len, - combined_len - current_len, - shaders[current_shader]->txt, - subst); - ++current_shader; + if ((current_shader + 1) == num_shaders) { + shaders[current_shader]->func(ureg, + &out, + in, + sampler, + temp, + constant); + } else { + shaders[current_shader]->func(ureg, + &temp[0], + in, + sampler, + temp, + constant); + } + current_shader++; } + ureg_END(ureg); - current_len = strlen(combined_txt); - snprintf(combined_txt + current_len, - combined_len - current_len, - "END\n"); + shader->tokens = ureg_finalize(ureg); + if(!shader->tokens) + return NULL; - debug_printf("Combined shader is : \n%s\n", - combined_txt); + p = pipe->create_fs_state(pipe, shader); + ureg_destroy(ureg); - shader->tokens = tokens_from_assembly( - combined_txt, combined_tokens); + if (num_temps >= 1) { + for (i = start_temp; i < end_temp; i++) { + ureg_release_temporary(ureg, temp[i]); + } + } - free(combined_txt); + if (temp) + free(temp); + if (constant) + free(constant); + if (sampler) + free(sampler); - return pipe->create_fs_state(pipe, shader); + return p; } static void * diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h index 610755e063..419151c3ae 100644 --- a/src/gallium/state_trackers/vega/st_inlines.h +++ b/src/gallium/state_trackers/vega/st_inlines.h @@ -38,7 +38,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" static INLINE struct pipe_transfer * diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index 00d23f5c22..426bf9bc62 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -34,7 +34,7 @@ #include "st_inlines.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "cso_cache/cso_context.h" @@ -122,8 +122,8 @@ struct vg_context * vg_create_context(struct pipe_context *pipe, void vg_destroy_context(struct vg_context *ctx) { - struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf; - struct pipe_constant_buffer *vsbuf = &ctx->vs_const_buffer; + struct pipe_buffer **cbuf = &ctx->mask.cbuf; + struct pipe_buffer **vsbuf = &ctx->vs_const_buffer; util_destroy_blit(ctx->blit); renderer_destroy(ctx->renderer); @@ -131,11 +131,11 @@ void vg_destroy_context(struct vg_context *ctx) shader_destroy(ctx->shader); paint_destroy(ctx->default_paint); - if (cbuf && cbuf->buffer) - pipe_buffer_reference(&cbuf->buffer, NULL); + if (*cbuf) + pipe_buffer_reference(cbuf, NULL); - if (vsbuf && vsbuf->buffer) - pipe_buffer_reference(&vsbuf->buffer, NULL); + if (*vsbuf) + pipe_buffer_reference(vsbuf, NULL); if (ctx->clear.fs) { cso_delete_fragment_shader(ctx->cso_context, ctx->clear.fs); @@ -252,7 +252,7 @@ static void update_clip_state(struct vg_context *ctx) ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0); /* disable color writes */ - blend->colormask = 0; /*disable colorwrites*/ + blend->rt[0].colormask = 0; /*disable colorwrites*/ cso_set_blend(ctx->cso_context, blend); /* enable scissoring */ @@ -286,7 +286,6 @@ static void update_clip_state(struct vg_context *ctx) renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f); } - blend->colormask = 1; /*enable colorwrites*/ cso_restore_blend(ctx->cso_context); cso_restore_fragment_shader(ctx->cso_context); @@ -301,57 +300,56 @@ void vg_validate_state(struct vg_context *ctx) if ((ctx->state.dirty & BLEND_DIRTY)) { struct pipe_blend_state *blend = &ctx->state.g3d.blend; memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->blend_enable = 1; - blend->colormask |= PIPE_MASK_R; - blend->colormask |= PIPE_MASK_G; - blend->colormask |= PIPE_MASK_B; - blend->colormask |= PIPE_MASK_A; + blend->rt[0].blend_enable = 1; + blend->rt[0].colormask = PIPE_MASK_RGBA; switch (ctx->state.vg.blend_mode) { case VG_BLEND_SRC: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].blend_enable = 0; break; case VG_BLEND_SRC_OVER: - blend->rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; break; case VG_BLEND_DST_OVER: - blend->rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA; break; case VG_BLEND_SRC_IN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; break; case VG_BLEND_DST_IN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ZERO; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA; break; case VG_BLEND_MULTIPLY: case VG_BLEND_SCREEN: case VG_BLEND_DARKEN: case VG_BLEND_LIGHTEN: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend->rt[0].blend_enable = 0; break; case VG_BLEND_ADDITIVE: - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; break; default: assert(!"not implemented blend mode"); @@ -371,20 +369,20 @@ void vg_validate_state(struct vg_context *ctx) 2.f/fb->width, 2.f/fb->height, 1, 1, -1, -1, 0, 0 }; - struct pipe_constant_buffer *cbuf = &ctx->vs_const_buffer; + struct pipe_buffer **cbuf = &ctx->vs_const_buffer; vg_set_viewport(ctx, VEGA_Y0_BOTTOM); - pipe_buffer_reference(&cbuf->buffer, NULL); - cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 16, + pipe_buffer_reference(cbuf, NULL); + *cbuf = pipe_buffer_create(ctx->pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT, param_bytes); - if (cbuf->buffer) { - st_no_flush_pipe_buffer_write(ctx, cbuf->buffer, + if (*cbuf) { + st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, vs_consts); } - ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, cbuf); + ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf); } if ((ctx->state.dirty & VS_DIRTY)) { cso_set_vertex_shader_handle(ctx->cso_context, diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h index ccc8889c8c..bc88c8d139 100644 --- a/src/gallium/state_trackers/vega/vg_context.h +++ b/src/gallium/state_trackers/vega/vg_context.h @@ -50,7 +50,7 @@ struct st_renderbuffer { }; struct st_framebuffer { - VGint init_width, init_height; + VGint width, height; struct st_renderbuffer *strb; struct st_renderbuffer *dsrb; @@ -113,7 +113,7 @@ struct vg_context } clear; struct { - struct pipe_constant_buffer cbuf; + struct pipe_buffer *cbuf; struct pipe_sampler_state sampler; struct vg_shader *union_fs; @@ -135,7 +135,7 @@ struct vg_context struct pipe_sampler_state blend_sampler; struct { - struct pipe_constant_buffer buffer; + struct pipe_buffer *buffer; void *color_matrix_fs; } filter; struct vg_paint *default_paint; @@ -145,7 +145,7 @@ struct vg_context struct vg_shader *plain_vs; struct vg_shader *clear_vs; struct vg_shader *texture_vs; - struct pipe_constant_buffer vs_const_buffer; + struct pipe_buffer *vs_const_buffer; }; struct vg_object { diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c index e503913275..a94dfb160c 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.c +++ b/src/gallium/state_trackers/vega/vg_tracker.c @@ -29,13 +29,16 @@ #include "mask.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_rect.h" +/* advertise OpenVG support */ +PUBLIC const int st_api_OpenVG = 1; + static struct pipe_texture * create_texture(struct pipe_context *pipe, enum pipe_format format, VGint width, VGint height) @@ -190,8 +193,8 @@ struct st_framebuffer * st_create_framebuffer(const void *visual, */ stfb->alpha_mask = 0; - stfb->init_width = width; - stfb->init_height = height; + stfb->width = width; + stfb->height = height; stfb->privateData = privateData; } @@ -279,11 +282,14 @@ void st_resize_framebuffer(struct st_framebuffer *stfb, /* If this is a noop, exit early and don't do the clear, etc below. */ - if (strb->width == width && - strb->height == height && + if (stfb->width == width && + stfb->height == height && state->zsbuf) return; + stfb->width = width; + stfb->height = height; + if (strb->width != width || strb->height != height) st_renderbuffer_alloc_storage(ctx, strb, width, height); @@ -368,14 +374,15 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb) /* FIXME */ } -void st_make_current(struct vg_context *st, - struct st_framebuffer *draw, - struct st_framebuffer *read) +boolean st_make_current(struct vg_context *st, + struct st_framebuffer *draw, + struct st_framebuffer *read) { vg_set_current_context(st); if (st) { st->draw_buffer = draw; } + return VG_TRUE; } struct vg_context *st_get_current(void) @@ -425,3 +432,8 @@ int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level) { return 0; } + +st_proc st_get_proc_address(const char *procname) +{ + return NULL; +} diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h index 0f0c27f455..c1196954a7 100644 --- a/src/gallium/state_trackers/vega/vg_tracker.h +++ b/src/gallium/state_trackers/vega/vg_tracker.h @@ -99,9 +99,9 @@ PUBLIC void st_unreference_framebuffer(struct st_framebuffer *stfb); PUBLIC -void st_make_current(struct vg_context *st, - struct st_framebuffer *draw, - struct st_framebuffer *read); +boolean st_make_current(struct vg_context *st, + struct st_framebuffer *draw, + struct st_framebuffer *read); PUBLIC struct vg_context *st_get_current(void); diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index f2f0264844..0785d2c6b8 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -34,11 +34,6 @@ #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" -#ifdef DEBUG -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#endif - #include "stw_icd.h" #include "stw_device.h" #include "stw_winsys.h" @@ -152,7 +147,6 @@ DrvCreateLayerContext( const struct stw_pixelformat_info *pfi; GLvisual visual; struct stw_context *ctx = NULL; - struct pipe_screen *screen = NULL; struct pipe_context *pipe = NULL; if(!stw_dev) @@ -175,28 +169,12 @@ DrvCreateLayerContext( ctx->hdc = hdc; ctx->iPixelFormat = iPixelFormat; - screen = stw_dev->screen; - -#ifdef DEBUG - /* Unwrap screen */ - if(stw_dev->trace_running) - screen = trace_screen(screen)->screen; -#endif - - pipe = stw_dev->stw_winsys->create_context( screen ); + /* priv == hdc, pass to stw_flush_frontbuffer as context_private + */ + pipe = stw_dev->screen->context_create( stw_dev->screen, hdc ); if (pipe == NULL) goto no_pipe; -#ifdef DEBUG - /* Wrap context */ - if(stw_dev->trace_running) - pipe = trace_context_create(stw_dev->screen, pipe); -#endif - - /* pass to stw_flush_frontbuffer as context_private */ - assert(!pipe->priv); - pipe->priv = hdc; - ctx->st = st_create_context( pipe, &visual, NULL ); if (ctx->st == NULL) goto no_st_ctx; diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h index 0bf3b0da82..a83841f6b7 100644 --- a/src/gallium/state_trackers/wgl/stw_device.h +++ b/src/gallium/state_trackers/wgl/stw_device.h @@ -30,7 +30,7 @@ #include "pipe/p_compiler.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_handle_table.h" #include "stw_icd.h" #include "stw_pixelformat.h" diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c index fb30ec5dba..8dd63f124a 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c +++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c @@ -48,32 +48,8 @@ wglGetGalliumScreenMESA(void) struct pipe_context * APIENTRY wglCreateGalliumContextMESA(void) { - struct pipe_screen *screen = NULL; - struct pipe_context *pipe = NULL; - if(!stw_dev) return NULL; - screen = stw_dev->screen; - -#ifdef DEBUG - /* Unwrap screen */ - if(stw_dev->trace_running) - screen = trace_screen(screen)->screen; -#endif - - pipe = stw_dev->stw_winsys->create_context( screen ); - if (pipe == NULL) - goto no_pipe; - -#ifdef DEBUG - /* Wrap context */ - if(stw_dev->trace_running) - pipe = trace_context_create(stw_dev->screen, pipe); -#endif - - return pipe; - -no_pipe: - return NULL; + return stw_dev->screen->context_create( stw_dev->screen, NULL ); } diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h index b80d168a7c..08cc4973bc 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h @@ -32,7 +32,7 @@ #include "main/mtypes.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" struct pipe_surface; struct stw_pixelformat_info; diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index 54cc361412..7d4c2430b0 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -95,8 +95,6 @@ stw_pf_depth_stencil[] = { { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, { PIPE_FORMAT_X8Z24_UNORM, {24, 0} }, { PIPE_FORMAT_Z16_UNORM, {16, 0} }, - /* pure stencil */ - { PIPE_FORMAT_S8_UNORM, { 0, 8} }, /* combined depth-stencil */ { PIPE_FORMAT_S8Z24_UNORM, {24, 8} }, { PIPE_FORMAT_Z24S8_UNORM, {24, 8} } @@ -220,7 +218,8 @@ stw_pixelformat_init( void ) const struct stw_pf_color_info *color = &stw_pf_color[j]; if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) + PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET, 0)) continue; for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) { diff --git a/src/gallium/state_trackers/wgl/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h index 1de6e906d0..270fad56a1 100644 --- a/src/gallium/state_trackers/wgl/stw_winsys.h +++ b/src/gallium/state_trackers/wgl/stw_winsys.h @@ -43,9 +43,6 @@ struct stw_winsys struct pipe_screen * (*create_screen)( void ); - struct pipe_context * - (*create_context)( struct pipe_screen *screen ); - /** * Present the color buffer to the window associated with the device context. */ diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 1c248a629e..c50873c150 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -4,10 +4,7 @@ #include "xorg_exa_tgsi.h" #include "cso_cache/cso_context.h" -#include "util/u_draw_quad.h" -#include "util/u_math.h" -#include "pipe/p_inlines.h" /*XXX also in Xrender.h but the including it here breaks compilition */ #define XFixedToDouble(f) (((double) (f)) / 65536.) @@ -220,13 +217,13 @@ bind_blend_state(struct exa_context *exa, int op, blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture); memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.rgb_src_factor = blend_opt.rgb_src; - blend.alpha_src_factor = blend_opt.rgb_src; - blend.rgb_dst_factor = blend_opt.rgb_dst; - blend.alpha_dst_factor = blend_opt.rgb_dst; + blend.rt[0].rgb_src_factor = blend_opt.rgb_src; + blend.rt[0].alpha_src_factor = blend_opt.rgb_src; + blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst; + blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst; cso_set_blend(exa->renderer->cso, &blend); } diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c index 650d2c0d1d..221ce772af 100644 --- a/src/gallium/state_trackers/xorg/xorg_crtc.c +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -49,8 +49,7 @@ #include <X11/extensions/dpms.h> #endif -#include "pipe/p_inlines.h" -#include "util/u_format.h" +#include "util/u_inlines.h" #include "util/u_rect.h" #ifdef HAVE_LIBKMS @@ -243,7 +242,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image) unsigned attr[8]; attr[0] = KMS_BO_TYPE; +#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 + attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; +#else attr[1] = KMS_BO_TYPE_CURSOR; +#endif attr[2] = KMS_WIDTH; attr[3] = 64; attr[4] = KMS_HEIGHT; diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index fd82f4fa1d..7457fe1c6d 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -38,15 +38,17 @@ #include "dri2.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" -#include "util/u_rect.h" /* Make all the #if cases in the code esier to read */ -/* XXX can it be set to 1? */ #ifndef DRI2INFOREC_VERSION -#define DRI2INFOREC_VERSION 0 +#define DRI2INFOREC_VERSION 1 +#endif + +#if DRI2INFOREC_VERSION == 2 +static Bool set_format_in_do_create_buffer; #endif typedef struct { @@ -147,7 +149,9 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form buffer->driverPrivate = private; buffer->flags = 0; /* not tiled */ #if DRI2INFOREC_VERSION == 2 - ((DRI2Buffer2Ptr)buffer)->format = 0; + /* ABI forwards/backwards compatibility */ + if (set_format_in_do_create_buffer) + ((DRI2Buffer2Ptr)buffer)->format = 0; #elif DRI2INFOREC_VERSION >= 3 buffer->format = 0; #endif @@ -211,7 +215,9 @@ dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) xfree(buffer); } -#else /* DRI2INFOREC_VERSION < 2 */ +#endif /* DRI2INFOREC_VERSION >= 2 */ + +#if DRI2INFOREC_VERSION <= 2 static DRI2BufferPtr dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count) @@ -261,7 +267,7 @@ dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) } } -#endif /* DRI2INFOREC_VERSION >= 2 */ +#endif /* DRI2INFOREC_VERSION <= 2 */ static void dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, @@ -369,12 +375,19 @@ xorg_dri2_init(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); DRI2InfoRec dri2info; - #if DRI2INFOREC_VERSION >= 2 - dri2info.version = DRI2INFOREC_VERSION; -#else - dri2info.version = 1; + int major, minor; + + if (xf86LoaderCheckSymbol("DRI2Version")) { + DRI2Version(&major, &minor); + } else { + /* Assume version 1.0 */ + major = 1; + minor = 0; + } #endif + + dri2info.version = DRI2INFOREC_VERSION; dri2info.fd = ms->fd; dri2info.driverName = pScrn->driverName; @@ -383,7 +396,22 @@ xorg_dri2_init(ScreenPtr pScreen) #if DRI2INFOREC_VERSION >= 2 dri2info.CreateBuffer = dri2_create_buffer; dri2info.DestroyBuffer = dri2_destroy_buffer; -#else +#endif + + /* For X servers in the 1.6.x series there where two DRI2 version. + * This allows us to build one binary that works on both servers. + */ +#if DRI2INFOREC_VERSION == 2 + if (minor == 0) { + set_format_in_do_create_buffer = FALSE; + dri2info.CreateBuffers = dri2_create_buffers; + dri2info.DestroyBuffers = dri2_destroy_buffers; + } else + set_format_in_do_create_buffer = FALSE; +#endif + + /* For version 1 set these unconditionaly. */ +#if DRI2INFOREC_VERSION == 1 dri2info.CreateBuffers = dri2_create_buffers; dri2info.DestroyBuffers = dri2_destroy_buffers; #endif diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index b02fe68f31..f53a879a14 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -45,7 +45,6 @@ #include "miscstruct.h" #include "dixstruct.h" #include "xf86xv.h" -#include <X11/extensions/Xv.h> #ifndef XSERVER_LIBPCIACCESS #error "libpciaccess needed" #endif @@ -79,11 +78,13 @@ typedef enum { OPTION_SW_CURSOR, OPTION_2D_ACCEL, + OPTION_DEBUG_FALLBACK, } drv_option_enums; static const OptionInfoRec drv_options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -111,6 +112,28 @@ xorg_tracker_set_functions(ScrnInfoPtr scrn) scrn->ValidMode = drv_valid_mode; } +Bool +xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device) +{ + char *BusID = xalloc(64); + sprintf(BusID, "pci:%04x:%02x:%02x.%d", + device->domain, device->bus, + device->dev, device->func); + + if (drmCheckModesettingSupported(BusID)) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "Drm modesetting not supported %s\n", BusID); + xfree(BusID); + return FALSE; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, + "Drm modesetting supported on %s\n", BusID); + + xfree(BusID); + return TRUE; +} + /* * Internal function definitions @@ -206,16 +229,41 @@ drv_init_drm(ScrnInfoPtr pScrn) ms->PciInfo->dev, ms->PciInfo->func ); - ms->fd = drmOpen(NULL, BusID); - if (ms->fd < 0) - return FALSE; + ms->api = drm_api_create(); + ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID); + xfree(BusID); + + if (ms->fd >= 0) + return TRUE; + + if (ms->api && ms->api->destroy) + ms->api->destroy(ms->api); + + ms->api = NULL; + + return FALSE; } return TRUE; } static Bool +drv_close_drm(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + + if (ms->api && ms->api->destroy) + ms->api->destroy(ms->api); + ms->api = NULL; + + drmClose(ms->fd); + ms->fd = -1; + + return TRUE; +} + +static Bool drv_init_resource_management(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); @@ -229,7 +277,6 @@ drv_init_resource_management(ScrnInfoPtr pScrn) if (ms->screen || ms->kms) return TRUE; - ms->api = drm_api_create(); if (ms->api) { ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); @@ -269,10 +316,6 @@ drv_close_resource_management(ScrnInfoPtr pScrn) } ms->screen = NULL; - if (ms->api && ms->api->destroy) - ms->api->destroy(ms->api); - ms->api = NULL; - #ifdef HAVE_LIBKMS if (ms->kms) kms_destroy(&ms->kms); @@ -629,10 +672,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86SetBlackWhitePixels(pScreen); + ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE); + ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE); + if (ms->screen) { - ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options, - OPTION_2D_ACCEL, TRUE)); - ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE); + ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d); xorg_xv_init(pScreen); #ifdef DRI2 @@ -640,6 +684,17 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n", + ms->screen && ms->accelerate_2d ? "enabled" : "disabled"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n", + ms->debug_fallback ? "enabled" : "disabled"); +#ifdef DRI2 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is %s\n", + ms->screen ? "enabled" : "disabled"); +#else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n"); +#endif + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -823,8 +878,7 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen) drv_close_resource_management(pScrn); - drmClose(ms->fd); - ms->fd = -1; + drv_close_drm(pScrn); pScrn->vtSema = FALSE; pScreen->CloseScreen = ms->CloseScreen; @@ -954,7 +1008,11 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn) int ret; attr[0] = KMS_BO_TYPE; +#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8 + attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8; +#else attr[1] = KMS_BO_TYPE_SCANOUT; +#endif attr[2] = KMS_WIDTH; attr[3] = pScrn->virtualX; attr[4] = KMS_HEIGHT; @@ -1012,12 +1070,22 @@ drv_bind_front_buffer_kms(ScrnInfoPtr pScrn) goto err_destroy; pScreen->ModifyPixmapHeader(rootPixmap, - pScreen->width, - pScreen->height, + pScrn->virtualX, + pScrn->virtualY, pScreen->rootDepth, pScrn->bitsPerPixel, stride, ptr); + + /* This a hack to work around EnableDisableFBAccess setting the pointer + * the real fix would be to replace pScrn->EnableDisableFBAccess hook + * and set the rootPixmap->devPrivate.ptr to something valid before that. + * + * But in its infinit visdome something uses either this some times before + * that, so our hook doesn't get called before the crash happens. + */ + pScrn->pixmapPrivate.ptr = ptr; + return TRUE; err_destroy: diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index d9432babf1..ae66c4baa9 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -41,9 +41,7 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" -#include "util/u_format.h" #include "util/u_rect.h" #include "util/u_math.h" #include "util/u_debug.h" @@ -1063,7 +1061,10 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel) } exa->scrn = ms->screen; - exa->pipe = ms->api->create_context(ms->api, exa->scrn); + exa->pipe = exa->scrn->context_create(exa->scrn, NULL); + if (exa->pipe == NULL) + goto out_err; + /* Share context with DRI */ ms->ctx = exa->pipe; diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index bed17caab7..3e5e6bd6a6 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -6,11 +6,9 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "util/u_memory.h" -#include "util/u_simple_shaders.h" #include "tgsi/tgsi_ureg.h" diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c index 251f331ea7..13c3fb97e3 100644 --- a/src/gallium/state_trackers/xorg/xorg_output.c +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -49,8 +49,6 @@ #include <X11/extensions/dpms.h> #endif -#include "X11/Xatom.h" - #include "xorg_tracker.h" static char *output_enum_list[] = { diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index d80f341e6c..83b0d31e38 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -5,12 +5,11 @@ #include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" -#include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_rect.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include <math.h> @@ -379,14 +378,14 @@ struct xorg_renderer * renderer_create(struct pipe_context *pipe) void renderer_destroy(struct xorg_renderer *r) { - struct pipe_constant_buffer *vsbuf = &r->vs_const_buffer; - struct pipe_constant_buffer *fsbuf = &r->fs_const_buffer; + struct pipe_buffer **vsbuf = &r->vs_const_buffer; + struct pipe_buffer **fsbuf = &r->fs_const_buffer; - if (vsbuf && vsbuf->buffer) - pipe_buffer_reference(&vsbuf->buffer, NULL); + if (*vsbuf) + pipe_buffer_reference(vsbuf, NULL); - if (fsbuf && fsbuf->buffer) - pipe_buffer_reference(&fsbuf->buffer, NULL); + if (*fsbuf) + pipe_buffer_reference(fsbuf, NULL); if (r->shaders) { xorg_shaders_destroy(r->shaders); @@ -409,20 +408,20 @@ void renderer_set_constants(struct xorg_renderer *r, const float *params, int param_bytes) { - struct pipe_constant_buffer *cbuf = + struct pipe_buffer **cbuf = (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer : &r->fs_const_buffer; - pipe_buffer_reference(&cbuf->buffer, NULL); - cbuf->buffer = pipe_buffer_create(r->pipe->screen, 16, - PIPE_BUFFER_USAGE_CONSTANT, - param_bytes); + pipe_buffer_reference(cbuf, NULL); + *cbuf = pipe_buffer_create(r->pipe->screen, 16, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); - if (cbuf->buffer) { - pipe_buffer_write(r->pipe->screen, cbuf->buffer, + if (*cbuf) { + pipe_buffer_write(r->pipe->screen, *cbuf, 0, param_bytes, params); } - r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf); + r->pipe->set_constant_buffer(r->pipe, shader_type, 0, *cbuf); } @@ -445,11 +444,11 @@ void renderer_copy_prepare(struct xorg_renderer *r, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].colormask = PIPE_MASK_RGBA; cso_set_blend(r->cso, &blend); } diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h index 5272cde2b3..af6aa0567d 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.h +++ b/src/gallium/state_trackers/xorg/xorg_renderer.h @@ -23,8 +23,8 @@ struct xorg_renderer { int fb_width; int fb_height; - struct pipe_constant_buffer vs_const_buffer; - struct pipe_constant_buffer fs_const_buffer; + struct pipe_buffer *vs_const_buffer; + struct pipe_buffer *fs_const_buffer; float buffer[BUF_SIZE]; int buffer_size; diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h index 4d5d4780dc..58bb60a721 100644 --- a/src/gallium/state_trackers/xorg/xorg_tracker.h +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -47,6 +47,8 @@ #endif #include "pipe/p_screen.h" +#include "util/u_inlines.h" +#include "util/u_debug.h" #include "state_tracker/drm_api.h" #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); @@ -112,6 +114,7 @@ typedef struct _modesettingRec /* exa */ struct exa_context *exa; Bool noEvict; + Bool accelerate_2d; Bool debug_fallback; /* winsys hocks */ diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h index 47ee4b9ffd..865733bca2 100644 --- a/src/gallium/state_trackers/xorg/xorg_winsys.h +++ b/src/gallium/state_trackers/xorg/xorg_winsys.h @@ -45,5 +45,6 @@ void xorg_tracker_set_functions(ScrnInfoPtr scrn); const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid); +Bool xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device); #endif diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index 6b5a41a372..3dcef22c13 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -11,9 +11,6 @@ #include "cso_cache/cso_context.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" - -#include "util/u_format.h" /*XXX get these from pipe's texture limits */ #define IMAGE_MAX_WIDTH 2048 @@ -403,14 +400,14 @@ bind_blend_state(struct xorg_xv_port_priv *port) struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 0; + blend.rt[0].colormask = PIPE_MASK_RGBA; /* porter&duff src */ - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; cso_set_blend(port->r->cso, &blend); } @@ -486,8 +483,11 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, int dxo, dyo; Bool hdtv; int x, y, w, h; - struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap); - struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst); + struct exa_pixmap_priv *dst; + struct pipe_surface *dst_surf = NULL; + + exaMoveInPixmap(pPixmap); + dst = exaGetPixmapDriverPrivate(pPixmap); if (dst && !dst->tex) { xorg_exa_set_shared_usage(pPixmap); @@ -497,6 +497,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, if (!dst || !dst->tex) XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex"); + dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst); hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y)); REGION_TRANSLATE(pScrn->pScreen, dstRegion, -pPixmap->screen_x, @@ -516,7 +517,6 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, bind_samplers(pPriv); setup_fs_video_constants(pPriv->r, hdtv); - exaMoveInPixmap(pPixmap); DamageDamageRegion(&pPixmap->drawable, dstRegion); while (nbox--) { diff --git a/src/gallium/winsys/drm/Makefile.egl b/src/gallium/winsys/drm/Makefile.egl new file mode 100644 index 0000000000..b1f2038550 --- /dev/null +++ b/src/gallium/winsys/drm/Makefile.egl @@ -0,0 +1,62 @@ +# src/gallium/winsys/drm/Makefile.egl + +# The driver Makefile should define +# +# EGL_DRIVER_NAME, the name of the driver +# EGL_DRIVER_SOURCES, the sources of the driver +# EGL_DRIVER_LIBS, extra libraries needed by the driver +# EGL_DRIVER_PIPES, the pipe drivers of the driver +# +# before including this file. + +EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o) + +common_LIBS = -ldrm -lm -ldl + +x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a +x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes + +kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a +kms_LIBS = $(common_LIBS) + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so) + +EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(TOP)/$(LIB_DIR)/$(drv)) + +default: $(EGL_DISPLAY_LIBS) + +$(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/%.so: %.so + $(INSTALL) $< $(TOP)/$(LIB_DIR) + +define mklib-egl +$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \ + -Wl,--whole-archive $($(1)_ST) -Wl,--no-whole-archive \ + $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS) +endef + +egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile + $(call mklib-egl,x11) + +egl_kms_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(kms_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile + $(call mklib-egl,kms) + +clean: + -rm -f $(EGL_DRIVER_OBJECTS) + -rm -f $(EGL_DISPLAY_DRIVERS) + +install: $(EGL_DISPLAY_LIBS) + $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR) + for lib in $(EGL_DISPLAY_LIBS); do \ + $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \ + done + +depend: diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template index 9635c3c50e..960353a73d 100644 --- a/src/gallium/winsys/drm/Makefile.template +++ b/src/gallium/winsys/drm/Makefile.template @@ -82,18 +82,11 @@ SHARED_INCLUDES = \ default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(MKLIB) -noprefix -o $@ \ + $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ $(OBJECTS) $(PIPE_DRIVERS) \ -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \ $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) -$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) - $(MKLIB) -o $(LIBNAME_EGL) \ - -linker "$(CC)" \ - -noprefix \ - $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ - --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS) - $(TOP)/$(LIB_DIR)/gallium: mkdir -p $@ diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile index a1b32eb2a7..1c13258200 100644 --- a/src/gallium/winsys/drm/i965/egl/Makefile +++ b/src/gallium/winsys/drm/i965/egl/Makefile @@ -1,29 +1,14 @@ TOP = ../../../../../.. -GALLIUMDIR = ../../../.. include $(TOP)/configs/current -LIBNAME = EGL_i965.so +EGL_DRIVER_NAME = i965 +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_intel -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \ +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/i965/libi965.a -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -DRIVER_EXTRAS = -ldrm_intel - -ASM_SOURCES = - -DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../../Makefile.template - -symlinks: +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/i965/egl/dummy.c b/src/gallium/winsys/drm/i965/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/i965/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c index fc9678d2b6..a061eef0be 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c @@ -212,11 +212,6 @@ i965_libdrm_create_screen(struct drm_api *api, int drmFD, return brw_create_screen(&idws->base, deviceID); } -static struct pipe_context * -i965_libdrm_create_context(struct drm_api *api, struct pipe_screen *screen) -{ - return brw_create_context(screen); -} static void destroy(struct drm_api *api) @@ -228,7 +223,7 @@ destroy(struct drm_api *api) struct drm_api i965_libdrm_api = { - .create_context = i965_libdrm_create_context, + .name = "i965", .create_screen = i965_libdrm_create_screen, .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle, .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture, diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c index a4a72b372d..07be1df87f 100644 --- a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c +++ b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c @@ -1,6 +1,7 @@ #include "i965_drm_winsys.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "i915_drm.h" #include "intel_bufmgr.h" diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c index d2b9a1ab31..74501eeb16 100644 --- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c +++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c @@ -469,31 +469,12 @@ fail: } -static struct pipe_context * -xlib_create_i965_context( struct pipe_screen *screen, - void *context_private ) -{ - struct pipe_context *pipe; - - pipe = brw_create_context(screen); - if (pipe == NULL) - goto fail; - - pipe->priv = context_private; - return pipe; - -fail: - /* Free stuff here */ - return NULL; -} - struct xm_driver xlib_i965_driver = { .create_pipe_screen = xlib_create_i965_screen, - .create_pipe_context = xlib_create_i965_context, .display_surface = xlib_i965_display_surface }; diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/winsys/drm/i965/xorg/Makefile index d91d0006ef..c25726b0bb 100644 --- a/src/gallium/winsys/drm/i965/xorg/Makefile +++ b/src/gallium/winsys/drm/i965/xorg/Makefile @@ -1,19 +1,25 @@ -TARGET = modesetting_drv.so -CFILES = $(wildcard ./*.c) -OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) TOP = ../../../../../.. -include $(TOP)/configs/current -INCLUDES = \ - $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ - -I../gem \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main +GALLIUMDIR = $(TOP)/src/gallium + +TARGET = i965g_drv.so + +CFILES = $(wildcard ./*.c) + +include ${TOP}/configs/current + +OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) + +CFLAGS = -DHAVE_CONFIG_H \ + -g -Wall -Wimplicit-function-declaration -fPIC \ + $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ + -I${GALLIUMDIR}/include \ + -I${GALLIUMDIR}/drivers \ + -I${GALLIUMDIR}/auxiliary \ + -I${TOP}/src/mesa \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ @@ -23,20 +29,21 @@ LIBS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(GALLIUM_AUXILIARIES) -DRIVER_DEFINES = \ - -DHAVE_CONFIG_H - - +TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET) ############################################# +all default: $(TARGET) $(TARGET_STAGING) - -all default: $(TARGET) - -$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS) +$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS) $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel +$(TOP)/$(LIB_DIR)/gallium: + mkdir -p $@ + +$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium + $(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium + clean: rm -rf $(OBJECTS) $(TARGET) @@ -44,14 +51,4 @@ install: $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR) - -############################################## - - -.c.o: - $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@ - - -############################################## - .PHONY = all clean install diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile index 1397e9f729..60d675ca73 100644 --- a/src/gallium/winsys/drm/intel/egl/Makefile +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -1,29 +1,14 @@ TOP = ../../../../../.. -GALLIUMDIR = ../../../.. include $(TOP)/configs/current -LIBNAME = EGL_i915.so +EGL_DRIVER_NAME = i915 +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_intel -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/i915/libi915.a -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -DRIVER_EXTRAS = -ldrm_intel - -ASM_SOURCES = - -DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../../Makefile.template - -symlinks: +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/winsys/drm/intel/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c index 5ed2a10af1..377ed25513 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c @@ -1,3 +1,4 @@ +#include <stdio.h> #include "state_tracker/drm_api.h" @@ -175,18 +176,11 @@ intel_drm_create_screen(struct drm_api *api, int drmFD, idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size); drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem); - idws->softpipe = FALSE; idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE); return i915_create_screen(&idws->base, deviceID); } -static struct pipe_context * -intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen) -{ - return i915_create_context(screen); -} - static void destroy(struct drm_api *api) { @@ -195,7 +189,8 @@ destroy(struct drm_api *api) struct drm_api intel_drm_api = { - .create_context = intel_drm_create_context, + .name = "i915", + .driver_name = "i915", .create_screen = intel_drm_create_screen, .texture_from_shared_handle = intel_drm_texture_from_shared_handle, .shared_handle_from_texture = intel_drm_shared_handle_from_texture, diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c index e8b58742ab..102faedfea 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c @@ -1,7 +1,8 @@ #include "intel_drm_winsys.h" #include "util/u_memory.h" -#include "pipe/p_refcnt.h" +#include "util/u_atomic.h" +#include "util/u_inlines.h" /** * Because gem does not have fence's we have to create our own fences. diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h index b4a60563ef..9786ee9365 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h +++ b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h @@ -17,7 +17,6 @@ struct intel_drm_winsys { struct intel_winsys base; - boolean softpipe; boolean dump_cmd; int fd; /**< Drm file discriptor */ diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index 0937f68c34..7e95f79d03 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -6,9 +6,6 @@ LIBNAME = nouveau_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.a \ - $(TOP)/src/gallium/drivers/nv10/libnv10.a \ - $(TOP)/src/gallium/drivers/nv20/libnv20.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a \ diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index e5912ef77f..c814d986b1 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -2,6 +2,7 @@ #include "pipe/p_state.h" #include "util/u_format.h" #include "util/u_memory.h" +#include "util/u_inlines.h" #include "nouveau_drm_api.h" @@ -54,6 +55,15 @@ static struct dri1_api nouveau_dri1_api = { nouveau_dri1_front_surface, }; +static void +nouveau_drm_destroy_winsys(struct pipe_winsys *s) +{ + struct nouveau_winsys *nv_winsys = nouveau_winsys(s); + struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen); + nouveau_device_close(&nv_screen->device); + FREE(nv_winsys); +} + static struct pipe_screen * nouveau_drm_create_screen(struct drm_api *api, int fd, struct drm_create_screen_arg *arg) @@ -71,15 +81,6 @@ nouveau_drm_create_screen(struct drm_api *api, int fd, return NULL; switch (dev->chipset & 0xf0) { - case 0x00: - init = nv04_screen_create; - break; - case 0x10: - init = nv10_screen_create; - break; - case 0x20: - init = nv20_screen_create; - break; case 0x30: init = nv30_screen_create; break; @@ -105,6 +106,7 @@ nouveau_drm_create_screen(struct drm_api *api, int fd, return NULL; } ws = &nvws->base; + ws->destroy = nouveau_drm_destroy_winsys; nvws->pscreen = init(ws, dev); if (!nvws->pscreen) { @@ -140,58 +142,6 @@ nouveau_drm_create_screen(struct drm_api *api, int fd, return nvws->pscreen; } -static struct pipe_context * -nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen) -{ - struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen); - struct pipe_context *(*init)(struct pipe_screen *, unsigned); - unsigned chipset = nouveau_screen(pscreen)->device->chipset; - int i; - - switch (chipset & 0xf0) { - case 0x00: - init = nv04_create; - break; - case 0x10: - init = nv10_create; - break; - case 0x20: - init = nv20_create; - break; - case 0x30: - init = nv30_create; - break; - case 0x40: - case 0x60: - init = nv40_create; - break; - case 0x50: - case 0x80: - case 0x90: - case 0xa0: - init = nv50_create; - break; - default: - debug_printf("%s: unknown chipset nv%02x\n", __func__, chipset); - return NULL; - } - - /* Find a free slot for a pipe context, allocate a new one if needed */ - for (i = 0; i < nvws->nr_pctx; i++) { - if (nvws->pctx[i] == NULL) - break; - } - - if (i == nvws->nr_pctx) { - nvws->nr_pctx++; - nvws->pctx = realloc(nvws->pctx, - sizeof(*nvws->pctx) * nvws->nr_pctx); - } - - nvws->pctx[i] = init(pscreen, i); - return nvws->pctx[i]; -} - static struct pipe_texture * nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen, struct pipe_texture *templ, const char *name, @@ -254,8 +204,9 @@ nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen, } struct drm_api drm_api_hooks = { + .name = "nouveau", + .driver_name = "nouveau", .create_screen = nouveau_drm_create_screen, - .create_context = nouveau_drm_create_context, .texture_from_shared_handle = nouveau_drm_pt_from_name, .shared_handle_from_texture = nouveau_drm_name_from_pt, .local_handle_from_texture = nouveau_drm_handle_from_pt, diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index e61e0e0957..a91aad7df8 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -4,7 +4,7 @@ #include "state_tracker/drm_api.h" #include "state_tracker/dri1_api.h" -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "nouveau_dri.h" @@ -13,9 +13,6 @@ struct nouveau_winsys { struct pipe_screen *pscreen; - unsigned nr_pctx; - struct pipe_context **pctx; - struct pipe_surface *front; }; diff --git a/src/gallium/winsys/drm/nouveau/egl/Makefile b/src/gallium/winsys/drm/nouveau/egl/Makefile new file mode 100644 index 0000000000..2c35260332 --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/egl/Makefile @@ -0,0 +1,16 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = nouveau +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_nouveau + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ + $(TOP)/src/gallium/drivers/nv30/libnv30.a \ + $(TOP)/src/gallium/drivers/nv40/libnv40.a \ + $(TOP)/src/gallium/drivers/nv50/libnv50.a \ + $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/nouveau/egl/dummy.c b/src/gallium/winsys/drm/nouveau/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/nouveau/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile index f0d3b337e8..179b50230b 100644 --- a/src/gallium/winsys/drm/nouveau/xorg/Makefile +++ b/src/gallium/winsys/drm/nouveau/xorg/Makefile @@ -18,9 +18,6 @@ INCLUDES = \ LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.a \ - $(TOP)/src/gallium/drivers/nv10/libnv10.a \ - $(TOP)/src/gallium/drivers/nv20/libnv20.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a \ diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 385fa857b5..3b1c3860a4 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -33,7 +33,6 @@ #include "radeon_buffer.h" #include "radeon_bo_gem.h" -#include "softpipe/sp_texture.h" #include "r300_context.h" #include "util/u_format.h" #include "util/u_math.h" @@ -51,6 +50,26 @@ static const char *radeon_get_name(struct pipe_winsys *ws) return "Radeon/GEM+KMS"; } +static uint32_t radeon_domain_from_usage(unsigned usage) +{ + uint32_t domain = 0; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + return domain; +} + static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, unsigned alignment, unsigned usage, @@ -58,6 +77,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, { struct radeon_winsys *radeon_ws = (struct radeon_winsys *)ws; struct radeon_pipe_buffer *radeon_buffer; + struct pb_desc desc; uint32_t domain; radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer); @@ -70,18 +90,16 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, radeon_buffer->base.usage = usage; radeon_buffer->base.size = size; - domain = 0; - - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; + if (usage & PIPE_BUFFER_USAGE_CONSTANT && is_r3xx(radeon_ws->pci_id)) { + /* Don't bother allocating a BO, as it'll never get to the card. */ + desc.alignment = alignment; + desc.usage = usage; + radeon_buffer->pb = pb_malloc_buffer_create(size, &desc); + return &radeon_buffer->base; } + domain = radeon_domain_from_usage(usage); + radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size, alignment, domain, 0); if (radeon_buffer->bo == NULL) { @@ -133,8 +151,16 @@ static void radeon_buffer_del(struct pipe_buffer *buffer) struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; - radeon_bo_unref(radeon_buffer->bo); - free(radeon_buffer); + if (radeon_buffer->pb) { + pipe_reference_init(&radeon_buffer->pb->base.reference, 0); + pb_destroy(radeon_buffer->pb); + } + + if (radeon_buffer->bo) { + radeon_bo_unref(radeon_buffer->bo); + } + + FREE(radeon_buffer); } static void *radeon_buffer_map(struct pipe_winsys *ws, @@ -146,6 +172,10 @@ static void *radeon_buffer_map(struct pipe_winsys *ws, (struct radeon_pipe_buffer*)buffer; int write = 0; + if (radeon_buffer->pb) { + return pb_map(radeon_buffer->pb, flags); + } + if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { uint32_t domain; @@ -174,7 +204,31 @@ static void radeon_buffer_unmap(struct pipe_winsys *ws, struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; - radeon_bo_unmap(radeon_buffer->bo); + if (radeon_buffer->pb) { + pb_unmap(radeon_buffer->pb); + } else { + radeon_bo_unmap(radeon_buffer->bo); + } +} + +static void radeon_buffer_set_tiling(struct radeon_winsys *ws, + struct pipe_buffer *buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled) +{ + struct radeon_pipe_buffer *radeon_buffer = + (struct radeon_pipe_buffer*)buffer; + uint32_t flags = 0; + + if (microtiled) { + flags |= RADEON_BO_FLAGS_MICRO_TILE; + } + if (macrotiled) { + flags |= RADEON_BO_FLAGS_MACRO_TILE; + } + + radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch); } static void radeon_fence_reference(struct pipe_winsys *ws, @@ -197,55 +251,6 @@ static int radeon_fence_finish(struct pipe_winsys *ws, return 0; } -static void radeon_display_surface(struct pipe_winsys *pws, - struct pipe_surface *psurf, - struct radeon_vl_context *rvl_ctx) -{ - struct r300_texture *r300tex = (struct r300_texture *)(psurf->texture); - XImage *ximage; - void *data; - - ximage = XCreateImage(rvl_ctx->display, - XDefaultVisual(rvl_ctx->display, rvl_ctx->screen), - XDefaultDepth(rvl_ctx->display, rvl_ctx->screen), - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - - assert(ximage->format); - assert(ximage->bitmap_unit); - - data = pws->buffer_map(pws, r300tex->buffer, 0); - - /* update XImage's fields */ - ximage->data = data; - ximage->width = psurf->width; - ximage->height = psurf->height; - ximage->bytes_per_line = psurf->width * (ximage->bits_per_pixel >> 3); - - XPutImage(rvl_ctx->display, rvl_ctx->drawable, - XDefaultGC(rvl_ctx->display, rvl_ctx->screen), - ximage, 0, 0, 0, 0, psurf->width, psurf->height); - - XSync(rvl_ctx->display, 0); - - ximage->data = NULL; - XDestroyImage(ximage); - - pws->buffer_unmap(pws, r300tex->buffer); -} - -static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, - struct pipe_surface *pipe_surface, - void *context_private) -{ - struct radeon_vl_context *rvl_ctx; - rvl_ctx = (struct radeon_vl_context *) context_private; - radeon_display_surface(pipe_winsys, pipe_surface, rvl_ctx); -} - struct radeon_winsys* radeon_pipe_winsys(int fd) { struct radeon_winsys* radeon_ws; @@ -264,7 +269,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd) radeon_ws->priv->fd = fd; radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd); - radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer; + radeon_ws->base.flush_frontbuffer = NULL; /* overriden by co-state tracker */ radeon_ws->base.buffer_create = radeon_buffer_create; radeon_ws->base.user_buffer_create = radeon_buffer_user_create; @@ -279,5 +284,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd) radeon_ws->base.get_name = radeon_get_name; + radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling; + return radeon_ws; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index d7f17564a9..f1c8fc2a3b 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -32,11 +32,11 @@ #include <stdio.h> -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" -//#include "state_tracker/st_public.h" +#include "pipebuffer/pb_buffer.h" #include "util/u_memory.h" @@ -49,7 +49,10 @@ struct radeon_pipe_buffer { struct pipe_buffer base; + /* Pointer to GPU-backed BO. */ struct radeon_bo *bo; + /* Pointer to fallback PB buffer. */ + struct pb_buffer *pb; boolean flinked; uint32_t flink; }; diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c index 05194fc52a..0c0e118ba3 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c @@ -29,8 +29,6 @@ * Joakim Sindholt <opensource@zhasha.com> */ -#include "softpipe/sp_winsys.h" - #include "radeon_drm.h" /* Helper function to do the ioctls needed for setup and init. */ @@ -40,12 +38,16 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys) struct drm_radeon_info info = {0}; int target = 0; int retval; + drmVersionPtr version; info.value = (unsigned long)⌖ /* We do things in a specific order here. * - * First, the PCI ID. This is essential and should return usable numbers + * DRM version first. We need to be sure we're running on a KMS chipset. + * This is also for some features. + * + * Then, the PCI ID. This is essential and should return usable numbers * for all Radeons. If this fails, we probably got handed an FD for some * non-Radeon card. * @@ -55,8 +57,18 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys) * * The GEM info is actually bogus on the kernel side, as well as our side * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because - * we don't actually use the info for anything yet. - * XXX update the above when we can safely use vram_size instead of vram_visible */ + * we don't actually use the info for anything yet. */ + + version = drmGetVersion(fd); + if (version->version_major != 2) { + fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " + "only compatible with 2.x.x\n", __FUNCTION__, + version->version_major, version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + exit(1); + } + info.request = RADEON_INFO_DEVICE_ID; retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { @@ -92,16 +104,18 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys) exit(1); } winsys->gart_size = gem_info.gart_size; - /* XXX */ - winsys->vram_size = gem_info.vram_visible; -} - -/* Guess at whether this chipset should use r300g. - * - * I believe that this check is valid, but I haven't been exhaustive. */ -static boolean is_r3xx(int pciid) -{ - return (pciid > 0x3150) && (pciid < 0x796f); + winsys->vram_size = gem_info.vram_size; + + debug_printf("radeon: Successfully grabbed chipset info from kernel!\n" + "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n" + "radeon: GART size: %d MB VRAM size: %d MB\n", + version->version_major, version->version_minor, + version->version_patchlevel, winsys->pci_id, + winsys->gb_pipes, winsys->z_pipes, + winsys->gart_size / 1024 / 1024, + winsys->vram_size / 1024 / 1024); + + drmFreeVersion(version); } /* Create a pipe_screen. */ @@ -112,36 +126,27 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB); do_ioctls(drmFB, rwinsys); - if (!is_r3xx(rwinsys->pci_id) || - debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) { - return softpipe_create_screen((struct pipe_winsys*)rwinsys); - } else { + /* The state tracker can organize a softpipe fallback if no hw + * driver is found. + */ + if (is_r3xx(rwinsys->pci_id)) { radeon_setup_winsys(drmFB, rwinsys); return r300_create_screen(rwinsys); - } -} - -/* Create a pipe_context. */ -struct pipe_context* radeon_create_context(struct drm_api* api, - struct pipe_screen* screen) -{ - struct radeon_winsys* rwinsys = (struct radeon_winsys*)screen->winsys; - - if (!is_r3xx(rwinsys->pci_id) || - debug_get_bool_option("RADEON_SOFTPIPE", FALSE)) { - return softpipe_create(screen); } else { - return r300_create_context(screen, rwinsys); + FREE(rwinsys); + return NULL; } } + boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_screen* screen, struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride) { /* XXX fix this */ - return r300_get_texture_buffer(texture, buffer, stride); + return r300_get_texture_buffer(screen, texture, buffer, stride); } /* Create a buffer from a handle. */ @@ -208,7 +213,7 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api, struct radeon_pipe_buffer* radeon_buffer; struct pipe_buffer *buffer = NULL; - if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) { + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } @@ -240,7 +245,7 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, unsigned *handle) { struct pipe_buffer *buffer = NULL; - if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) { + if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) { return FALSE; } @@ -251,12 +256,19 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api, return TRUE; } +static void radeon_drm_api_destroy(struct drm_api *api) +{ + return; +} + struct drm_api drm_api_hooks = { + .name = "radeon", + .driver_name = "radeon", .create_screen = radeon_create_screen, - .create_context = radeon_create_context, .texture_from_shared_handle = radeon_texture_from_shared_handle, .shared_handle_from_texture = radeon_shared_handle_from_texture, .local_handle_from_texture = radeon_local_handle_from_texture, + .destroy = radeon_drm_api_destroy, }; struct drm_api* drm_api_create() diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index bf0e78138d..8d74cbafc2 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -52,10 +52,9 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB, struct drm_create_screen_arg *arg); -struct pipe_context* radeon_create_context(struct drm_api* api, - struct pipe_screen* screen); boolean radeon_buffer_from_texture(struct drm_api* api, + struct pipe_screen* screen, struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); @@ -76,4 +75,13 @@ boolean radeon_global_handle_from_buffer(struct drm_api* api, unsigned* handle); void radeon_destroy_drm_api(struct drm_api* api); + +/* Guess at whether this chipset should use r300g. + * + * I believe that this check is valid, but I haven't been exhaustive. */ +static INLINE boolean is_r3xx(int pciid) +{ + return (pciid > 0x3150) && (pciid < 0x796f); +} + #endif diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 0875ee41cb..d759beaba1 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -81,9 +81,13 @@ static void radeon_write_cs_reloc(struct radeon_winsys* winsys, uint32_t flags) { int retval = 0; + struct radeon_pipe_buffer* radeon_buffer = + (struct radeon_pipe_buffer*)pbuffer; - retval = radeon_cs_write_reloc(winsys->priv->cs, - ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); + assert(!radeon_buffer->pb); + + retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, + rd, wd, flags); if (retval) { debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", @@ -108,6 +112,11 @@ static void radeon_flush_cs(struct radeon_winsys* winsys) { int retval; + /* Don't flush a zero-sized CS. */ + if (!winsys->priv->cs->cdw) { + return; + } + /* Emit the CS. */ retval = radeon_cs_emit(winsys->priv->cs); if (retval) { diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index 9edc9e038c..4901080ca7 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -30,7 +30,7 @@ #ifndef RADEON_WINSYS_H #define RADEON_WINSYS_H -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" struct radeon_winsys_priv; @@ -100,6 +100,12 @@ struct radeon_winsys { void (*flush_cb)(void *), void *data); void (*reset_bos)(struct radeon_winsys *winsys); + + void (*buffer_set_tiling)(struct radeon_winsys* winsys, + struct pipe_buffer* buffer, + uint32_t pitch, + boolean microtiled, + boolean macrotiled); }; #endif diff --git a/src/gallium/winsys/drm/radeon/dri/Makefile b/src/gallium/winsys/drm/radeon/dri/Makefile index a9889444de..eaa3418032 100644 --- a/src/gallium/winsys/drm/radeon/dri/Makefile +++ b/src/gallium/winsys/drm/radeon/dri/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../../.. include $(TOP)/configs/current -LIBNAME = radeon_dri.so +LIBNAME = radeong_dri.so MINIGLX_SOURCES = diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile index 6a1448d1b9..cd4f9b20f0 100644 --- a/src/gallium/winsys/drm/radeon/egl/Makefile +++ b/src/gallium/winsys/drm/radeon/egl/Makefile @@ -1,26 +1,14 @@ TOP = ../../../../../.. -GALLIUMDIR = ../../../.. include $(TOP)/configs/current -LIBNAME = EGL_r300.so +EGL_DRIVER_NAME = radeon +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -ldrm_radeon -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ - $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \ +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/r300/libr300.a -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -DRIVER_EXTRAS = -ldrm_radeon - -ASM_SOURCES = - -include ../../Makefile.template - -symlinks: +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/winsys/drm/radeon/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c index c3ec24aaf7..fc63081a4c 100644 --- a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c +++ b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c @@ -124,17 +124,9 @@ error: } -static struct pipe_context * -radeon_hardpipe_context_create(struct pipe_screen *screen) -{ - /* FIXME: create a radon pipe_context from screen */ - - return NULL; -} const struct st_winsys st_hardpipe_winsys = { &radeon_hardpipe_screen_create, - &radeon_hardpipe_context_create, }; diff --git a/src/gallium/winsys/drm/swrast/Makefile b/src/gallium/winsys/drm/swrast/Makefile new file mode 100644 index 0000000000..363b89584f --- /dev/null +++ b/src/gallium/winsys/drm/swrast/Makefile @@ -0,0 +1,12 @@ +# src/gallium/winsys/drm/swrast/Makefile +TOP = ../../../../.. +include $(TOP)/configs/current + +SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS) + +default install clean: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $@) || exit 1; \ + fi \ + done diff --git a/src/gallium/winsys/drm/swrast/core/Makefile b/src/gallium/winsys/drm/swrast/core/Makefile new file mode 100644 index 0000000000..93931ae22b --- /dev/null +++ b/src/gallium/winsys/drm/swrast/core/Makefile @@ -0,0 +1,10 @@ +# src/gallium/winsys/drm/swrast/core/Makefile + +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = swrastdrm + +C_SOURCES = swrast_drm_api.c + +include ../../../../Makefile.template diff --git a/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c b/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c new file mode 100644 index 0000000000..8c9f80e2c1 --- /dev/null +++ b/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c @@ -0,0 +1,13 @@ +#include "state_tracker/drm_api.h" + +static struct drm_api swrast_drm_api = +{ + .name = "swrast", +}; + +struct drm_api * +drm_api_create() +{ + (void) swrast_drm_api; + return NULL; +} diff --git a/src/gallium/winsys/drm/swrast/egl/Makefile b/src/gallium/winsys/drm/swrast/egl/Makefile new file mode 100644 index 0000000000..26fe2d2805 --- /dev/null +++ b/src/gallium/winsys/drm/swrast/egl/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +EGL_DRIVER_NAME = swrast +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = + +EGL_DRIVER_PIPES = \ + $(TOP)/src/gallium/winsys/drm/swrast/core/libswrastdrm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a + +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/swrast/egl/dummy.c b/src/gallium/winsys/drm/swrast/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/swrast/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c index b812fb59d3..eca174a6c5 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.c @@ -41,7 +41,7 @@ #include "svga_cmd.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" #include "pipebuffer/pb_buffer.h" #include "pipebuffer/pb_bufmgr.h" diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h index 634bdcabd2..41fb4476da 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h +++ b/src/gallium/winsys/drm/vmware/core/vmw_buffer.h @@ -27,7 +27,7 @@ #ifndef VMW_BUFFER_H_ #define VMW_BUFFER_H_ - +#include <assert.h> #include "pipe/p_compiler.h" struct SVGAGuestPtr; diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/drm/vmware/core/vmw_context.c index b6997588de..90ffc4868f 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_context.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_context.c @@ -41,9 +41,18 @@ #define VMW_COMMAND_SIZE (64*1024) #define VMW_SURFACE_RELOCS (1024) +#define VMW_REGION_RELOCS (512) #define VMW_MUST_FLUSH_STACK 8 +struct vmw_region_relocation +{ + struct SVGAGuestPtr *where; + struct pb_buffer *buffer; + /* TODO: put offset info inside where */ + uint32 offset; +}; + struct vmw_svga_winsys_context { struct svga_winsys_context base; @@ -69,10 +78,31 @@ struct vmw_svga_winsys_context uint32_t staged; uint32_t reserved; } surface; + + struct { + struct vmw_region_relocation relocs[VMW_REGION_RELOCS]; + uint32_t size; + uint32_t used; + uint32_t staged; + uint32_t reserved; + } region; struct pb_validate *validate; uint32_t last_fence; + + /** + * The amount of GMR that is referred by the commands currently batched + * in the context. + */ + uint32_t seen_regions; + + /** + * Whether this context should fail to reserve more commands, not because it + * ran out of command space, but because a substantial ammount of GMR was + * referred. + */ + boolean preemptive_flush; }; @@ -96,6 +126,19 @@ vmw_swc_flush(struct svga_winsys_context *swc, ret = pb_validate_validate(vswc->validate); assert(ret == PIPE_OK); if(ret == PIPE_OK) { + + /* Apply relocations */ + for(i = 0; i < vswc->region.used; ++i) { + struct vmw_region_relocation *reloc = &vswc->region.relocs[i]; + struct SVGAGuestPtr ptr; + + if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr)) + assert(0); + + ptr.offset += reloc->offset; + + *reloc->where = ptr; + } if (vswc->command.used) vmw_ioctl_command(vswc->vws, @@ -121,9 +164,18 @@ vmw_swc_flush(struct svga_winsys_context *swc, vswc->surface.used = 0; vswc->surface.reserved = 0; + for(i = 0; i < vswc->region.used + vswc->region.staged; ++i) { + pb_reference(&vswc->region.relocs[i].buffer, NULL); + } + + vswc->region.used = 0; + vswc->region.reserved = 0; + #ifdef DEBUG vswc->must_flush = FALSE; #endif + vswc->preemptive_flush = FALSE; + vswc->seen_regions = 0; if(pfence) *pfence = fence; @@ -151,8 +203,10 @@ vmw_swc_reserve(struct svga_winsys_context *swc, if(nr_bytes > vswc->command.size) return NULL; - if(vswc->command.used + nr_bytes > vswc->command.size || - vswc->surface.used + nr_relocs > vswc->surface.size) { + if(vswc->preemptive_flush || + vswc->command.used + nr_bytes > vswc->command.size || + vswc->surface.used + nr_relocs > vswc->surface.size || + vswc->region.used + nr_relocs > vswc->region.size) { #ifdef DEBUG vswc->must_flush = TRUE; debug_backtrace_capture(vswc->must_flush_stack, 1, @@ -163,11 +217,14 @@ vmw_swc_reserve(struct svga_winsys_context *swc, assert(vswc->command.used + nr_bytes <= vswc->command.size); assert(vswc->surface.used + nr_relocs <= vswc->surface.size); - + assert(vswc->region.used + nr_relocs <= vswc->region.size); + vswc->command.reserved = nr_bytes; vswc->surface.reserved = nr_relocs; vswc->surface.staged = 0; - + vswc->region.reserved = nr_relocs; + vswc->region.staged = 0; + return vswc->command.buffer + vswc->command.used; } @@ -206,20 +263,41 @@ vmw_swc_region_relocation(struct svga_winsys_context *swc, unsigned flags) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); - struct SVGAGuestPtr ptr; - struct pb_buffer *buf = vmw_pb_buffer(buffer); + struct vmw_region_relocation *reloc; enum pipe_error ret; + + assert(vswc->region.staged < vswc->region.reserved); - if(!vmw_gmr_bufmgr_region_ptr(buf, &ptr)) - assert(0); - - ptr.offset += offset; + reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged]; + reloc->where = where; + pb_reference(&reloc->buffer, vmw_pb_buffer(buffer)); + reloc->offset = offset; - *where = ptr; + ++vswc->region.staged; - ret = pb_validate_add_buffer(vswc->validate, buf, flags); + ret = pb_validate_add_buffer(vswc->validate, reloc->buffer, flags); /* TODO: Update pipebuffer to reserve buffers and not fail here */ assert(ret == PIPE_OK); + + /* + * Flush preemptively the FIFO commands to keep the GMR working set within + * the GMR pool size. + * + * This is necessary for applications like SPECviewperf that generate huge + * amounts of immediate vertex data, so that we don't pile up too much of + * that vertex data neither in the guest nor in the host. + * + * Note that in the current implementation if a region is referred twice in + * a command stream, it will be accounted twice. We could detect repeated + * regions and count only once, but there is no incentive to do that, since + * regions are typically short-lived; always referred in a single command; + * and at the worst we just flush the commands a bit sooner, which for the + * SVGA virtual device it's not a performance issue since flushing commands + * to the FIFO won't cause flushing in the host. + */ + vswc->seen_regions += reloc->buffer->base.size; + if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/2) + vswc->preemptive_flush = TRUE; } @@ -238,6 +316,12 @@ vmw_swc_commit(struct svga_winsys_context *swc) vswc->surface.used += vswc->surface.staged; vswc->surface.staged = 0; vswc->surface.reserved = 0; + + assert(vswc->region.staged <= vswc->region.reserved); + assert(vswc->region.used + vswc->region.staged <= vswc->region.size); + vswc->region.used += vswc->region.staged; + vswc->region.staged = 0; + vswc->region.reserved = 0; } @@ -246,6 +330,11 @@ vmw_swc_destroy(struct svga_winsys_context *swc) { struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc); unsigned i; + + for(i = 0; i < vswc->region.used; ++i) { + pb_reference(&vswc->region.relocs[i].buffer, NULL); + } + for(i = 0; i < vswc->surface.used; ++i) { p_atomic_dec(&vswc->surface.handles[i]->validated); vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL); @@ -279,6 +368,7 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws) vswc->command.size = VMW_COMMAND_SIZE; vswc->surface.size = VMW_SURFACE_RELOCS; + vswc->region.size = VMW_REGION_RELOCS; vswc->validate = pb_validate_create(); if(!vswc->validate) { @@ -290,8 +380,3 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws) } -struct pipe_context * -vmw_svga_context_create(struct pipe_screen *screen) -{ - return svga_context_create(screen); -} diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.h b/src/gallium/winsys/drm/vmware/core/vmw_context.h index 305ce9b5be..d4884d24e9 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_context.h +++ b/src/gallium/winsys/drm/vmware/core/vmw_context.h @@ -52,8 +52,5 @@ struct pipe_screen; struct svga_winsys_context * vmw_svga_winsys_context_create(struct svga_winsys_screen *sws); -struct pipe_context * -vmw_svga_context_create(struct pipe_screen *screen); - #endif /* VMW_CONTEXT_H_ */ diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.c b/src/gallium/winsys/drm/vmware/core/vmw_screen.c index 911eec5e25..6cc9b38293 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.c @@ -37,13 +37,16 @@ * module. */ struct vmw_winsys_screen * -vmw_winsys_create( int fd ) +vmw_winsys_create( int fd, boolean use_old_scanout_flag ) { struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen); if (!vws) goto out_no_vws; vws->ioctl.drm_fd = fd; + vws->use_old_scanout_flag = use_old_scanout_flag; + debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__, + use_old_scanout_flag ? "true" : "false"); if (!vmw_ioctl_init(vws)) goto out_no_ioctl; diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/drm/vmware/core/vmw_screen.h index a875107370..d3f2c2c7f5 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen.h +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.h @@ -40,6 +40,10 @@ #include "svga_winsys.h" + +#define VMW_GMR_POOL_SIZE (16*1024*1024) + + struct pb_manager; struct vmw_region; @@ -48,6 +52,8 @@ struct vmw_winsys_screen { struct svga_winsys_screen base; + boolean use_old_scanout_flag; + struct { volatile uint32_t *fifo_map; uint64_t last_fence; @@ -127,7 +133,7 @@ boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws); void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws); void vmw_pools_cleanup(struct vmw_winsys_screen *vws); -struct vmw_winsys_screen *vmw_winsys_create(int fd); +struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag); void vmw_winsys_destroy(struct vmw_winsys_screen *sws); diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c index 5995eee34b..1dcbc419db 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c @@ -25,8 +25,9 @@ #include "pipe/p_compiler.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_memory.h" +#include "util/u_format.h" #include "vmw_screen.h" #include "trace/tr_drm.h" @@ -49,7 +50,8 @@ static struct dri1_api_version ddx_compat = { 0, 0, 0 }; static struct dri1_api_version dri_required = { 4, 0, 0 }; static struct dri1_api_version dri_compat = { 4, 0, 0 }; static struct dri1_api_version drm_required = { 0, 1, 0 }; -static struct dri1_api_version drm_compat = { 0, 0, 0 }; +static struct dri1_api_version drm_compat = { 1, 0, 0 }; +static struct dri1_api_version drm_scanout = { 0, 9, 0 }; static boolean vmw_dri1_check_version(const struct dri1_api_version *cur, @@ -84,6 +86,29 @@ vmw_drm_create_screen(struct drm_api *drm_api, struct vmw_winsys_screen *vws; struct pipe_screen *screen; struct dri1_create_screen_arg *dri1; + boolean use_old_scanout_flag = FALSE; + + if (!arg || arg->mode == DRM_CREATE_NORMAL) { + struct dri1_api_version drm_ver; + drmVersionPtr ver; + + ver = drmGetVersion(fd); + if (ver == NULL) + return NULL; + + drm_ver.major = ver->version_major; + drm_ver.minor = ver->version_minor; + drm_ver.patch_level = 0; /* ??? */ + + drmFreeVersion(ver); + if (!vmw_dri1_check_version(&drm_ver, &drm_required, + &drm_compat, "vmwgfx drm driver")) + return NULL; + + if (!vmw_dri1_check_version(&drm_ver, &drm_scanout, + &drm_compat, "use old scanout field (not a error)")) + use_old_scanout_flag = TRUE; + } if (arg != NULL) { switch (arg->mode) { @@ -100,6 +125,9 @@ vmw_drm_create_screen(struct drm_api *drm_api, if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required, &drm_compat, "vmwgfx drm driver")) return NULL; + if (!vmw_dri1_check_version(&dri1->drm_version, &drm_scanout, + &drm_compat, "use old scanout field (not a error)")) + use_old_scanout_flag = TRUE; dri1->api = &dri1_api_hooks; break; default: @@ -107,7 +135,7 @@ vmw_drm_create_screen(struct drm_api *drm_api, } } - vws = vmw_winsys_create( fd ); + vws = vmw_winsys_create( fd, use_old_scanout_flag ); if (!vws) goto out_no_vws; @@ -220,22 +248,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe, vmw_svga_winsys_surface_reference(&vsrf, NULL); } -/** - * FIXME: We'd probably want to cache these buffers in the - * screen, based on handle. - */ - -static struct pipe_buffer * -vmw_drm_buffer_from_handle(struct drm_api *drm_api, - struct pipe_screen *screen, - const char *name, - unsigned handle) +static struct pipe_texture * +vmw_drm_texture_from_handle(struct drm_api *drm_api, + struct pipe_screen *screen, + struct pipe_texture *templat, + const char *name, + unsigned stride, + unsigned handle) { struct vmw_svga_winsys_surface *vsrf; struct svga_winsys_surface *ssrf; struct vmw_winsys_screen *vws = vmw_winsys_screen(svga_winsys_screen(screen)); - struct pipe_buffer *buf; + struct pipe_texture *tex; union drm_vmw_surface_reference_arg arg; struct drm_vmw_surface_arg *req = &arg.req; struct drm_vmw_surface_create_req *rep = &arg.rep; @@ -282,43 +307,28 @@ vmw_drm_buffer_from_handle(struct drm_api *drm_api, pipe_reference_init(&vsrf->refcnt, 1); p_atomic_set(&vsrf->validated, 0); + vsrf->screen = vws; vsrf->sid = handle; ssrf = svga_winsys_surface(vsrf); - buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf); - if (!buf) + tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf); + if (!tex) vmw_svga_winsys_surface_reference(&vsrf, NULL); - return buf; + return tex; out_mip: vmw_ioctl_surface_destroy(vws, handle); return NULL; } -static struct pipe_texture * -vmw_drm_texture_from_handle(struct drm_api *drm_api, - struct pipe_screen *screen, - struct pipe_texture *templat, - const char *name, - unsigned stride, - unsigned handle) -{ - struct pipe_buffer *buffer; - buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle); - - if (!buffer) - return NULL; - - return screen->texture_blanket(screen, templat, &stride, buffer); -} - static boolean -vmw_drm_handle_from_buffer(struct drm_api *drm_api, +vmw_drm_handle_from_texture(struct drm_api *drm_api, struct pipe_screen *screen, - struct pipe_buffer *buffer, + struct pipe_texture *texture, + unsigned *stride, unsigned *handle) { struct svga_winsys_surface *surface = - svga_screen_buffer_get_winsys_surface(buffer); + svga_screen_texture_get_winsys_surface(texture); struct vmw_svga_winsys_surface *vsrf; if (!surface) @@ -326,31 +336,13 @@ vmw_drm_handle_from_buffer(struct drm_api *drm_api, vsrf = vmw_svga_winsys_surface(surface); *handle = vsrf->sid; + *stride = util_format_get_nblocksx(texture->format, texture->width0) * + util_format_get_blocksize(texture->format); + vmw_svga_winsys_surface_reference(&vsrf, NULL); return TRUE; } -static boolean -vmw_drm_handle_from_texture(struct drm_api *drm_api, - struct pipe_screen *screen, - struct pipe_texture *texture, - unsigned *stride, - unsigned *handle) -{ - struct pipe_buffer *buffer; - - if (!svga_screen_buffer_from_texture(texture, &buffer, stride)) - return FALSE; - - return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle); -} - -static struct pipe_context* -vmw_drm_create_context(struct drm_api *drm_api, - struct pipe_screen *screen) -{ - return vmw_svga_context_create(screen); -} static struct dri1_api dri1_api_hooks = { .front_srf_locked = NULL, @@ -358,8 +350,9 @@ static struct dri1_api dri1_api_hooks = { }; static struct drm_api vmw_drm_api_hooks = { + .name = "vmwgfx", + .driver_name = "vmwgfx", .create_screen = vmw_drm_create_screen, - .create_context = vmw_drm_create_context, .texture_from_shared_handle = vmw_drm_texture_from_handle, .shared_handle_from_texture = vmw_drm_handle_from_texture, .local_handle_from_texture = vmw_drm_handle_from_texture, diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c index ccd0b418a1..5d81fa8c4a 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c @@ -57,6 +57,12 @@ struct vmw_region uint32_t size; }; +/* XXX: This isn't a real hardware flag, but just a hack for kernel to + * know about primary surfaces. In newer versions of the kernel + * interface the driver uses a special field. + */ +#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9) + static void vmw_check_last_cmd(struct vmw_winsys_screen *vws) { @@ -169,7 +175,17 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws, vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format); memset(&s_arg, 0, sizeof(s_arg)); - req->flags = (uint32_t) flags; + if (vws->use_old_scanout_flag && + (flags & SVGA3D_SURFACE_HINT_SCANOUT)) { + req->flags = (uint32_t) flags; + req->scanout = false; + } else if (flags & SVGA3D_SURFACE_HINT_SCANOUT) { + req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT); + req->scanout = true; + } else { + req->flags = (uint32_t) flags; + req->scanout = false; + } req->format = (uint32_t) format; req->shareable = 1; diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c index b1c24b0cb6..b9823d7857 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c @@ -53,14 +53,32 @@ vmw_pools_init(struct vmw_winsys_screen *vws) goto error; vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr, - 16*1024*1024, + VMW_GMR_POOL_SIZE, 12 /* 4096 alignment */); if(!vws->pools.gmr_mm) goto error; + /* + * GMR buffers are typically shortlived, but it's possible that at a given + * instance a buffer is mapped. So to avoid stalling we tell pipebuffer to + * forbid creation of buffers beyond half the GMR pool size, + * + * XXX: It is unclear weather we want to limit the total amount of temporary + * malloc memory used to backup unvalidated GMR buffers. On one hand it is + * preferrable to fail an allocation than exhausting the guest memory with + * temporary data, but on the other hand it is possible that a stupid + * application creates large vertex buffers and does not use them for a long + * time -- since the svga pipe driver only emits the DMA uploads when a + * buffer is used for drawing this would effectively disabling swapping GMR + * buffers to memory. So far, the preemptively flush already seems to keep + * total allocated memory within relatively small numbers, so we don't + * limit. + */ vws->pools.gmr_fenced = fenced_bufmgr_create( vws->pools.gmr_mm, - vmw_fence_ops_create(vws)); + vmw_fence_ops_create(vws), + VMW_GMR_POOL_SIZE/2, + ~0); #ifdef DEBUG vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced, diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c index d7d008859b..2b4e80f003 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c +++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c @@ -36,7 +36,7 @@ #include "svga_cmd.h" #include "svga3d_caps.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "pipebuffer/pb_buffer.h" diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.h b/src/gallium/winsys/drm/vmware/core/vmw_surface.h index 340cc1532e..3d61595c28 100644 --- a/src/gallium/winsys/drm/vmware/core/vmw_surface.h +++ b/src/gallium/winsys/drm/vmware/core/vmw_surface.h @@ -36,8 +36,8 @@ #include "pipe/p_compiler.h" -#include "pipe/p_atomic.h" -#include "pipe/p_refcnt.h" +#include "util/u_atomic.h" +#include "util/u_inlines.h" #define VMW_MAX_PRESENTS 3 @@ -45,7 +45,7 @@ struct vmw_svga_winsys_surface { - struct pipe_atomic validated; + int32_t validated; /* atomic */ struct pipe_reference refcnt; struct vmw_winsys_screen *screen; diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h index 2be7e1249b..1457966db8 100644 --- a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h +++ b/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h @@ -68,7 +68,8 @@ #define DRM_VMW_PARAM_NUM_FREE_STREAMS 1 #define DRM_VMW_PARAM_3D 2 #define DRM_VMW_PARAM_FIFO_OFFSET 3 - +#define DRM_VMW_PARAM_HW_CAPS 4 +#define DRM_VMW_PARAM_FIFO_CAPS 5 /** * struct drm_vmw_getparam_arg @@ -87,49 +88,6 @@ struct drm_vmw_getparam_arg { /*************************************************************************/ /** - * DRM_VMW_EXTENSION - Query device extensions. - */ - -/** - * struct drm_vmw_extension_rep - * - * @exists: The queried extension exists. - * @driver_ioctl_offset: Ioctl number of the first ioctl in the extension. - * @driver_sarea_offset: Offset to any space in the DRI SAREA - * used by the extension. - * @major: Major version number of the extension. - * @minor: Minor version number of the extension. - * @pl: Patch level version number of the extension. - * - * Output argument to the DRM_VMW_EXTENSION Ioctl. - */ - -struct drm_vmw_extension_rep { - int32_t exists; - uint32_t driver_ioctl_offset; - uint32_t driver_sarea_offset; - uint32_t major; - uint32_t minor; - uint32_t pl; - uint32_t pad64; -}; - -/** - * union drm_vmw_extension_arg - * - * @extension - Ascii name of the extension to be queried. //In - * @rep - Reply as defined above. //Out - * - * Argument to the DRM_VMW_EXTENSION Ioctl. - */ - -union drm_vmw_extension_arg { - char extension[DRM_VMW_EXT_NAME_LEN]; - struct drm_vmw_extension_rep rep; -}; - -/*************************************************************************/ -/** * DRM_VMW_CREATE_CONTEXT - Create a host context. * * Allocates a device unique context id, and queues a create context command @@ -181,6 +139,8 @@ struct drm_vmw_context_arg { * The size of the array should equal the total number of mipmap levels. * @shareable: Boolean whether other clients (as identified by file descriptors) * may reference this surface. + * @scanout: Boolean whether the surface is intended to be used as a + * scanout. * * Input data to the DRM_VMW_CREATE_SURFACE Ioctl. * Output data from the DRM_VMW_REF_SURFACE Ioctl. @@ -192,7 +152,7 @@ struct drm_vmw_surface_create_req { uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; uint64_t size_addr; int32_t shareable; - uint32_t pad64; + int32_t scanout; }; /** @@ -295,6 +255,9 @@ union drm_vmw_surface_reference_arg { * * @commands: User-space address of a command buffer cast to an uint64_t. * @command-size: Size in bytes of the command buffer. + * @throttle-us: Sleep until software is less than @throttle_us + * microseconds ahead of hardware. The driver may round this value + * to the nearest kernel tick. * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an * uint64_t. * @@ -304,7 +267,7 @@ union drm_vmw_surface_reference_arg { struct drm_vmw_execbuf_arg { uint64_t commands; uint32_t command_size; - uint32_t pad64; + uint32_t throttle_us; uint64_t fence_rep; }; diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile index 8e2980c318..a3e73131c3 100644 --- a/src/gallium/winsys/drm/vmware/egl/Makefile +++ b/src/gallium/winsys/drm/vmware/egl/Makefile @@ -1,18 +1,14 @@ - TOP = ../../../../../.. include $(TOP)/configs/current -LIBNAME = EGL_svga.so +EGL_DRIVER_NAME = vmwgfx +EGL_DRIVER_SOURCES = dummy.c +EGL_DRIVER_LIBS = -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \ +EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/trace/libtrace.a \ $(TOP)/src/gallium/drivers/svga/libsvga.a -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) - -include ../../Makefile.template - -symlinks: +include ../../Makefile.egl diff --git a/src/gallium/winsys/drm/vmware/egl/dummy.c b/src/gallium/winsys/drm/vmware/egl/dummy.c new file mode 100644 index 0000000000..4a1bc28b0b --- /dev/null +++ b/src/gallium/winsys/drm/vmware/egl/dummy.c @@ -0,0 +1 @@ +/* mklib expects at least one object file */ diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c index b065b96346..ff3b992d07 100644 --- a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c @@ -649,7 +649,8 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port, return XvBadAlloc; } - port->currBuf = ++port->currBuf & (VMWARE_VID_NUM_BUFFERS - 1); + if (++(port->currBuf) >= VMWARE_VID_NUM_BUFFERS) + port->currBuf = 0; return Success; } diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c index 4b208719ca..cd273d091f 100644 --- a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c +++ b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c @@ -34,10 +34,10 @@ #include "vmw_hook.h" static void vmw_xorg_identify(int flags); -static Bool vmw_xorg_pci_probe(DriverPtr driver, - int entity_num, - struct pci_device *device, - intptr_t match_data); +_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver, + int entity_num, + struct pci_device *device, + intptr_t match_data); static const struct pci_id_match vmw_xorg_device_match[] = { {0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0}, @@ -126,7 +126,7 @@ vmw_xorg_identify(int flags) vmw_xorg_chipsets); } -static Bool +_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver, int entity_num, struct pci_device *device, intptr_t match_data) { diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile deleted file mode 100644 index 3efb7ed4af..0000000000 --- a/src/gallium/winsys/egl_xlib/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# src/gallium/winsys/egl_xlib/Makefile - -# Build softpipe/xlib/EGL driver library/object: "egl_softpipe.so" - - -TOP = ../../../.. -include $(TOP)/configs/current - - -DRIVER_NAME = egl_softpipe.so - - -INCLUDE_DIRS = \ - -I$(TOP)/include \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/auxiliary - -WINSYS_SOURCES = \ - egl_xlib.c \ - sw_winsys.c - -WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o) - - -LIBS = \ - $(GALLIUM_DRIVERS) \ - $(GALLIUM_AUXILIARIES) - -# XXX temporary (should create a separate lib with the GL API funcs and -# mesa code, as done for ES 1.x, 2.x, OpenVG, etc) -UNUSED_LIBS = \ - $(TOP)/src/mesa/libglapi.a \ - $(TOP)/src/mesa/libmesagallium.a \ - - -LOCAL_CFLAGS = - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ - - -.PHONY: library - - -default: depend library Makefile - - -library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) - - -# Make the egl_softpipe.so library -$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) - $(TOP)/bin/mklib -o $(DRIVER_NAME) \ - -linker "$(CC)" \ - -noprefix \ - -install $(TOP)/$(LIB_DIR) \ - $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ - -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive - - -depend: $(ALL_SOURCES) - @ echo "running $(MKDEP)" - @ rm -f depend # workaround oops on gutsy?!? - @ touch depend - @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ - > /dev/null 2>/dev/null - - -install: default - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - @if [ -e $(TOP)/$(LIB_DIR) ]; then \ - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \ - fi - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h - -clean: - -rm -f *.o *~ *.bak - - -include depend diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c deleted file mode 100644 index 420dccc92c..0000000000 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ /dev/null @@ -1,853 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 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. - * - **************************************************************************/ - -/** - * EGL / softpipe / xlib winsys module - * - * Authors: Brian Paul - */ - - -#include <dlfcn.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -#include "pipe/p_compiler.h" -#include "pipe/p_format.h" -#include "pipe/p_state.h" -#include "pipe/internal/p_winsys_screen.h" -#include "util/u_memory.h" -#include "util/u_math.h" -#include "softpipe/sp_winsys.h" -#include "softpipe/sp_texture.h" - -#include "eglconfig.h" -#include "eglconfigutil.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "egllog.h" -#include "eglsurface.h" - -#include "state_tracker/st_public.h" - -#include "sw_winsys.h" - - -/** subclass of _EGLDriver */ -struct xlib_egl_driver -{ - _EGLDriver Base; /**< base class */ - EGLint apis; -}; - - -/** driver data of _EGLDisplay */ -struct xlib_egl_display -{ - Display *Dpy; - - struct pipe_winsys *winsys; - struct pipe_screen *screen; -}; - - -/** subclass of _EGLContext */ -struct xlib_egl_context -{ - _EGLContext Base; /**< base class */ - - struct pipe_context *pipe; /**< Gallium driver context */ - struct st_context *Context; /**< Mesa/gallium state tracker context */ -}; - - -/** subclass of _EGLSurface */ -struct xlib_egl_surface -{ - _EGLSurface Base; /**< base class */ - - /* These are set for window surface */ - Display *Dpy; /**< The X Display of the window */ - Window Win; /**< The user-created window ID */ - GC Gc; - XVisualInfo VisInfo; - - struct pipe_winsys *winsys; - - struct st_framebuffer *Framebuffer; -}; - - -static void -flush_frontbuffer(struct pipe_winsys *pws, - struct pipe_surface *psurf, - void *context_private); - - -/** cast wrapper */ -static INLINE struct xlib_egl_driver * -xlib_egl_driver(_EGLDriver *drv) -{ - return (struct xlib_egl_driver *) drv; -} - - -static INLINE struct xlib_egl_display * -xlib_egl_display(_EGLDisplay *dpy) -{ - return (struct xlib_egl_display *) dpy->DriverData; -} - - -static INLINE struct xlib_egl_surface * -lookup_surface(_EGLSurface *surf) -{ - return (struct xlib_egl_surface *) surf; -} - - -static INLINE struct xlib_egl_context * -lookup_context(_EGLContext *ctx) -{ - return (struct xlib_egl_context *) ctx; -} - - -/** - * Create the EGLConfigs. (one per X visual) - */ -static void -create_configs(struct xlib_egl_display *xdpy, _EGLDisplay *disp) -{ - static const EGLint all_apis = (EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_BIT); - XVisualInfo *visInfo, visTemplate; - int num_visuals, i; - - /* get list of all X visuals, create an EGL config for each */ - visTemplate.screen = DefaultScreen(xdpy->Dpy); - visInfo = XGetVisualInfo(xdpy->Dpy, VisualScreenMask, - &visTemplate, &num_visuals); - if (!visInfo) { - printf("egl_xlib.c: couldn't get any X visuals\n"); - abort(); - } - - for (i = 0; i < num_visuals; i++) { - _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); - int id = i + 1; - int rbits = util_bitcount(visInfo[i].red_mask); - int gbits = util_bitcount(visInfo[i].green_mask); - int bbits = util_bitcount(visInfo[i].blue_mask); - int abits = bbits == 8 ? 8 : 0; - int zbits = 24; - int sbits = 8; - int visid = visInfo[i].visualid; -#if defined(__cplusplus) || defined(c_plusplus) - int vistype = visInfo[i].c_class; -#else - int vistype = visInfo[i].class; -#endif - - _eglInitConfig(config, id); - SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits); - SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits); - SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits); - SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits); - SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits); - SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits); - SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); - SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); - SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); - SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); - SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis); - SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis); - SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); - SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); - SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); - - _eglAddConfig(disp, config); - } - - XFree(visInfo); -} - - -/** - * Called via eglInitialize(), drv->API.Initialize(). - */ -static EGLBoolean -xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) -{ - struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); - struct xlib_egl_display *xdpy; - - xdpy = CALLOC_STRUCT(xlib_egl_display); - if (!xdpy) - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - - xdpy->Dpy = (Display *) dpy->NativeDisplay; - if (!xdpy->Dpy) { - xdpy->Dpy = XOpenDisplay(NULL); - if (!xdpy->Dpy) { - free(xdpy); - return EGL_FALSE; - } - } - - /* create winsys and pipe screen */ - xdpy->winsys = create_sw_winsys(); - if (!xdpy->winsys) { - free(xdpy); - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - } - xdpy->winsys->flush_frontbuffer = flush_frontbuffer; - xdpy->screen = softpipe_create_screen(xdpy->winsys); - if (!xdpy->screen) { - free(xdpy->winsys); - free(xdpy); - return _eglError(EGL_BAD_ALLOC, "eglInitialize"); - } - - dpy->DriverData = (void *) xdpy; - dpy->ClientAPIsMask = xdrv->apis; - - create_configs(xdpy, dpy); - - /* we're supporting EGL 1.4 */ - *major = 1; - *minor = 4; - - return EGL_TRUE; -} - - -/** - * Called via eglTerminate(), drv->API.Terminate(). - */ -static EGLBoolean -xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - struct xlib_egl_display *xdpy = xlib_egl_display(dpy); - - _eglReleaseDisplayResources(drv, dpy); - _eglCleanupDisplay(dpy); - - xdpy->screen->destroy(xdpy->screen); - free(xdpy->winsys); - - if (!dpy->NativeDisplay) - XCloseDisplay(xdpy->Dpy); - free(xdpy); - - return EGL_TRUE; -} - - -static _EGLProc -xlib_eglGetProcAddress(const char *procname) -{ - return (_EGLProc) st_get_proc_address(procname); -} - - -static void -get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo) -{ - XWindowAttributes attr; - XVisualInfo visTemp, *vis; - int num_visuals; - - XGetWindowAttributes(dpy, d, &attr); - - visTemp.screen = DefaultScreen(dpy); - visTemp.visualid = attr.visual->visualid; - vis = XGetVisualInfo(dpy, - (VisualScreenMask | VisualIDMask), - &visTemp, &num_visuals); - if (vis) - *visInfo = *vis; - - XFree(vis); -} - - - -/** Get size of given window */ -static Status -get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) -{ - Window root; - Status stat; - int xpos, ypos; - unsigned int w, h, bw, depth; - stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); - *width = w; - *height = h; - return stat; -} - - -static void -check_and_update_buffer_size(struct xlib_egl_surface *surface) -{ - uint width, height; - if (surface->Base.Type == EGL_PBUFFER_BIT) { - width = surface->Base.Width; - height = surface->Base.Height; - } - else { - get_drawable_size(surface->Dpy, surface->Win, &width, &height); - } - st_resize_framebuffer(surface->Framebuffer, width, height); - surface->Base.Width = width; - surface->Base.Height = height; -} - - - -static void -display_surface(struct pipe_winsys *pws, - struct pipe_surface *psurf, - struct xlib_egl_surface *xsurf) -{ - struct softpipe_texture *spt = softpipe_texture(psurf->texture); - XImage *ximage; - void *data; - - if (xsurf->Base.Type == EGL_PBUFFER_BIT) - return; - - ximage = XCreateImage(xsurf->Dpy, - xsurf->VisInfo.visual, - xsurf->VisInfo.depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - - - assert(ximage->format); - assert(ximage->bitmap_unit); - - data = pws->buffer_map(pws, spt->buffer, 0); - - /* update XImage's fields */ - ximage->data = data; - ximage->width = psurf->width; - ximage->height = psurf->height; - ximage->bytes_per_line = spt->stride[psurf->level]; - - XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, - ximage, 0, 0, 0, 0, psurf->width, psurf->height); - - XSync(xsurf->Dpy, 0); - - ximage->data = NULL; - XDestroyImage(ximage); - - pws->buffer_unmap(pws, spt->buffer); -} - - - -/** Display gallium surface in X window */ -static void -flush_frontbuffer(struct pipe_winsys *pws, - struct pipe_surface *psurf, - void *context_private) -{ - struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private; - display_surface(pws, psurf, xsurf); -} - - - -/** - * Called via eglCreateContext(), drv->API.CreateContext(). - */ -static _EGLContext * -xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - _EGLContext *share_list, const EGLint *attrib_list) -{ - struct xlib_egl_display *xdpy = xlib_egl_display(dpy); - struct xlib_egl_context *ctx; - struct st_context *share_ctx = NULL; /* XXX fix */ - __GLcontextModes visual; - - ctx = CALLOC_STRUCT(xlib_egl_context); - if (!ctx) - return NULL; - - /* let EGL lib init the common stuff */ - if (!_eglInitContext(drv, &ctx->Base, conf, attrib_list)) { - free(ctx); - return NULL; - } - - /* API-dependent context creation */ - switch (ctx->Base.ClientAPI) { - case EGL_OPENVG_API: - case EGL_OPENGL_ES_API: - _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", - ctx->Base.ClientVersion); - /* fall-through */ - case EGL_OPENGL_API: - /* create a softpipe context */ - ctx->pipe = softpipe_create(xdpy->screen); - /* Now do xlib / state tracker inits here */ - _eglConfigToContextModesRec(conf, &visual); - ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); - break; - default: - _eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)"); - free(ctx); - return NULL; - } - - return &ctx->Base; -} - - -static EGLBoolean -xlib_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) -{ - struct xlib_egl_context *context = lookup_context(ctx); - - if (!_eglIsContextBound(&context->Base)) { - /* API-dependent clean-up */ - switch (context->Base.ClientAPI) { - case EGL_OPENGL_ES_API: - case EGL_OPENVG_API: - /* fall-through */ - case EGL_OPENGL_API: - st_destroy_context(context->Context); - break; - default: - assert(0); - } - free(context); - } - return EGL_TRUE; -} - - -/** - * Called via eglMakeCurrent(), drv->API.MakeCurrent(). - */ -static EGLBoolean -xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx) -{ - struct xlib_egl_context *context = lookup_context(ctx); - struct xlib_egl_surface *draw_surf = lookup_surface(draw); - struct xlib_egl_surface *read_surf = lookup_surface(read); - struct st_context *oldcontext = NULL; - _EGLContext *oldctx; - - oldctx = _eglGetCurrentContext(); - if (oldctx && _eglIsContextLinked(oldctx)) - oldcontext = st_get_current(); - - if (!_eglMakeCurrent(drv, dpy, draw, read, ctx)) - return EGL_FALSE; - - /* Flush before switching context. Check client API? */ - if (oldcontext) - st_flush(oldcontext, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); - st_make_current((context ? context->Context : NULL), - (draw_surf ? draw_surf->Framebuffer : NULL), - (read_surf ? read_surf->Framebuffer : NULL)); - - if (draw_surf) - check_and_update_buffer_size(draw_surf); - if (read_surf && read_surf != draw_surf) - check_and_update_buffer_size(draw_surf); - - return EGL_TRUE; -} - - -static enum pipe_format -choose_color_format(const __GLcontextModes *visual) -{ - if (visual->redBits == 8 && - visual->greenBits == 8 && - visual->blueBits == 8 && - visual->alphaBits == 8) { - /* XXX this really also depends on the ordering of R,G,B,A */ - return PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - assert(0); - return PIPE_FORMAT_NONE; - } -} - - -static enum pipe_format -choose_depth_format(const __GLcontextModes *visual) -{ - if (visual->depthBits > 0) - return PIPE_FORMAT_S8Z24_UNORM; - else - return PIPE_FORMAT_NONE; -} - - -static enum pipe_format -choose_stencil_format(const __GLcontextModes *visual) -{ - if (visual->stencilBits > 0) - return PIPE_FORMAT_S8Z24_UNORM; - else - return PIPE_FORMAT_NONE; -} - - -/** - * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). - */ -static _EGLSurface * -xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) -{ - struct xlib_egl_display *xdpy = xlib_egl_display(disp); - struct xlib_egl_surface *surf; - __GLcontextModes visual; - uint width, height; - - surf = CALLOC_STRUCT(xlib_egl_surface); - if (!surf) - return NULL; - - /* Let EGL lib init the common stuff */ - if (!_eglInitSurface(drv, &surf->Base, EGL_WINDOW_BIT, - conf, attrib_list)) { - free(surf); - return NULL; - } - - /* - * Now init the Xlib and gallium stuff - */ - surf->Win = (Window) window; /* The X window ID */ - surf->Dpy = xdpy->Dpy; /* The X display */ - surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL); - - surf->winsys = xdpy->winsys; - - _eglConfigToContextModesRec(conf, &visual); - get_drawable_size(surf->Dpy, surf->Win, &width, &height); - get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo); - - surf->Base.Width = width; - surf->Base.Height = height; - - /* Create GL statetracker framebuffer */ - surf->Framebuffer = st_create_framebuffer(&visual, - choose_color_format(&visual), - choose_depth_format(&visual), - choose_stencil_format(&visual), - width, height, - (void *) surf); - - st_resize_framebuffer(surf->Framebuffer, width, height); - - return &surf->Base; -} - - -static _EGLSurface * -xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - const EGLint *attrib_list) -{ - struct xlib_egl_display *xdpy = xlib_egl_display(disp); - struct xlib_egl_surface *surf; - __GLcontextModes visual; - uint width, height; - EGLBoolean bind_texture; - - surf = CALLOC_STRUCT(xlib_egl_surface); - if (!surf) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); - return NULL; - } - - if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, - conf, attrib_list)) { - free(surf); - return NULL; - } - if (surf->Base.Width < 0 || surf->Base.Height < 0) { - _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface"); - free(surf); - return NULL; - } - - bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE); - width = (uint) surf->Base.Width; - height = (uint) surf->Base.Height; - if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) || - (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) { - _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); - free(surf); - return NULL; - } - /* a framebuffer of zero width or height confuses st */ - if (width == 0 || height == 0) { - _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); - free(surf); - return NULL; - } - /* no mipmap generation */ - if (surf->Base.MipmapTexture) { - _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface"); - free(surf); - return NULL; - } - - surf->winsys = xdpy->winsys; - - _eglConfigToContextModesRec(conf, &visual); - - /* Create GL statetracker framebuffer */ - surf->Framebuffer = st_create_framebuffer(&visual, - choose_color_format(&visual), - choose_depth_format(&visual), - choose_stencil_format(&visual), - width, height, - (void *) surf); - st_resize_framebuffer(surf->Framebuffer, width, height); - - return &surf->Base; -} - - -static EGLBoolean -xlib_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - struct xlib_egl_surface *surf = lookup_surface(surface); - if (!_eglIsSurfaceBound(&surf->Base)) { - if (surf->Base.Type != EGL_PBUFFER_BIT) - XFreeGC(surf->Dpy, surf->Gc); - st_unreference_framebuffer(surf->Framebuffer); - free(surf); - } - return EGL_TRUE; -} - - -static EGLBoolean -xlib_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *surface, EGLint buffer) -{ - struct xlib_egl_surface *xsurf = lookup_surface(surface); - struct xlib_egl_context *xctx; - struct pipe_surface *psurf; - enum pipe_format format; - int target; - - if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT) - return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); - if (buffer != EGL_BACK_BUFFER) - return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage"); - if (xsurf->Base.BoundToTexture) - return _eglError(EGL_BAD_ACCESS, "eglBindTexImage"); - - /* this should be updated when choose_color_format is */ - switch (xsurf->Base.TextureFormat) { - case EGL_TEXTURE_RGB: - format = PIPE_FORMAT_R8G8B8_UNORM; - break; - case EGL_TEXTURE_RGBA: - format = PIPE_FORMAT_A8R8G8B8_UNORM; - break; - default: - return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - } - - switch (xsurf->Base.TextureTarget) { - case EGL_TEXTURE_2D: - target = ST_TEXTURE_2D; - break; - default: - return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); - } - - /* flush properly */ - if (eglGetCurrentSurface(EGL_DRAW) == surface) { - xctx = lookup_context(_eglGetCurrentContext()); - st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, - NULL); - } - else if (_eglIsSurfaceBound(&xsurf->Base)) { - xctx = lookup_context(xsurf->Base.Binding); - if (xctx) - st_finish(xctx->Context); - } - - st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, - &psurf); - st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format); - xsurf->Base.BoundToTexture = EGL_TRUE; - - return EGL_TRUE; -} - - -static EGLBoolean -xlib_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, - EGLint buffer) -{ - struct xlib_egl_surface *xsurf = lookup_surface(surface); - struct pipe_surface *psurf; - - if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT || - !xsurf->Base.BoundToTexture) - return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage"); - if (buffer != EGL_BACK_BUFFER) - return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage"); - - st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, - &psurf); - st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel); - xsurf->Base.BoundToTexture = EGL_FALSE; - - return EGL_TRUE; -} - - -static EGLBoolean -xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) -{ - struct xlib_egl_surface *xsurf = lookup_surface(draw); - struct pipe_winsys *pws = xsurf->winsys; - struct pipe_surface *psurf; - - st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, - &psurf); - - st_notify_swapbuffers(xsurf->Framebuffer); - - display_surface(pws, psurf, xsurf); - - check_and_update_buffer_size(xsurf); - - return EGL_TRUE; -} - - -/** - * Determine which API(s) is(are) present by looking for some specific - * global symbols. - */ -static EGLint -find_supported_apis(void) -{ - EGLint mask = 0; - void *handle; - - handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); - if(!handle) - return mask; - - if (dlsym(handle, "st_api_OpenGL_ES1")) - mask |= EGL_OPENGL_ES_BIT; - - if (dlsym(handle, "st_api_OpenGL_ES2")) - mask |= EGL_OPENGL_ES2_BIT; - - if (dlsym(handle, "st_api_OpenGL")) - mask |= EGL_OPENGL_BIT; - - if (dlsym(handle, "st_api_OpenVG")) - mask |= EGL_OPENVG_BIT; - - dlclose(handle); - - return mask; -} - - -static void -xlib_Unload(_EGLDriver *drv) -{ - struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); - free(xdrv); -} - - -/** - * This is the main entrypoint into the driver. - * Called by libEGL to instantiate an _EGLDriver object. - */ -_EGLDriver * -_eglMain(const char *args) -{ - struct xlib_egl_driver *xdrv; - - _eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args); - - xdrv = CALLOC_STRUCT(xlib_egl_driver); - if (!xdrv) - return NULL; - - _eglInitDriverFallbacks(&xdrv->Base); - xdrv->Base.API.Initialize = xlib_eglInitialize; - xdrv->Base.API.Terminate = xlib_eglTerminate; - xdrv->Base.API.GetProcAddress = xlib_eglGetProcAddress; - xdrv->Base.API.CreateContext = xlib_eglCreateContext; - xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; - xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; - xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface; - xdrv->Base.API.DestroySurface = xlib_eglDestroySurface; - xdrv->Base.API.BindTexImage = xlib_eglBindTexImage; - xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage; - xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; - xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; - - xdrv->apis = find_supported_apis(); - if (xdrv->apis == 0x0) { - /* the app isn't directly linked with any EGL-supprted APIs - * (such as libGLESv2.so) so use an EGL utility to see what - * APIs might be loaded dynamically on this system. - */ - xdrv->apis = _eglFindAPIs(); - } - - xdrv->Base.Name = "Xlib/softpipe"; - xdrv->Base.Unload = xlib_Unload; - - return &xdrv->Base; -} diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 3965bd949f..f07a7926d6 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -20,14 +20,11 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${DRIDIR}/lib \ -L${GALLIUMDIR}/winsys/drm/nouveau/common \ -L${GALLIUMDIR}/auxiliary \ - -L${GALLIUMDIR}/drivers/nv04 \ - -L${GALLIUMDIR}/drivers/nv10 \ - -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -lgallium -lm +LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv30 -lnv40 -lnv50 -lgallium -lm ############################################# diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c index f15bcd37b5..048af62ed3 100644 --- a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c @@ -27,9 +27,9 @@ #include <vl_winsys.h> #include <X11/Xutil.h> -#include <pipe/internal/p_winsys_screen.h> +#include <util/u_simple_screen.h> #include <pipe/p_state.h> -#include <pipe/p_inlines.h> +#include <util/u_inlines.h> #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_math.h> diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c index 7d076be3a3..03dbd76c37 100644 --- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c @@ -38,7 +38,7 @@ #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -216,11 +216,6 @@ no_winsys: } -static struct pipe_context * -gdi_llvmpipe_context_create(struct pipe_screen *screen) -{ - return llvmpipe_create(screen); -} static void @@ -243,7 +238,6 @@ gdi_llvmpipe_present(struct pipe_screen *screen, static const struct stw_winsys stw_winsys = { &gdi_llvmpipe_screen_create, - &gdi_llvmpipe_context_create, &gdi_llvmpipe_present, NULL, /* get_adapter_luid */ NULL, /* shared_surface_open */ diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 2ad794c3f0..2078020f8f 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -38,10 +38,10 @@ #include <windows.h> -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -249,13 +249,6 @@ gdi_softpipe_screen_create(void) } -static struct pipe_context * -gdi_softpipe_context_create(struct pipe_screen *screen) -{ - return softpipe_create(screen); -} - - static void gdi_softpipe_present(struct pipe_screen *screen, struct pipe_surface *surface, @@ -291,7 +284,6 @@ gdi_softpipe_present(struct pipe_screen *screen, static const struct stw_winsys stw_winsys = { &gdi_softpipe_screen_create, - &gdi_softpipe_context_create, &gdi_softpipe_present, NULL, /* get_adapter_luid */ NULL, /* shared_surface_open */ diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c index 6dbe05f193..67617a470d 100644 --- a/src/gallium/winsys/xlib/xlib.c +++ b/src/gallium/winsys/xlib/xlib.c @@ -47,6 +47,8 @@ enum mode { MODE_SOFTPIPE }; +/* advertise OpenGL support */ +PUBLIC const int st_api_OpenGL = 1; static enum mode get_mode() { @@ -103,3 +105,34 @@ extern void (*linker_foo(const unsigned char *procName))() { return glXGetProcAddress(procName); } + + +/** + * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in + * libglapi.a. We need to define them here. + */ +#ifdef GLX_INDIRECT_RENDERING + +#define GL_GLEXT_PROTOTYPES +#include "GL/gl.h" +#include "glapi/glapi.h" +#include "glapi/glapitable.h" +#include "glapi/glapidispatch.h" + +#if defined(USE_MGL_NAMESPACE) +#define NAME(func) mgl##func +#else +#define NAME(func) gl##func +#endif + +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + CALL_ ## FUNC(GET_DISPATCH(), ARGS); + +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + return CALL_ ## FUNC(GET_DISPATCH(), ARGS); + +/* skip normal ones */ +#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS +#include "glapi/glapitemp.h" + +#endif /* GLX_INDIRECT_RENDERING */ diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c index fc9addd09e..22bf41a46f 100644 --- a/src/gallium/winsys/xlib/xlib_brw_context.c +++ b/src/gallium/winsys/xlib/xlib_brw_context.c @@ -36,8 +36,8 @@ /* #include "glxheader.h" */ /* #include "xmesaP.h" */ -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" +#include "util/u_simple_screen.h" +#include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" #include "i965simple/brw_winsys.h" diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c index 47ae0519a4..1dc9e8fa11 100644 --- a/src/gallium/winsys/xlib/xlib_cell.c +++ b/src/gallium/winsys/xlib/xlib_cell.c @@ -41,10 +41,10 @@ #undef ASSERT #undef Elements -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -383,35 +383,10 @@ fail: } -static struct pipe_context * -xlib_create_cell_context( struct pipe_screen *screen, - void *priv ) -{ - struct pipe_context *pipe; - - - /* This takes a cell_winsys pointer, but probably that should be - * created and stored at screen creation, not context creation. - * - * The actual cell_winsys value isn't used for anything, so just - * passing NULL for now. - */ - pipe = cell_create_context( screen, NULL); - if (pipe == NULL) - goto fail; - - pipe->priv = priv; - - return pipe; - -fail: - return NULL; -} struct xm_driver xlib_cell_driver = { .create_pipe_screen = xlib_create_cell_screen, - .create_pipe_context = xlib_create_cell_context, .display_surface = xlib_cell_display_surface, }; @@ -420,7 +395,6 @@ struct xm_driver xlib_cell_driver = struct xm_driver xlib_cell_driver = { .create_pipe_screen = NULL, - .create_pipe_context = NULL, .display_surface = NULL, }; diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c index 2a434b5fd2..6cebd4c201 100644 --- a/src/gallium/winsys/xlib/xlib_llvmpipe.c +++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c @@ -40,10 +40,10 @@ #undef ASSERT #undef Elements -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -419,25 +419,6 @@ fail: } -static struct pipe_context * -xlib_create_llvmpipe_context( struct pipe_screen *screen, - void *context_private ) -{ - struct pipe_context *pipe; - - pipe = llvmpipe_create(screen); - if (pipe == NULL) - goto fail; - - pipe->priv = context_private; - return pipe; - -fail: - /* Free stuff here */ - return NULL; -} - - static void xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer, struct pipe_surface *surf) @@ -453,7 +434,6 @@ xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer, struct xm_driver xlib_llvmpipe_driver = { .create_pipe_screen = xlib_create_llvmpipe_screen, - .create_pipe_context = xlib_create_llvmpipe_context, .display_surface = xlib_llvmpipe_display_surface }; diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c index f7c0099584..716338aef4 100644 --- a/src/gallium/winsys/xlib/xlib_softpipe.c +++ b/src/gallium/winsys/xlib/xlib_softpipe.c @@ -38,10 +38,10 @@ #undef ASSERT #undef Elements -#include "pipe/internal/p_winsys_screen.h" +#include "util/u_simple_screen.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -63,7 +63,7 @@ struct xm_buffer XImage *tempImage; #ifdef USE_XSHM - int shm; + boolean shm; /** Is this a shared memory buffer? */ XShmSegmentInfo shminfo; #endif }; @@ -152,7 +152,7 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, &b->shminfo, width, height); if (b->tempImage == NULL) { - b->shm = 0; + b->shm = FALSE; return; } @@ -169,12 +169,12 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, mesaXErrorFlag = 0; XDestroyImage(b->tempImage); b->tempImage = NULL; - b->shm = 0; + b->shm = FALSE; (void) XSetErrorHandler(old_handler); return; } - b->shm = 1; + b->shm = TRUE; } #endif /* USE_XSHM */ @@ -204,6 +204,14 @@ xm_buffer_destroy(struct pipe_buffer *buf) { struct xm_buffer *oldBuf = xm_buffer(buf); + /* + * Note oldBuf->data may point to one of three things: + * 1. XShm shared memory image data + * 2. User-provided (wrapped) memory, see xm_user_buffer_create() + * 3. Regular, malloc'd memory + * We need to be careful with freeing that data now. + */ + if (oldBuf->data) { #ifdef USE_XSHM if (oldBuf->shminfo.shmid >= 0) { @@ -213,12 +221,20 @@ xm_buffer_destroy(struct pipe_buffer *buf) oldBuf->shminfo.shmid = -1; oldBuf->shminfo.shmaddr = (char *) -1; } - else + + if (oldBuf->shm) { + oldBuf->data = NULL; + } + + if (oldBuf->tempImage) { + XDestroyImage(oldBuf->tempImage); + oldBuf->tempImage = NULL; + } #endif - { - if (!oldBuf->userBuffer) { - align_free(oldBuf->data); - } + + if (oldBuf->data && !oldBuf->userBuffer) { + /* this was regular malloc'd memory */ + align_free(oldBuf->data); } oldBuf->data = NULL; @@ -327,10 +343,8 @@ xm_buffer_create(struct pipe_winsys *pws, buffer->base.usage = usage; buffer->base.size = size; - if (buffer->data == NULL) { - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); - } + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); return &buffer->base; } @@ -484,28 +498,9 @@ fail: } -static struct pipe_context * -xlib_create_softpipe_context( struct pipe_screen *screen, - void *context_private ) -{ - struct pipe_context *pipe; - - pipe = softpipe_create(screen); - if (pipe == NULL) - goto fail; - - pipe->priv = context_private; - return pipe; - -fail: - /* Free stuff here */ - return NULL; -} - struct xm_driver xlib_softpipe_driver = { .create_pipe_screen = xlib_create_softpipe_screen, - .create_pipe_context = xlib_create_softpipe_context, .display_surface = xlib_softpipe_display_surface }; diff --git a/src/glew/SConscript b/src/glew/SConscript index ce6e71e157..45375e083a 100644 --- a/src/glew/SConscript +++ b/src/glew/SConscript @@ -52,6 +52,9 @@ prog_env = env.Clone() prog_env.Prepend(LIBS = [glew]) +if prog_env['platform'] == 'darwin': + prog_env.Append(FRAMEWORKS = ['AGL']) + prog_env.Program( target = 'glewinfo', source = ['glewinfo.c'], diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index e9b3707ac1..e256ab8213 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -345,7 +345,7 @@ struct parse_state { }; -static __inline unsigned int +static unsigned int _emit(struct parse_context *ctx, unsigned int *out, unsigned char b) diff --git a/src/glsl/pp/sl_pp_purify.c b/src/glsl/pp/sl_pp_purify.c index b50f819251..acc000cf3d 100644 --- a/src/glsl/pp/sl_pp_purify.c +++ b/src/glsl/pp/sl_pp_purify.c @@ -140,7 +140,7 @@ sl_pp_purify_state_init(struct sl_pp_purify_state *state, } -unsigned int +static unsigned int _purify_comment(struct sl_pp_purify_state *state, char *output, unsigned int *current_line, diff --git a/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h b/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h index 449329665c..ba6868a306 100644 --- a/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h +++ b/src/glu/sgi/libnurbs/interface/bezierPatchMesh.h @@ -33,6 +33,7 @@ #ifndef _BEZIERPATCHMESH_H #define _BEZIERPATCHMESH_H +#include <GL/gl.h> #include "bezierPatch.h" typedef struct bezierPatchMesh{ diff --git a/src/glu/sgi/libnurbs/interface/glsurfeval.h b/src/glu/sgi/libnurbs/interface/glsurfeval.h index 1567c6b098..621e59391a 100644 --- a/src/glu/sgi/libnurbs/interface/glsurfeval.h +++ b/src/glu/sgi/libnurbs/interface/glsurfeval.h @@ -83,7 +83,7 @@ typedef struct surfEvalMachine{ class StoredVertex { public: - StoredVertex() { type = 0; } + StoredVertex() { type = 0; coord[0] = 0; coord[1] = 0; point[0] = 0; point[1] = 0; } ~StoredVertex(void) {} void saveEvalCoord(REAL x, REAL y) {coord[0] = x; coord[1] = y; type = TYPECOORD; } diff --git a/src/glu/sgi/libnurbs/internals/arc.cc b/src/glu/sgi/libnurbs/internals/arc.cc index b85139de93..cd4c4048a0 100644 --- a/src/glu/sgi/libnurbs/internals/arc.cc +++ b/src/glu/sgi/libnurbs/internals/arc.cc @@ -43,7 +43,6 @@ #include "myassert.h" #include "arc.h" #include "bin.h" -#include "bezierarc.h" #include "pwlarc.h" #include "simplemath.h" diff --git a/src/glu/sgi/libnurbs/internals/backend.cc b/src/glu/sgi/libnurbs/internals/backend.cc index 88dc3f5168..27b41ebb29 100644 --- a/src/glu/sgi/libnurbs/internals/backend.cc +++ b/src/glu/sgi/libnurbs/internals/backend.cc @@ -46,7 +46,6 @@ #include "backend.h" #include "basiccrveval.h" #include "basicsurfeval.h" -#include "nurbsconsts.h" #define NOWIREFRAME diff --git a/src/glu/sgi/libnurbs/internals/curvelist.cc b/src/glu/sgi/libnurbs/internals/curvelist.cc index 872eb5816d..abfebb767f 100644 --- a/src/glu/sgi/libnurbs/internals/curvelist.cc +++ b/src/glu/sgi/libnurbs/internals/curvelist.cc @@ -43,7 +43,6 @@ #include "quilt.h" #include "curvelist.h" #include "curve.h" -#include "nurbsconsts.h" #include "types.h" Curvelist::Curvelist( Quilt *quilts, REAL pta, REAL ptb ) diff --git a/src/glu/sgi/libnurbs/internals/curvesub.cc b/src/glu/sgi/libnurbs/internals/curvesub.cc index f85acc269a..91f2ca8ce8 100644 --- a/src/glu/sgi/libnurbs/internals/curvesub.cc +++ b/src/glu/sgi/libnurbs/internals/curvesub.cc @@ -45,7 +45,6 @@ #include "backend.h" #include "quilt.h" #include "curvelist.h" -#include "curve.h" #include "nurbsconsts.h" /*-------------------------------------------------------------------------- diff --git a/src/glu/sgi/libnurbs/internals/maplist.cc b/src/glu/sgi/libnurbs/internals/maplist.cc index f944d1529e..e51a3e85d0 100644 --- a/src/glu/sgi/libnurbs/internals/maplist.cc +++ b/src/glu/sgi/libnurbs/internals/maplist.cc @@ -44,7 +44,6 @@ #include "nurbsconsts.h" #include "maplist.h" #include "mapdesc.h" -#include "backend.h" Maplist::Maplist( Backend& b ) : mapdescPool( sizeof( Mapdesc ), 10, "mapdesc pool" ), diff --git a/src/glu/sgi/libnurbs/internals/mesher.cc b/src/glu/sgi/libnurbs/internals/mesher.cc index 9cc436adbf..b2d83f4128 100644 --- a/src/glu/sgi/libnurbs/internals/mesher.cc +++ b/src/glu/sgi/libnurbs/internals/mesher.cc @@ -58,6 +58,9 @@ Mesher::Mesher( Backend& b ) { stacksize = 0; vdata = 0; + last[0] = 0; + last[1] = 0; + itop = 0; lastedge = 0; //needed to prevent purify UMR } diff --git a/src/glu/sgi/libnurbs/internals/patchlist.cc b/src/glu/sgi/libnurbs/internals/patchlist.cc index 989d2dd00a..6a400ab6f7 100644 --- a/src/glu/sgi/libnurbs/internals/patchlist.cc +++ b/src/glu/sgi/libnurbs/internals/patchlist.cc @@ -44,7 +44,6 @@ #include "quilt.h" #include "patchlist.h" #include "patch.h" -#include "nurbsconsts.h" Patchlist::Patchlist( Quilt *quilts, REAL *pta, REAL *ptb ) { diff --git a/src/glu/sgi/libnurbs/internals/quilt.cc b/src/glu/sgi/libnurbs/internals/quilt.cc index 4fc58b7473..d16f4bfec0 100644 --- a/src/glu/sgi/libnurbs/internals/quilt.cc +++ b/src/glu/sgi/libnurbs/internals/quilt.cc @@ -44,9 +44,7 @@ #include "backend.h" #include "mapdesc.h" #include "flist.h" -#include "knotvector.h" #include "patchlist.h" -#include "math.h" //fglu_abs() #include "simplemath.h" //min() /* local preprocessor definitions */ diff --git a/src/glu/sgi/libnurbs/internals/reader.cc b/src/glu/sgi/libnurbs/internals/reader.cc index 6135eef60e..c59240d26a 100644 --- a/src/glu/sgi/libnurbs/internals/reader.cc +++ b/src/glu/sgi/libnurbs/internals/reader.cc @@ -64,6 +64,7 @@ O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, owner = 0; pts = trimpts; npts = (int) count; + save = 0; int i; /* copy user data into internal trimming data structures */ @@ -115,6 +116,7 @@ O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, owner = 0; pts = trimpts; npts = (int) count; + save = 0; /* copy user data into internal trimming data structures */ switch( _type ) { diff --git a/src/glu/sgi/libnurbs/internals/renderhints.cc b/src/glu/sgi/libnurbs/internals/renderhints.cc index a3aa62d42c..4b347ebc7f 100644 --- a/src/glu/sgi/libnurbs/internals/renderhints.cc +++ b/src/glu/sgi/libnurbs/internals/renderhints.cc @@ -40,7 +40,6 @@ #include "glimports.h" #include "mystdio.h" #include "renderhints.h" -#include "defines.h" #include "nurbsconsts.h" @@ -54,6 +53,10 @@ Renderhints::Renderhints() errorchecking = N_MSG; subdivisions = 6.0; tmp1 = 0.0; + displaydomain = 0; + maxsubdivisions = (int) subdivisions; + wiretris = 0; + wirequads = 0; } void diff --git a/src/glu/sgi/libnurbs/internals/simplemath.h b/src/glu/sgi/libnurbs/internals/simplemath.h index 0a060c57ea..d00062dc70 100644 --- a/src/glu/sgi/libnurbs/internals/simplemath.h +++ b/src/glu/sgi/libnurbs/internals/simplemath.h @@ -38,6 +38,8 @@ /* simple inline routines */ +#include "types.h" + inline int max( int x, int y ) { return ( x < y ) ? y : x; } diff --git a/src/glu/sgi/libnurbs/internals/slicer.cc b/src/glu/sgi/libnurbs/internals/slicer.cc index 27d2a650d1..1b18d73c17 100644 --- a/src/glu/sgi/libnurbs/internals/slicer.cc +++ b/src/glu/sgi/libnurbs/internals/slicer.cc @@ -1181,6 +1181,10 @@ void Slicer::slice(Arc_ptr loop) Slicer::Slicer( Backend &b ) : CoveAndTiler( b ), Mesher( b ), backend( b ) { + oneOverDu = 0; + du = 0; + dv = 0; + isolines = 0; ulinear = 0; vlinear = 0; } diff --git a/src/glu/sgi/libnurbs/internals/trimregion.cc b/src/glu/sgi/libnurbs/internals/trimregion.cc index efe7893569..4aeb5eeac1 100644 --- a/src/glu/sgi/libnurbs/internals/trimregion.cc +++ b/src/glu/sgi/libnurbs/internals/trimregion.cc @@ -41,7 +41,6 @@ #include "myassert.h" #include "mystdio.h" #include "trimregion.h" -#include "backend.h" TrimRegion::TrimRegion( void ) { diff --git a/src/glu/sgi/libutil/error.c b/src/glu/sgi/libutil/error.c index e734818ed6..7212748450 100644 --- a/src/glu/sgi/libutil/error.c +++ b/src/glu/sgi/libutil/error.c @@ -31,8 +31,6 @@ #include "gluos.h" #include "gluint.h" #include <GL/glu.h> -#include <stdio.h> -#include <stdlib.h> struct token_string diff --git a/src/glu/sgi/libutil/mipmap.c b/src/glu/sgi/libutil/mipmap.c index d1fd5a7d72..8e63eaaad7 100644 --- a/src/glu/sgi/libutil/mipmap.c +++ b/src/glu/sgi/libutil/mipmap.c @@ -36,7 +36,6 @@ #include <string.h> #include <limits.h> /* UINT_MAX */ #include <math.h> -#include "gluint.h" typedef union { unsigned char ub[4]; diff --git a/src/glut/glx/SConscript b/src/glut/glx/SConscript index 5234e6d58a..9363b5ca5c 100644 --- a/src/glut/glx/SConscript +++ b/src/glut/glx/SConscript @@ -105,5 +105,7 @@ env.InstallSharedLibrary(glut, version=(3, 7, 1)) if env['platform'] == 'windows': glut = env.FindIxes(glut, 'LIBPREFIX', 'LIBSUFFIX') +else: + glut = env.FindIxes(glut, 'SHLIBPREFIX', 'SHLIBSUFFIX') Export('glut') diff --git a/src/glut/glx/glut_fullscrn.c b/src/glut/glx/glut_fullscrn.c index aab3b48763..78a7a6148b 100644 --- a/src/glut/glx/glut_fullscrn.c +++ b/src/glut/glx/glut_fullscrn.c @@ -14,7 +14,6 @@ #if !defined(_WIN32) #include <X11/Xlib.h> -#include <X11/Xatom.h> #endif /* SGI optimization introduced in IRIX 6.3 to avoid X server diff --git a/src/glut/glx/glut_gamemode.c b/src/glut/glx/glut_gamemode.c index 3ffeafee57..4a92099f3f 100644 --- a/src/glut/glx/glut_gamemode.c +++ b/src/glut/glx/glut_gamemode.c @@ -18,7 +18,6 @@ #ifndef _WIN32 #include <X11/Xlib.h> -#include <X11/Xatom.h> /* SGI optimization introduced in IRIX 6.3 to avoid X server round trips for interning common X atoms. */ diff --git a/src/glut/glx/glut_init.c b/src/glut/glx/glut_init.c index 78843e93bc..842aefc93c 100644 --- a/src/glut/glx/glut_init.c +++ b/src/glut/glx/glut_init.c @@ -15,7 +15,6 @@ #if !defined(_WIN32) #include <X11/Xlib.h> -#include <X11/Xatom.h> #endif /* SGI optimization introduced in IRIX 6.3 to avoid X server diff --git a/src/glut/glx/glut_menu2.c b/src/glut/glx/glut_menu2.c index 969b8120b4..3a66101bc4 100644 --- a/src/glut/glx/glut_menu2.c +++ b/src/glut/glx/glut_menu2.c @@ -25,7 +25,6 @@ #include <X11/Xlib.h> #include "glutint.h" -#include "layerutil.h" /* CENTRY */ /* DEPRICATED, use glutMenuStatusFunc instead. */ diff --git a/src/glut/glx/glut_overlay.c b/src/glut/glx/glut_overlay.c index 837bbc3cb2..db1abe005d 100644 --- a/src/glut/glx/glut_overlay.c +++ b/src/glut/glx/glut_overlay.c @@ -17,7 +17,6 @@ #if !defined(_WIN32) #include <X11/Xlib.h> #include <X11/Xutil.h> -#include <X11/Xatom.h> /* for XA_RGB_DEFAULT_MAP atom */ #if defined (__vms) #include <Xmu/StdCmap.h> /* for XmuLookupStandardColormap */ #else diff --git a/src/glut/glx/layerutil.c b/src/glut/glx/layerutil.c index 26ba0b6029..36d43e59f0 100644 --- a/src/glut/glx/layerutil.c +++ b/src/glut/glx/layerutil.c @@ -13,7 +13,6 @@ /* SGI optimization introduced in IRIX 6.3 to avoid X server round trips for interning common X atoms. */ -#include <X11/Xatom.h> #if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS) #include <X11/SGIFastAtom.h> #else diff --git a/src/glx/Makefile b/src/glx/Makefile index e0ab4a0240..6711fdc61b 100644 --- a/src/glx/Makefile +++ b/src/glx/Makefile @@ -1,12 +1,97 @@ - TOP = ../.. include $(TOP)/configs/current +EXTRA_DEFINES = -DXF86VIDMODE -D_REENTRANT \ + -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" + +SOURCES = \ + glcontextmodes.c \ + clientattrib.c \ + compsize.c \ + eval.c \ + glxcmds.c \ + glxcurrent.c \ + glxext.c \ + glxextensions.c \ + indirect.c \ + indirect_init.c \ + indirect_size.c \ + indirect_window_pos.c \ + indirect_texture_compression.c \ + indirect_transpose_matrix.c \ + indirect_vertex_array.c \ + indirect_vertex_program.c \ + pixel.c \ + pixelstore.c \ + render2.c \ + renderpix.c \ + single2.c \ + singlepix.c \ + vertarr.c \ + xfont.c \ + glx_pbuffer.c \ + glx_query.c \ + drisw_glx.c \ + dri_common.c \ + dri_glx.c \ + XF86dri.c \ + glxhash.c \ + dri2_glx.c \ + dri2.c + +GLAPI_LIB = $(TOP)/src/mesa/libglapi.a + +OBJECTS = $(SOURCES:.c=.o) + +INCLUDES = -I. \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/glapi \ + $(LIBDRM_CFLAGS) \ + $(DRI2PROTO_CFLAGS) \ + $(X11_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ + +##### TARGETS ##### + +default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + +# Make libGL +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(GLAPI_LIB) Makefile + $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major 1 -minor 2 $(MKLIB_OPTIONS) \ + -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/lib$(GL_LIB).1.dylib \ + $(GL_LIB_DEPS) $(OBJECTS) $(GLAPI_LIB) + +$(GLAPI_LIB): + @$(MAKE) -C $(TOP)/src/mesa libglapi.a + +depend: $(SOURCES) Makefile + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) + -default: - cd mini && $(MAKE) +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find $(TOP)/include` +install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + $(MAKE) -C $(TOP)/src/mesa install-libgl +# Remove .o and backup files clean: - -@cd mini && $(MAKE) clean + -rm -f $(TOP)/$(LIB_DIR)/libGL.so* + -rm -f *.o *~ + -rm -f depend depend.bak +-include depend diff --git a/src/glx/x11/XF86dri.c b/src/glx/XF86dri.c index 90a5dd81ea..248d96ac5d 100644 --- a/src/glx/x11/XF86dri.c +++ b/src/glx/XF86dri.c @@ -104,7 +104,7 @@ XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info) #define TRACE(msg) #endif -PUBLIC Bool +Bool XF86DRIQueryExtension(Display * dpy, int *event_basep, int *error_basep) { @@ -123,7 +123,7 @@ XF86DRIQueryExtension(Display * dpy, int *event_basep, } } -PUBLIC Bool +Bool XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, int *patchVersion) { @@ -153,7 +153,7 @@ XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion, return True; } -PUBLIC Bool +Bool XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen, Bool * isCapable) { @@ -182,7 +182,7 @@ XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen, return True; } -PUBLIC Bool +Bool XF86DRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, char **busIdString) { @@ -230,7 +230,7 @@ XF86DRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA, return True; } -PUBLIC Bool +Bool XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic) { XExtDisplayInfo *info = find_display(dpy); @@ -259,7 +259,7 @@ XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic) return True; } -PUBLIC Bool +Bool XF86DRICloseConnection(Display * dpy, int screen) { XExtDisplayInfo *info = find_display(dpy); @@ -280,7 +280,7 @@ XF86DRICloseConnection(Display * dpy, int screen) return True; } -PUBLIC Bool +Bool XF86DRIGetClientDriverName(Display * dpy, int screen, int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, @@ -331,7 +331,7 @@ XF86DRIGetClientDriverName(Display * dpy, int screen, return True; } -PUBLIC Bool +Bool XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID, XID * context, drm_context_t * hHWContext) { @@ -363,7 +363,7 @@ XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID, return True; } -PUBLIC Bool +Bool XF86DRICreateContext(Display * dpy, int screen, Visual * visual, XID * context, drm_context_t * hHWContext) { @@ -371,7 +371,7 @@ XF86DRICreateContext(Display * dpy, int screen, Visual * visual, context, hHWContext); } -PUBLIC Bool +Bool XF86DRIDestroyContext(Display * dpy, int screen, XID context) { XExtDisplayInfo *info = find_display(dpy); @@ -392,7 +392,7 @@ XF86DRIDestroyContext(Display * dpy, int screen, XID context) return True; } -PUBLIC Bool +Bool XF86DRICreateDrawable(Display * dpy, int screen, XID drawable, drm_drawable_t * hHWDrawable) { @@ -428,7 +428,7 @@ noopErrorHandler(Display * dpy, XErrorEvent * xerr) return 0; } -PUBLIC Bool +Bool XF86DRIDestroyDrawable(Display * dpy, int screen, XID drawable) { XExtDisplayInfo *info = find_display(dpy); @@ -468,7 +468,7 @@ XF86DRIDestroyDrawable(Display * dpy, int screen, XID drawable) return True; } -PUBLIC Bool +Bool XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, unsigned int *index, unsigned int *stamp, int *X, int *Y, int *W, int *H, @@ -557,7 +557,7 @@ XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable, return True; } -PUBLIC Bool +Bool XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer, int *fbOrigin, int *fbSize, int *fbStride, int *devPrivateSize, void **pDevPrivate) @@ -612,7 +612,7 @@ XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer, return True; } -PUBLIC Bool +Bool XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable) { /* This function and the underlying X protocol are deprecated. @@ -623,7 +623,7 @@ XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable) return False; } -PUBLIC Bool +Bool XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable) { /* This function and the underlying X protocol are deprecated. diff --git a/src/glx/x11/clientattrib.c b/src/glx/clientattrib.c index a7dfb53486..a7dfb53486 100644 --- a/src/glx/x11/clientattrib.c +++ b/src/glx/clientattrib.c diff --git a/src/glx/x11/compsize.c b/src/glx/compsize.c index eca572feb3..5ba6dc919e 100644 --- a/src/glx/x11/compsize.c +++ b/src/glx/compsize.c @@ -29,7 +29,6 @@ */ #include <GL/gl.h> -#include "indirect_size.h" #include "glxclient.h" /* diff --git a/src/glx/x11/dri2.c b/src/glx/dri2.c index dad04470a0..91053d3fb6 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/dri2.c @@ -34,12 +34,15 @@ #ifdef GLX_DIRECT_RENDERING #define NEED_REPLIES +#include <stdio.h> #include <X11/Xlibint.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> #include <X11/extensions/dri2proto.h> #include "xf86drm.h" #include "dri2.h" +#include "glxclient.h" +#include "GL/glxext.h" /* Allow the build to work with an older versions of dri2proto.h and * dri2tokens.h. @@ -55,6 +58,11 @@ static char dri2ExtensionName[] = DRI2_NAME; static XExtensionInfo *dri2Info; static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) +static Bool +DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire); +static Status +DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire); + static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_gc */ NULL, /* copy_gc */ @@ -63,8 +71,8 @@ static /* const */ XExtensionHooks dri2ExtensionHooks = { NULL, /* create_font */ NULL, /* free_font */ DRI2CloseDisplay, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ + DRI2WireToEvent, /* wire_to_event */ + DRI2EventToWire, /* event_to_wire */ NULL, /* error */ NULL, /* error_string */ }; @@ -73,7 +81,78 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, - 0, NULL) + 1, NULL) + +static Bool +DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); + static int glx_event_base; + static Bool found_glx_info = False; + + XextCheckExtension(dpy, info, dri2ExtensionName, False); + + switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { + +#ifdef X_DRI2SwapBuffers + case DRI2_BufferSwapComplete: + { + GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; + xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; + aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire); + aevent->type = + (glx_info->codes->first_event + GLX_BufferSwapComplete) & 0x75; + aevent->send_event = (awire->type & 0x80) != 0; + aevent->display = dpy; + aevent->drawable = awire->drawable; + switch (awire->event_type) { + case DRI2_EXCHANGE_COMPLETE: + aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL; + break; + case DRI2_BLIT_COMPLETE: + aevent->event_type = GLX_BLIT_COMPLETE_INTEL; + break; + case DRI2_FLIP_COMPLETE: + aevent->event_type = GLX_FLIP_COMPLETE_INTEL; + break; + default: + /* unknown swap completion type */ + return False; + } + aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; + aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; + aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; + return True; + } +#endif + + default: + /* client doesn't support server event */ + break; + } + + return False; +} + +/* We don't actually support this. It doesn't make sense for clients to + * send each other DRI2 events. + */ +static Status +DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + + XextCheckExtension(dpy, info, dri2ExtensionName, False); + + switch (event->type) { + default: + /* client doesn't support server event */ + break; + } + + return Success; +} Bool DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase) @@ -380,4 +459,187 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, SyncHandle(); } +#ifdef X_DRI2SwapBuffers +static void +load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor, + CARD64 remainder) +{ + req->target_msc_hi = target >> 32; + req->target_msc_lo = target & 0xffffffff; + req->divisor_hi = divisor >> 32; + req->divisor_lo = divisor & 0xffffffff; + req->remainder_hi = remainder >> 32; + req->remainder_lo = remainder & 0xffffffff; +} + +static CARD64 +vals_to_card64(CARD32 lo, CARD32 hi) +{ + return (CARD64)hi << 32 | lo; +} + +void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, + CARD64 divisor, CARD64 remainder, CARD64 *count) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapBuffersReq *req; + xDRI2SwapBuffersReply rep; + + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2SwapBuffers, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2SwapBuffers; + req->drawable = drawable; + load_swap_req(req, target_msc, divisor, remainder); + + _XReply(dpy, (xReply *)&rep, 0, xFalse); + + *count = vals_to_card64(rep.swap_lo, rep.swap_hi); + + UnlockDisplay(dpy); + SyncHandle(); +} +#endif + +#ifdef X_DRI2GetMSC +Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, + CARD64 *sbc) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2GetMSCReq *req; + xDRI2MSCReply rep; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2GetMSC, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2GetMSC; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *ust = vals_to_card64(rep.ust_lo, rep.ust_hi); + *msc = vals_to_card64(rep.msc_lo, rep.msc_hi); + *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi); + + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} +#endif + +#ifdef X_DRI2WaitMSC +static void +load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor, + CARD64 remainder) +{ + req->target_msc_hi = target >> 32; + req->target_msc_lo = target & 0xffffffff; + req->divisor_hi = divisor >> 32; + req->divisor_lo = divisor & 0xffffffff; + req->remainder_hi = remainder >> 32; + req->remainder_lo = remainder & 0xffffffff; +} + +Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, + CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2WaitMSCReq *req; + xDRI2MSCReply rep; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2WaitMSC, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2WaitMSC; + req->drawable = drawable; + load_msc_req(req, target_msc, divisor, remainder); + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo; + *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo; + *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo; + + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} +#endif + +#ifdef X_DRI2WaitSBC +static void +load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target) +{ + req->target_sbc_hi = target >> 32; + req->target_sbc_lo = target & 0xffffffff; +} + +Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, + CARD64 *msc, CARD64 *sbc) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2WaitSBCReq *req; + xDRI2MSCReply rep; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2WaitSBC, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2WaitSBC; + req->drawable = drawable; + load_sbc_req(req, target_sbc); + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo; + *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo; + *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo; + + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} +#endif + +#ifdef X_DRI2SwapInterval +void DRI2SwapInterval(Display *dpy, XID drawable, int interval) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapIntervalReq *req; + + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2SwapInterval, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2SwapInterval; + req->drawable = drawable; + req->interval = interval; + UnlockDisplay(dpy); + SyncHandle(); +} +#endif + #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri2.h b/src/glx/dri2.h index a6fe66e136..114e9f8f96 100644 --- a/src/glx/x11/dri2.h +++ b/src/glx/dri2.h @@ -85,4 +85,22 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src); +extern void +DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, + CARD64 remainder, CARD64 *count); + +extern Bool +DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc); + +extern Bool +DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor, + CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc); + +extern Bool +DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, + CARD64 *msc, CARD64 *sbc); + +extern void +DRI2SwapInterval(Display *dpy, XID drawable, int interval); + #endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/dri2_glx.c index 89efe3ab29..15a3ea5907 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -35,8 +35,9 @@ #include <X11/Xlib.h> #include <X11/extensions/Xfixes.h> #include <X11/extensions/Xdamage.h> +#include "glapi.h" #include "glxclient.h" -#include "glcontextmodes.h" +#include <X11/extensions/dri2proto.h> #include "xf86dri.h" #include <dlfcn.h> #include <fcntl.h> @@ -46,6 +47,7 @@ #include "xf86drm.h" #include "dri2.h" #include "dri_common.h" +#include "../../mesa/drivers/dri/common/dri_util.h" #undef DRI2_MINOR #define DRI2_MINOR 1 @@ -64,6 +66,7 @@ struct __GLXDRIdisplayPrivateRec int driMajor; int driMinor; int driPatch; + int swapAvailable; }; struct __GLXDRIcontextPrivateRec @@ -81,6 +84,7 @@ struct __GLXDRIdrawablePrivateRec int width, height; int have_back; int have_fake_front; + int swap_interval; }; static void dri2WaitX(__GLXDRIdrawable * pdraw); @@ -197,9 +201,31 @@ dri2CreateDrawable(__GLXscreenConfigs * psc, return &pdraw->base; } +static int +dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, + int64_t *ust, int64_t *msc, int64_t *sbc) +{ + return DRI2GetMSC(psc->dpy, pdraw->xDrawable, ust, msc, sbc); +} + +static int +dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, + int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) +{ + return DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor, + remainder, ust, msc, sbc); +} + +static int +dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, + int64_t *msc, int64_t *sbc) +{ + return DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable, target_sbc, ust, msc, + sbc); +} + static void -dri2CopySubBuffer(__GLXDRIdrawable * pdraw, - int x, int y, int width, int height) +dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; XRectangle xrect; @@ -232,15 +258,7 @@ dri2CopySubBuffer(__GLXDRIdrawable * pdraw, } static void -dri2SwapBuffers(__GLXDRIdrawable * pdraw) -{ - __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; - - dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); -} - -static void -dri2WaitX(__GLXDRIdrawable * pdraw) +dri2WaitX(__GLXDRIdrawable *pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; XRectangle xrect; @@ -342,6 +360,40 @@ process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers, } +static int64_t +dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, + int64_t remainder) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy); + __GLXDRIdisplayPrivate *pdp = + (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; + int64_t ret; + +#ifdef __DRI2_FLUSH + if (pdraw->psc->f) + (*pdraw->psc->f->flush)(pdraw->driDrawable); +#endif + + /* Old servers can't handle swapbuffers */ + if (!pdp->swapAvailable) { + dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + return 0; + } + +#ifdef X_DRI2SwapBuffers + DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor, + remainder, &ret); +#endif + +#if __DRI2_FLUSH_VERSION >= 2 + if (pdraw->psc->f) + (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); +#endif + + return ret; +} + static __DRIbuffer * dri2GetBuffers(__DRIdrawable * driDrawable, int *width, int *height, @@ -390,6 +442,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, return pdraw->buffers; } +static void +dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + + DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval); + priv->swap_interval = interval; +} + +static unsigned int +dri2GetSwapInterval(__GLXDRIdrawable *pdraw) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + + return priv->swap_interval; +} + static const __DRIdri2LoaderExtension dri2LoaderExtension = { {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION}, dri2GetBuffers, @@ -437,8 +506,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, psc->ext_list_first_time = GL_TRUE; if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen), - &driverName, &deviceName)) + &driverName, &deviceName)) { + XFree(psp); return NULL; + } psc->driver = driOpenDriver(driverName); if (psc->driver == NULL) { @@ -454,9 +525,9 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_CORE) == 0) - psc->core = (__DRIcoreExtension *) extensions[i]; + psc->core = (__DRIcoreExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_DRI2) == 0) - psc->dri2 = (__DRIdri2Extension *) extensions[i]; + psc->dri2 = (__DRIdri2Extension *) extensions[i]; } if (psc->core == NULL || psc->dri2 == NULL) { @@ -467,17 +538,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, psc->fd = open(deviceName, O_RDWR); if (psc->fd < 0) { ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); - return NULL; + goto handle_error; } if (drmGetMagic(psc->fd, &magic)) { ErrorMessageF("failed to get magic\n"); - return NULL; + goto handle_error; } if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { ErrorMessageF("failed to authenticate magic %d\n", magic); - return NULL; + goto handle_error; } /* If the server does not support the protocol for @@ -485,16 +556,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, */ psc->__driScreen = psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1) - ? loader_extensions_old - : loader_extensions), - &driver_configs, psc); + ? loader_extensions_old + : loader_extensions), + &driver_configs, psc); if (psc->__driScreen == NULL) { ErrorMessageF("failed to create dri screen\n"); - return NULL; + goto handle_error; } - driBindExtensions(psc, 1); + driBindCommonExtensions(psc); + dri2BindExtensions(psc); psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); @@ -507,6 +579,25 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, psp->swapBuffers = dri2SwapBuffers; psp->waitGL = dri2WaitGL; psp->waitX = dri2WaitX; + psp->getDrawableMSC = NULL; + psp->waitForMSC = NULL; + psp->waitForSBC = NULL; + psp->setSwapInterval = NULL; + psp->getSwapInterval = NULL; + + if (pdp->driMinor >= 2) { +#ifdef X_DRI2GetMSC + psp->getDrawableMSC = dri2DrawableGetMSC; +#endif +#ifdef X_DRI2WaitMSC + psp->waitForMSC = dri2WaitForMSC; + psp->waitForSBC = dri2WaitForSBC; +#endif +#ifdef X_DRI2SwapInterval + psp->setSwapInterval = dri2SetSwapInterval; + psp->getSwapInterval = dri2GetSwapInterval; +#endif + } /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always * available.*/ @@ -518,9 +609,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, return psp; - handle_error: +handle_error: Xfree(driverName); Xfree(deviceName); + XFree(psp); /* FIXME: clean up here */ @@ -559,6 +651,11 @@ dri2CreateDisplay(Display * dpy) } pdp->driPatch = 0; + pdp->swapAvailable = 0; +#ifdef X_DRI2SwapBuffers + if (pdp->driMinor >= 2) + pdp->swapAvailable = 1; +#endif pdp->base.destroyDisplay = dri2DestroyDisplay; pdp->base.createScreen = dri2CreateScreen; diff --git a/src/glx/x11/dri_common.c b/src/glx/dri_common.c index 9c825ad74a..e4034161bb 100644 --- a/src/glx/x11/dri_common.c +++ b/src/glx/dri_common.c @@ -336,8 +336,9 @@ driConvertConfigs(const __DRIcoreExtension * core, return head.next; } +/* Bind DRI1 specific extensions */ _X_HIDDEN void -driBindExtensions(__GLXscreenConfigs * psc, int dri2) +driBindExtensions(__GLXscreenConfigs *psc) { const __DRIextension **extensions; int i; @@ -345,35 +346,13 @@ driBindExtensions(__GLXscreenConfigs * psc, int dri2) extensions = psc->core->getExtensions(psc->__driScreen); for (i = 0; extensions[i]; i++) { -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - psc->driCopySubBuffer = - (__DRIcopySubBufferExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); - } -#endif - #ifdef __DRI_SWAP_CONTROL /* No DRI2 support for swap_control at the moment, since SwapBuffers * is done by the X server */ - if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) { - psc->swapControl = (__DRIswapControlExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); - __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); - } -#endif - -#ifdef __DRI_ALLOCATE - if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { - psc->allocate = (__DRIallocateExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); - } -#endif - -#ifdef __DRI_FRAME_TRACKING - if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { - psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); + if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { + psc->swapControl = (__DRIswapControlExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); + __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); } #endif @@ -390,23 +369,77 @@ driBindExtensions(__GLXscreenConfigs * psc, int dri2) * GLX_OML_sync_control if implemented. */ #endif -#ifdef __DRI_READ_DRAWABLE - if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { - __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); - } -#endif + /* Ignore unknown extensions */ + } +} +/* Bind DRI2 specific extensions */ +_X_HIDDEN void +dri2BindExtensions(__GLXscreenConfigs *psc) +{ + const __DRIextension **extensions; + int i; + + extensions = psc->core->getExtensions(psc->__driScreen); + + for (i = 0; extensions[i]; i++) { #ifdef __DRI_TEX_BUFFER - if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) { - psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); + if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) { + psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); } #endif + __glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); + __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); + __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); + + /* FIXME: if DRI2 version supports it... */ + __glXEnableDirectExtension(psc, "INTEL_swap_event"); + #ifdef __DRI2_FLUSH - if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) { - psc->f = (__DRI2flushExtension *) extensions[i]; - /* internal driver extension, no GL extension exposed */ + if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) { + psc->f = (__DRI2flushExtension *) extensions[i]; + /* internal driver extension, no GL extension exposed */ + } +#endif + } +} + +/* Bind extensions common to DRI1 and DRI2 */ +_X_HIDDEN void +driBindCommonExtensions(__GLXscreenConfigs *psc) +{ + const __DRIextension **extensions; + int i; + + extensions = psc->core->getExtensions(psc->__driScreen); + + for (i = 0; extensions[i]; i++) { +#ifdef __DRI_COPY_SUB_BUFFER + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { + psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer"); + } +#endif + +#ifdef __DRI_ALLOCATE + if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { + psc->allocate = (__DRIallocateExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); + } +#endif + +#ifdef __DRI_FRAME_TRACKING + if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { + psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; + __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); + } +#endif + +#ifdef __DRI_READ_DRAWABLE + if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { + __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); } #endif diff --git a/src/glx/x11/dri_common.h b/src/glx/dri_common.h index 61ac9c6416..bb178db787 100644 --- a/src/glx/x11/dri_common.h +++ b/src/glx/dri_common.h @@ -56,6 +56,8 @@ extern void ErrorMessageF(const char *f, ...); extern void *driOpenDriver(const char *driverName); -extern void driBindExtensions(__GLXscreenConfigs * psc, int dri2); +extern void driBindExtensions(__GLXscreenConfigs * psc); +extern void dri2BindExtensions(__GLXscreenConfigs * psc); +extern void driBindCommonExtensions(__GLXscreenConfigs * psc); #endif /* _DRI_COMMON_H */ diff --git a/src/glx/x11/dri_glx.c b/src/glx/dri_glx.c index a890feeab2..0ff53c324f 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/dri_glx.c @@ -38,7 +38,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <X11/extensions/Xfixes.h> #include <X11/extensions/Xdamage.h> #include "glxclient.h" -#include "glcontextmodes.h" #include "xf86dri.h" #include "dri2.h" #include "sarea.h" @@ -607,10 +606,12 @@ driCreateDrawable(__GLXscreenConfigs * psc, return pdraw; } -static void -driSwapBuffers(__GLXDRIdrawable * pdraw) +static int64_t +driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2, + int64_t unused3) { (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable); + return 0; } static void @@ -670,9 +671,9 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, for (i = 0; extensions[i]; i++) { if (strcmp(extensions[i]->name, __DRI_CORE) == 0) - psc->core = (__DRIcoreExtension *) extensions[i]; + psc->core = (__DRIcoreExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0) - psc->legacy = (__DRIlegacyExtension *) extensions[i]; + psc->legacy = (__DRIlegacyExtension *) extensions[i]; } if (psc->core == NULL || psc->legacy == NULL) { @@ -688,7 +689,9 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, return NULL; } - driBindExtensions(psc, 0); + driBindExtensions(psc); + driBindCommonExtensions(psc); + if (psc->driCopySubBuffer) psp->copySubBuffer = driCopySubBuffer; diff --git a/src/glx/x11/drisw_glx.c b/src/glx/drisw_glx.c index 1866b2cc87..eed9a8c472 100644 --- a/src/glx/x11/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -25,7 +25,6 @@ #include <X11/Xlib.h> #include "glxclient.h" -#include "glcontextmodes.h" #include <dlfcn.h> #include "dri_common.h" @@ -398,7 +397,8 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, goto handle_error; } - driBindExtensions(psc, 0); + driBindExtensions(psc); + driBindCommonExtensions(psc); psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); diff --git a/src/glx/x11/eval.c b/src/glx/eval.c index 226fb7df2e..226fb7df2e 100644 --- a/src/glx/x11/eval.c +++ b/src/glx/eval.c diff --git a/src/glx/x11/glcontextmodes.c b/src/glx/glcontextmodes.c index 232031c2ca..232031c2ca 100644 --- a/src/glx/x11/glcontextmodes.c +++ b/src/glx/glcontextmodes.c diff --git a/src/glx/x11/glcontextmodes.h b/src/glx/glcontextmodes.h index 6676ae306c..6676ae306c 100644 --- a/src/glx/x11/glcontextmodes.h +++ b/src/glx/glcontextmodes.h diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 501500afc3..a0a02238b0 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -35,9 +35,7 @@ #include <X11/extensions/Xext.h> #include <assert.h> #include <string.h> -#include "glapi.h" #include "glxextensions.h" -#include "glcontextmodes.h" #define WARN_ONCE_GLX_1_3(a, b) { \ static int warned=1; \ diff --git a/src/glx/x11/glx_query.c b/src/glx/glx_query.c index efad13d376..efad13d376 100644 --- a/src/glx/x11/glx_query.c +++ b/src/glx/glx_query.c diff --git a/src/glx/x11/glxclient.h b/src/glx/glxclient.h index 00ee14fb05..e0b286b688 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/glxclient.h @@ -41,6 +41,7 @@ #define NEED_EVENTS #include <X11/Xproto.h> #include <X11/Xlibint.h> +#include <X11/extensions/extutil.h> #define GLX_GLXEXT_PROTOTYPES #include <GL/glx.h> #include <GL/glxext.h> @@ -121,26 +122,35 @@ struct __GLXDRIdisplayRec __GLXdisplayPrivate * priv); }; -struct __GLXDRIscreenRec -{ - - void (*destroyScreen) (__GLXscreenConfigs * psc); - - __GLXDRIcontext *(*createContext) (__GLXscreenConfigs * psc, - const __GLcontextModes * mode, - GLXContext gc, - GLXContext shareList, int renderType); - - __GLXDRIdrawable *(*createDrawable) (__GLXscreenConfigs * psc, - XID drawable, - GLXDrawable glxDrawable, - const __GLcontextModes * modes); - - void (*swapBuffers) (__GLXDRIdrawable * pdraw); - void (*copySubBuffer) (__GLXDRIdrawable * pdraw, - int x, int y, int width, int height); - void (*waitX) (__GLXDRIdrawable * pdraw); - void (*waitGL) (__GLXDRIdrawable * pdraw); +struct __GLXDRIscreenRec { + + void (*destroyScreen)(__GLXscreenConfigs *psc); + + __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc, + const __GLcontextModes *mode, + GLXContext gc, + GLXContext shareList, int renderType); + + __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, + XID drawable, + GLXDrawable glxDrawable, + const __GLcontextModes *modes); + + int64_t (*swapBuffers)(__GLXDRIdrawable *pdraw, int64_t target_msc, + int64_t divisor, int64_t remainder); + void (*copySubBuffer)(__GLXDRIdrawable *pdraw, + int x, int y, int width, int height); + void (*waitX)(__GLXDRIdrawable *pdraw); + void (*waitGL)(__GLXDRIdrawable *pdraw); + int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, + int64_t *ust, int64_t *msc, int64_t *sbc); + int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc, + int64_t divisor, int64_t remainder, int64_t *ust, + int64_t *msc, int64_t *sbc); + int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, + int64_t *msc, int64_t *sbc); + void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval); + int (*getSwapInterval)(__GLXDRIdrawable *pdraw); }; struct __GLXDRIcontextRec @@ -784,6 +794,10 @@ extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, GLboolean __driGetMscRateOML(__DRIdrawable * draw, int32_t * numerator, int32_t * denominator, void *private); + +/* So that dri2.c:DRI2WireToEvent() can access + * glx_info->codes->first_event */ +XExtDisplayInfo *__glXFindDisplay (Display *dpy); #endif #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/glxcmds.c index d1c68dd02e..c3be974ea9 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/glxcmds.c @@ -982,7 +982,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) if (pdraw != NULL) { glFlush(); - (*pdraw->psc->driScreen->swapBuffers) (pdraw); + (*pdraw->psc->driScreen->swapBuffers)(pdraw, 0, 0, 0); return; } #endif @@ -1884,6 +1884,7 @@ __glXSwapIntervalSGI(int interval) { xGLXVendorPrivateReq *req; GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc; Display *dpy; CARD32 *interval_ptr; CARD8 opcode; @@ -1898,20 +1899,30 @@ __glXSwapIntervalSGI(int interval) #ifdef __DRI_SWAP_CONTROL if (gc->driContext) { - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, - gc->screen); + __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, + gc->screen ); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, - gc->currentDrawable, - NULL); + gc->currentDrawable, + NULL); if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); - return 0; + psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); + return 0; } - else { - return GLX_BAD_CONTEXT; + else if (pdraw == NULL) { + return GLX_BAD_CONTEXT; } } #endif + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + + if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, + NULL); + psc->driScreen->setSwapInterval(pdraw, interval); + return 0; + } + dpy = gc->currentDpy; opcode = __glXSetupForCommand(dpy); if (!opcode) { @@ -1943,13 +1954,13 @@ __glXSwapIntervalSGI(int interval) static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); if (interval < 0) { return GLX_BAD_VALUE; } +#ifdef __DRI_SWAP_CONTROL if (gc != NULL && gc->driContext) { __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen); @@ -1963,10 +1974,20 @@ __glXSwapIntervalMESA(unsigned int interval) } } } -#else - (void) interval; #endif + if (gc != NULL && gc->driContext) { + __GLXscreenConfigs *psc; + + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + if (psc->driScreen && psc->driScreen->setSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, NULL); + psc->driScreen->setSwapInterval(pdraw, interval); + return 0; + } + } + return GLX_BAD_CONTEXT; } @@ -1990,6 +2011,16 @@ __glXGetSwapIntervalMESA(void) } } #endif + if (gc != NULL && gc->driContext) { + __GLXscreenConfigs *psc; + + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + if (psc->driScreen && psc->driScreen->getSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, NULL); + return psc->driScreen->getSwapInterval(pdraw); + } + } return 0; } @@ -2102,64 +2133,73 @@ __glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable, static int __glXGetVideoSyncSGI(unsigned int *count) { + int64_t ust, msc, sbc; + int ret; + GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc; + __GLXDRIdrawable *pdraw; + + if (!gc || !gc->driContext) + return GLX_BAD_CONTEXT; + + psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen); + pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry, * FIXME: there should be a GLX encoding for this call. I can find no * FIXME: documentation for the GLX encoding. */ #ifdef __DRI_MEDIA_STREAM_COUNTER - GLXContext gc = __glXGetCurrentContext(); - - - if (gc != NULL && gc->driContext) { - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, - gc->screen); - if (psc->msc && psc->driScreen) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - int64_t temp; - int ret; + if ( psc->msc && psc->driScreen ) { + ret = (*psc->msc->getDrawableMSC)(psc->__driScreen, + pdraw->driDrawable, &msc); + *count = (unsigned) msc; - ret = (*psc->msc->getDrawableMSC) (psc->__driScreen, - pdraw->driDrawable, &temp); - *count = (unsigned) temp; - - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; - } + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } -#else - (void) count; #endif + if (psc->driScreen && psc->driScreen->getDrawableMSC) { + ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc); + *count = (unsigned) msc; + return (ret == True) ? 0 : GLX_BAD_CONTEXT; + } + return GLX_BAD_CONTEXT; } static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { -#ifdef __DRI_MEDIA_STREAM_COUNTER GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc; + __GLXDRIdrawable *pdraw; + int64_t ust, msc, sbc; + int ret; if (divisor <= 0 || remainder < 0) return GLX_BAD_VALUE; - if (gc != NULL && gc->driContext) { - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, - gc->screen); - if (psc->msc != NULL && psc->driScreen) { - __GLXDRIdrawable *pdraw = - GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - int ret; - int64_t msc; - int64_t sbc; - - ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, 0, - divisor, remainder, &msc, &sbc); - *count = (unsigned) msc; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; - } + if (!gc || !gc->driContext) + return GLX_BAD_CONTEXT; + + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + +#ifdef __DRI_MEDIA_STREAM_COUNTER + if (psc->msc != NULL && psc->driScreen ) { + ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0, + divisor, remainder, &msc, &sbc); + *count = (unsigned) msc; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } -#else - (void) count; #endif + if (psc->driScreen && psc->driScreen->waitForMSC) { + ret = psc->driScreen->waitForMSC(pdraw, 0, divisor, remainder, &ust, &msc, + &sbc); + *count = (unsigned) msc; + return (ret == True) ? 0 : GLX_BAD_CONTEXT; + } + return GLX_BAD_CONTEXT; } @@ -2312,27 +2352,29 @@ static Bool __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, int64_t * ust, int64_t * msc, int64_t * sbc) { -#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + int i, ret; + __GLXDRIdrawable *pdraw; + __GLXscreenConfigs *psc; - if (priv != NULL) { - int i; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); - __GLXscreenConfigs *const psc = &priv->screenConfigs[i]; + if (!priv) + return False; - assert((pdraw == NULL) || (i != -1)); - return ((pdraw && psc->sbc && psc->msc) - && ((*psc->msc->getMSC) (psc->driScreen, msc) == 0) - && ((*psc->sbc->getSBC) (pdraw->driDrawable, sbc) == 0) - && (__glXGetUST(ust) == 0)); - } -#else - (void) dpy; - (void) drawable; - (void) ust; - (void) msc; - (void) sbc; + pdraw = GetGLXDRIDrawable(dpy, drawable, &i); + psc = &priv->screenConfigs[i]; + +#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) + if (pdraw && psc->sbc && psc->sbc) + return ( (pdraw && psc->sbc && psc->msc) + && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) + && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) + && (__glXGetUST(ust) == 0) ); #endif + if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) { + ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc); + return ret; + } + return False; } @@ -2440,11 +2482,14 @@ static int64_t __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { -#ifdef __DRI_SWAP_BUFFER_COUNTER + GLXContext gc = __glXGetCurrentContext(); int screen; __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); + if (!pdraw || !gc->driContext) /* no GLX for this */ + return -1; + /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE * error", but it also says "It [glXSwapBuffersMscOML] will return a value * of -1 if the function failed because of errors detected in the input @@ -2455,18 +2500,19 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, if (divisor > 0 && remainder >= divisor) return -1; - if (pdraw != NULL && psc->counters != NULL) - return (*psc->sbc->swapBuffersMSC) (pdraw->driDrawable, target_msc, - divisor, remainder); +#ifdef __DRI_SWAP_BUFFER_COUNTER + if (psc->counters != NULL) + return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, + divisor, remainder); +#endif -#else - (void) dpy; - (void) drawable; - (void) target_msc; - (void) divisor; - (void) remainder; +#ifdef GLX_DIRECT_RENDERING + if (psc->driScreen && psc->driScreen->swapBuffers) + return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor, + remainder); #endif - return 0; + + return -1; } @@ -2476,12 +2522,14 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t remainder, int64_t * ust, int64_t * msc, int64_t * sbc) { -#ifdef __DRI_MEDIA_STREAM_COUNTER - int screen = 0; + int screen; __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); + __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; + fprintf(stderr, "waitmsc: %lld, %lld, %lld\n", target_msc, divisor, + remainder); + /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE * error", but the return type in the spec is Bool. */ @@ -2490,7 +2538,9 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, if (divisor > 0 && remainder >= divisor) return False; +#ifdef __DRI_MEDIA_STREAM_COUNTER if (pdraw != NULL && psc->msc != NULL) { + fprintf(stderr, "dri1 msc\n"); ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc, divisor, remainder, msc, sbc); @@ -2499,16 +2549,14 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, */ return ((ret == 0) && (__glXGetUST(ust) == 0)); } -#else - (void) dpy; - (void) drawable; - (void) target_msc; - (void) divisor; - (void) remainder; - (void) ust; - (void) msc; - (void) sbc; #endif + if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) { + ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder, + ust, msc, sbc); + return ret; + } + + fprintf(stderr, "no drawable??\n"); return False; } @@ -2518,7 +2566,6 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t * ust, int64_t * msc, int64_t * sbc) { -#ifdef __DRI_SWAP_BUFFER_COUNTER int screen; __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); @@ -2529,7 +2576,7 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, */ if (target_sbc < 0) return False; - +#ifdef __DRI_SWAP_BUFFER_COUNTER if (pdraw != NULL && psc->sbc != NULL) { ret = (*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc); @@ -2539,14 +2586,11 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, */ return ((ret == 0) && (__glXGetUST(ust) == 0)); } -#else - (void) dpy; - (void) drawable; - (void) target_sbc; - (void) ust; - (void) msc; - (void) sbc; #endif + if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) { + ret = psc->driScreen->waitForSBC(pdraw, target_sbc, ust, msc, sbc); + return ret; + } return False; } diff --git a/src/glx/x11/glxcurrent.c b/src/glx/glxcurrent.c index fae1bd9fa6..c28360bdde 100644 --- a/src/glx/x11/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -37,10 +37,6 @@ #include "glapi.h" #include "indirect_init.h" -#ifdef GLX_DIRECT_RENDERING -#include "xf86dri.h" -#endif - /* ** We setup some dummy structures here so that the API can be used ** even if no context is current. @@ -162,6 +158,7 @@ __glXSetCurrentContextNull(void) __glXSetCurrentContext(&dummyContext); #ifdef GLX_DIRECT_RENDERING _glapi_set_dispatch(NULL); /* no-op functions */ + _glapi_set_context(NULL); #endif } diff --git a/src/glx/x11/glxext.c b/src/glx/glxext.c index 5633a3e4a2..c2de1a3fff 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/glxext.c @@ -41,7 +41,7 @@ #include "glxclient.h" #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> -#include "glapi.h" +#include <X11/extensions/dri2proto.h> #include "glxextensions.h" #include "glcontextmodes.h" @@ -101,6 +101,10 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes) static XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName, __GLX_NUMBER_ERRORS, error_list) +static Bool +__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire); +static Status +__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); static /* const */ XExtensionHooks __glXExtensionHooks = { NULL, /* create_gc */ @@ -110,17 +114,110 @@ static /* const */ XExtensionHooks __glXExtensionHooks = { NULL, /* create_font */ NULL, /* free_font */ __glXCloseDisplay, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ + __glXWireToEvent, /* wire_to_event */ + __glXEventToWire, /* event_to_wire */ NULL, /* error */ __glXErrorString, /* error_string */ }; -static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, __glXExtensionName, &__glXExtensionHooks, __GLX_NUMBER_EVENTS, NULL) +/* + * GLX events are a bit funky. We don't stuff the X event code into + * our user exposed (via XNextEvent) structure. Instead we use the GLX + * private event code namespace (and hope it doesn't conflict). Clients + * have to know that bit 15 in the event type field means they're getting + * a GLX event, and then handle the various sub-event types there, rather + * than simply checking the event code and handling it directly. + */ + +static Bool +__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = __glXFindDisplay(dpy); + + XextCheckExtension(dpy, info, __glXExtensionName, False); + + switch ((wire->u.u.type & 0x7f) - info->codes->first_event) { + case GLX_PbufferClobber: + { + GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event; + xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire; + aevent->event_type = awire->type; + aevent->serial = awire->sequenceNumber; + aevent->event_type = awire->event_type; + aevent->draw_type = awire->draw_type; + aevent->drawable = awire->drawable; + aevent->buffer_mask = awire->buffer_mask; + aevent->aux_buffer = awire->aux_buffer; + aevent->x = awire->x; + aevent->y = awire->y; + aevent->width = awire->width; + aevent->height = awire->height; + aevent->count = awire->count; + return True; + } + /* No easy symbol to test for this, as GLX_BufferSwapComplete is + * defined in the local glx.h header, but the + * xGLXBufferSwapComplete typedef is only available in new versions + * of the external glxproto.h header, which doesn't have any + * testable versioning define. + * + * I'll use the related DRI2 define, in the hope that we won't + * receive these events unless we know how to ask for them: + */ +#ifdef X_DRI2SwapBuffers + case GLX_BufferSwapComplete: + { + GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; + xGLXBufferSwapComplete *awire = (xGLXBufferSwapComplete *)wire; + aevent->event_type = awire->event_type; + aevent->drawable = awire->drawable; + aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo; + aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo; + aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; + return True; + } +#endif + default: + /* client doesn't support server event */ + break; + } + + return False; +} + +/* We don't actually support this. It doesn't make sense for clients to + * send each other GLX events. + */ +static Status +__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) +{ + XExtDisplayInfo *info = __glXFindDisplay(dpy); + + XextCheckExtension(dpy, info, __glXExtensionName, False); + + switch (event->type) { + case GLX_DAMAGED: + break; + case GLX_SAVED: + break; + case GLX_EXCHANGE_COMPLETE_INTEL: + break; + case GLX_BLIT_COMPLETE_INTEL: + break; + case GLX_FLIP_COMPLETE_INTEL: + break; + default: + /* client doesn't support server event */ + break; + } + + return Success; +} + /************************************************************************/ /* ** Free the per screen configs data as well as the array of diff --git a/src/glx/x11/glxextensions.c b/src/glx/glxextensions.c index 6852128e2a..56c69cbfcb 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/glxextensions.c @@ -32,7 +32,6 @@ #include <X11/extensions/extutil.h> #include <X11/extensions/Xext.h> #include <string.h> -#include "glapi.h" #include "glxextensions.h" @@ -104,6 +103,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, { GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N }, { GLX(EXT_texture_from_pixmap), VER(0,0), Y, N, N, N }, + { GLX(INTEL_swap_event), VER(1,4), Y, Y, N, N }, { NULL } }; diff --git a/src/glx/x11/glxextensions.h b/src/glx/glxextensions.h index 652c5db1c8..f556b1239c 100644 --- a/src/glx/x11/glxextensions.h +++ b/src/glx/glxextensions.h @@ -65,7 +65,8 @@ enum SGIX_swap_barrier_bit, SGIX_swap_group_bit, SGIX_visual_select_group_bit, - EXT_texture_from_pixmap_bit + EXT_texture_from_pixmap_bit, + INTEL_swap_event_bit, }; enum diff --git a/src/glx/x11/glxhash.c b/src/glx/glxhash.c index b76ec32345..b76ec32345 100644 --- a/src/glx/x11/glxhash.c +++ b/src/glx/glxhash.c diff --git a/src/glx/x11/glxhash.h b/src/glx/glxhash.h index 710712dd28..710712dd28 100644 --- a/src/glx/x11/glxhash.h +++ b/src/glx/glxhash.h diff --git a/src/glx/x11/indirect.c b/src/glx/indirect.c index ea90ce4463..48bae1478f 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/indirect.c @@ -30,7 +30,8 @@ #include "indirect.h" #include "glxclient.h" #include "indirect_size.h" -#include "dispatch.h" +#include "glapitable.h" +#include "glapidispatch.h" #include "glapi.h" #include "glthread.h" #include <GL/glxproto.h> @@ -47,7 +48,7 @@ # else # define FASTCALL # endif -# if defined(__GNUC__) +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define NOINLINE __attribute__((noinline)) # else # define NOINLINE diff --git a/src/glx/x11/indirect.h b/src/glx/indirect.h index 19a8c0d134..9e73b33818 100644 --- a/src/glx/x11/indirect.h +++ b/src/glx/indirect.h @@ -37,7 +37,7 @@ * \author Ian Romanick <idr@us.ibm.com> */ -# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) +# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined(__ELF__) # define HIDDEN __attribute__((visibility("hidden"))) # else # define HIDDEN @@ -47,7 +47,7 @@ # else # define FASTCALL # endif -# if defined(__GNUC__) +# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define NOINLINE __attribute__((noinline)) # else # define NOINLINE diff --git a/src/glx/x11/indirect_init.c b/src/glx/indirect_init.c index 73ca993027..73ca993027 100644 --- a/src/glx/x11/indirect_init.c +++ b/src/glx/indirect_init.c diff --git a/src/glx/x11/indirect_init.h b/src/glx/indirect_init.h index 72255f1301..72255f1301 100644 --- a/src/glx/x11/indirect_init.h +++ b/src/glx/indirect_init.h diff --git a/src/glx/x11/indirect_size.c b/src/glx/indirect_size.c index cdaf02ffe6..6356ddd49b 100644 --- a/src/glx/x11/indirect_size.c +++ b/src/glx/indirect_size.c @@ -29,7 +29,7 @@ #include <GL/gl.h> #include "indirect_size.h" -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PURE __attribute__((pure)) # else # define PURE @@ -41,7 +41,7 @@ # define FASTCALL # endif -# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) +# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined(__ELF__) # define INTERNAL __attribute__((visibility("internal"))) # else # define INTERNAL @@ -73,6 +73,7 @@ __glCallLists_size(GLenum e) case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_2_BYTES: + case GL_HALF_FLOAT: return 2; case GL_3_BYTES: return 3; diff --git a/src/glx/x11/indirect_size.h b/src/glx/indirect_size.h index 9ba0bd6907..af0919f964 100644 --- a/src/glx/x11/indirect_size.h +++ b/src/glx/indirect_size.h @@ -36,7 +36,7 @@ * \author Ian Romanick <idr@us.ibm.com> */ -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PURE __attribute__((pure)) # else # define PURE @@ -48,7 +48,7 @@ # define FASTCALL # endif -# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) +# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined(__ELF__) # define INTERNAL __attribute__((visibility("internal"))) # else # define INTERNAL diff --git a/src/glx/x11/indirect_texture_compression.c b/src/glx/indirect_texture_compression.c index fa927ebdf6..fa927ebdf6 100644 --- a/src/glx/x11/indirect_texture_compression.c +++ b/src/glx/indirect_texture_compression.c diff --git a/src/glx/x11/indirect_transpose_matrix.c b/src/glx/indirect_transpose_matrix.c index 618db9f5d4..618db9f5d4 100644 --- a/src/glx/x11/indirect_transpose_matrix.c +++ b/src/glx/indirect_transpose_matrix.c diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/indirect_vertex_array.c index ad9882528f..ad9882528f 100644 --- a/src/glx/x11/indirect_vertex_array.c +++ b/src/glx/indirect_vertex_array.c diff --git a/src/glx/x11/indirect_vertex_array.h b/src/glx/indirect_vertex_array.h index 37380320ed..37380320ed 100644 --- a/src/glx/x11/indirect_vertex_array.h +++ b/src/glx/indirect_vertex_array.h diff --git a/src/glx/x11/indirect_vertex_array_priv.h b/src/glx/indirect_vertex_array_priv.h index 56dac37c78..56dac37c78 100644 --- a/src/glx/x11/indirect_vertex_array_priv.h +++ b/src/glx/indirect_vertex_array_priv.h diff --git a/src/glx/x11/indirect_vertex_program.c b/src/glx/indirect_vertex_program.c index 3313ac008a..3313ac008a 100644 --- a/src/glx/x11/indirect_vertex_program.c +++ b/src/glx/indirect_vertex_program.c diff --git a/src/glx/x11/indirect_window_pos.c b/src/glx/indirect_window_pos.c index e97be3506d..e97be3506d 100644 --- a/src/glx/x11/indirect_window_pos.c +++ b/src/glx/indirect_window_pos.c diff --git a/src/glx/mini/Makefile b/src/glx/mini/Makefile deleted file mode 100644 index 6b5a3c76d7..0000000000 --- a/src/glx/mini/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# Build the MiniGLX libGL.so library. - -TOP = ../../.. -include $(TOP)/configs/current - - -DEFINES += -DGLX_DIRECT_RENDERING -DIN_MINI_GLX -UIN_DRI_DRIVER - -C_SOURCES = \ - $(TOP)/src/mesa/main/dispatch.c \ - $(TOP)/src/mesa/glapi/glapi.c \ - $(TOP)/src/mesa/glapi/glthread.c \ - $(TOP)/src/glx/x11/glcontextmodes.c \ - miniglx.c \ - miniglx_events.c - -X86_SOURCES = $(TOP)/src/mesa/x86/glapi_x86.S - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) - -INCLUDES = -I. $(INCLUDE_DIRS) - -INCLUDE_DIRS = \ - -I$(TOP)/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/glx/x11 \ - -I$(TOP)/src/mesa/drivers/dri/common \ - $(LIBDRM_CFLAGS) \ - $(PCIACCESS_CFLAGS) - - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/miniglx.conf - - -# Make libGL -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile - @ $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major 1 -minor 2 $(MKLIB_OPTIONS) \ - -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) \ - $(LIBDRM_LIB) $(PCIACCESS_LIB) - - -# install sample miniglx.conf -$(TOP)/$(LIB_DIR)/miniglx.conf: - $(INSTALL) example.miniglx.conf $(TOP)/$(LIB_DIR)/miniglx.conf - - -drmtest: xf86drm.o drmtest.o - rm -f drmtest && $(CC) -o drmtest xf86drm.o drmtest.o - - -depend: $(C_SOURCES) $(ASM_SOURCES) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) $(ASM_SOURCES) \ - > /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Dummy install target -install: - - -# Remove .o and backup files -clean: - -rm -f drmtest $(TOP)/$(LIB_DIR)/libGL.so* - -rm -f *.o *~ - -rm -f depend depend.bak - -include depend diff --git a/src/glx/mini/NOTES b/src/glx/mini/NOTES deleted file mode 100644 index 1774107d63..0000000000 --- a/src/glx/mini/NOTES +++ /dev/null @@ -1,115 +0,0 @@ - - -Getting MiniGLX up and running ------------------------------- - -It's necessary to do a bit of work to set up an environment to run miniglx. - -For the radeon driver, it's necessary to get the right set of kernel -modules installed before attempting to run any programs: - - rmmod radeon agpgart; - insmod agpgart; - insmod $(MESA)/src/kernel/radeonfb/radeonfb.o; - insmod $(MESA)/src/kernel/radeon/radeon.o; - -For all drivers, its necessary to reach the compiled libraries, and -tell MiniGLX where to find it's configuration file: - - export LD_LIBRARY_PATH=$(MESA)/lib; - export MINIGLX_CONF=$(MESA)/lib/miniglx.conf - ------------------------------------------------------------- - -MiniGLX Example Programs ------------------------- - -The following programs will work with miniglx: - - $(MESA)/tests/miniglx - $(MESA)/xdemos/glxgears - -Thanks to the miniglut stub library, most of the mesa glut demos will -work. In particular, the following have been tested. (Note there is -no keyboard or mouse interaction with these demos). - - $(MESA)/demos/gears - $(MESA)/demos/geartrain - $(MESA)/demos/morph3d - $(MESA)/demos/isosurf - $(MESA)/demos/texobj - $(MESA)/demos/texcyl - $(MESA)/demos/gloss - $(MESA)/demos/fire - $(MESA)/demos/tunnel - $(MESA)/demos/teapot - $(MESA)/samples/prim - $(MESA)/samples/olympic - $(MESA)/samples/star - $(MESA)/samples/wave - ...etc - -In fact most of the glut demos seem to work within the constraints of -having no keyboard/mouse interactivity. Furthermore, the use of the -glut wrapper means that these programs don't require recompilation to -run under MiniGLX -- the same binary works with both regular GLX and -MiniGLX. - - ------------------------------------------------------------- - -Porting GLX apps to MiniGLX ---------------------------- - -A quick list of issues encountered in porting existing GLX apps to -MiniGLX. Listed in no particular order. - -1) No input events - -MiniGLX doesn't provide an input layer, so any X11 input event -handling in the existing app will have to be redone for whatever -input devices exist on the target. - -2) No configuration, expose events - -Many GLX and Xlib programs wait on an event to ensure the window has -become visible after being mapped. MiniGLX provides no equivalent -facility. - -3) Different headers - -X11/Xlib.h, GL/GLX.h, etc must not be used if the program is being -compiled against MiniGLX. - -The equivalent header is GL/MiniGLX.h. - -4) Different library - -It may be necessary to link directly against the minGLX libGL.so. - -5) Reduced number of Xlib and GLX entrypoints. - -By definition (MiniGLX is a subset of GLX), many Xlib and GLX -entrypoints, structures and macros are not present in MiniGLX. It -will be necessary to find and eliminate all references to -non-supported entrypoints. - - ---------------------------------------------------------------- - -Bugs in radeonfb.o -- the radeon framebuffer driver. ----------------------------------------------------- - -Several bugs have been found in the radeonfb.o framebuffer driver. -Most of these are resolved in the version included in the MiniGLX -sources, but some remain: - -1) Occasionally, after entering graphics mode, colors appear 'shifted' -or 'translated', particularly in higher resolution modes. This is -definitely a bug in radeonfb.o as this can be provoked even when using -the software dri driver (fb_dri.so). Importance: High. Workaround: -Use 800x600 as it seems to be less frequent at this resolution, -otherwise, restart the application. - - - diff --git a/src/glx/mini/dispatch.c b/src/glx/mini/dispatch.c deleted file mode 100644 index ac24df9e7d..0000000000 --- a/src/glx/mini/dispatch.c +++ /dev/null @@ -1,64 +0,0 @@ -/** - * \file miniglx/dispatch.c - * - * \brief C-based dispatch of the OpenGL entry points (glAccum(), glBegin(), - * etc). - * - * \author Brian Paul <brian@precisioninsight.com> - * - * \note This code IS NOT USED if we're compiling on an x86 system and using - * the glapi_x86.S assembly code. - */ - -/* - * Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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 "glheader.h" -#include "glapi.h" -#include "glapitable.h" - - -#if !(defined(USE_X86_ASM) || defined(USE_SPARC_ASM)) - -#define KEYWORD1 - -#define KEYWORD2 - -#define NAME(func) gl##func - -#define DISPATCH(func, args, msg) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - (dispatch->func) args - -#define RETURN_DISPATCH(func, args, msg) \ - const struct _glapi_table *dispatch; \ - dispatch = _glapi_Dispatch ? _glapi_Dispatch : _glapi_get_dispatch();\ - return (dispatch->func) args - - -#include "glapitemp.h" - -#endif /* USE_X86_ASM */ diff --git a/src/glx/mini/driver.h b/src/glx/mini/driver.h deleted file mode 100644 index 39c0f9b5fa..0000000000 --- a/src/glx/mini/driver.h +++ /dev/null @@ -1,168 +0,0 @@ -/** - * \file driver.h - * \brief DRI utility functions definitions. - * - * 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. - * - * Look for more comments in the dri_util.c file. - * - * \author Kevin E. Martin <kevin@precisioninsight.com> - * \author Brian Paul <brian@precisioninsight.com> - */ - -/* - * Copyright 1998-1999 Precision Insight, 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 PRECISION INSIGHT 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. - */ - -#ifndef _driver_H_ -#define _driver_H_ - -#include "GL/gl.h" -#include "GL/internal/glcore.h" - -#include "drm.h" -#include "drm_sarea.h" - -/** - * \brief DRIDriverContext type. - */ -typedef struct DRIDriverContextRec { - const char *pciBusID; - int pciBus; - int pciDevice; - int pciFunc; - int chipset; - int bpp; - int cpp; - int agpmode; - int isPCI; - - int colorTiling; /**< \brief color tiling is enabled */ - - unsigned long FBStart; /**< \brief physical address of the framebuffer */ - unsigned long MMIOStart; /**< \brief physical address of the MMIO region */ - - int FBSize; /**< \brief size of the mmap'd framebuffer in bytes */ - int MMIOSize; /**< \brief size of the mmap'd MMIO region in bytes */ - - void *FBAddress; /**< \brief start of the mmap'd framebuffer */ - void *MMIOAddress; /**< \brief start of the mmap'd MMIO region */ - - /** - * \brief Client configuration details - * - * These are computed on the server and sent to clients as part of - * the initial handshaking. - */ - struct { - drm_handle_t hSAREA; - int SAREASize; - drm_handle_t hFrameBuffer; - int fbOrigin; - int fbSize; - int fbStride; - int virtualWidth; - int virtualHeight; - int Width; - } shared; - - /** - * \name From DRIInfoRec - */ - /*@{*/ - int drmFD; /**< \brief DRM device file descriptor */ - drm_sarea_t *pSAREA; - unsigned int serverContext; /**< \brief DRM context only active on server */ - /*@}*/ - - - /** - * \name Driver private - * - * Populated by __driInitFBDev() - */ - /*@{*/ - void *driverPrivate; - void *driverClientMsg; - int driverClientMsgSize; - /*@}*/ -} DRIDriverContext; - -/** - * \brief Interface to the DRI driver. - * - * This structure is retrieved from the loadable driver by the \e - * __driDriver symbol to access the Mini GLX specific hardware - * initialization and take down routines. - */ -typedef struct DRIDriverRec { - /** - * \brief Validate the framebuffer device mode - */ - int (*validateMode)( const DRIDriverContext *context ); - - /** - * \brief Examine mode returned by fbdev (may differ from the one - * requested), restore any hw regs clobbered by fbdev. - */ - int (*postValidateMode)( const DRIDriverContext *context ); - - /** - * \brief Initialize the framebuffer device. - */ - int (*initFBDev)( DRIDriverContext *context ); - - /** - * \brief Halt the framebuffer device. - */ - void (*haltFBDev)( DRIDriverContext *context ); - - - /** - * \brief Idle and shutdown hardware in preparation for a VT switch. - */ - int (*shutdownHardware)( const DRIDriverContext *context ); - - /** - * \brief Restore hardware state after regaining the VT. - */ - int (*restoreHardware)( const DRIDriverContext *context ); - - /** - * \brief Notify hardware driver of gain/loose focus. May be zero - * as this is of limited utility for most drivers. - */ - void (*notifyFocus)( int have_focus ); -} DRIDriver; - -#endif /* _driver_H_ */ diff --git a/src/glx/mini/example.miniglx.conf b/src/glx/mini/example.miniglx.conf deleted file mode 100644 index 62dd4f65ec..0000000000 --- a/src/glx/mini/example.miniglx.conf +++ /dev/null @@ -1,36 +0,0 @@ -# Example miniglx configuration file (/etc/miniglx.conf) -# - -# Framebuffer device to open: Might need to change this on dual-head -# systems. -fbdevDevice=/dev/fb0 - -# Which driver? -# radeon_dri.so -- HW accelerated radeon driver -# fb_dri.so -- Software rasterizer -clientDriverName=radeon_dri.so - -# The pci bus id of the video card. Find this with scanpci, lspci or -# look in /proc/pci. -pciBusID=PCI:1:0:0 - -# Is the card PCI or AGP ? -isPCI=0 - -# Virtual screen dimensions. Can reduce this to save videocard memory -# at the expense of maximum window size available. -virtualWidth=1280 -virtualHeight=1024 - -# Screen depth. Only 16 & 32bpp supported. -bpp=32 - -# AGP Mode. Not all cards supported (1, 2 or 4) -agpmode=1 - -# Rotated monitor? -- NOTE: only works with subsetted radeon driver! -rotateMode=0 - -# Do we want to use color tiling ? -colorTiling=0 - diff --git a/src/glx/mini/miniglx.c b/src/glx/mini/miniglx.c deleted file mode 100644 index e9a10b4ac7..0000000000 --- a/src/glx/mini/miniglx.c +++ /dev/null @@ -1,2580 +0,0 @@ -/** - * \file miniglx.c - * \brief Mini GLX interface functions. - * \author Brian Paul - * - * The Mini GLX interface is a subset of the GLX interface, plus a - * minimal set of Xlib functions. - */ - -/* - * Mesa 3-D graphics library - * Version: 6.0.1 - * - * Copyright (C) 1999-2004 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 - * BRIAN PAUL 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. - */ - - -/** - * \mainpage Mini GLX - * - * \section miniglxIntro Introduction - * - * The Mini GLX interface facilitates OpenGL rendering on embedded devices. The - * interface is a subset of the GLX interface, plus a minimal set of Xlib-like - * functions. - * - * Programs written to the Mini GLX specification should run unchanged - * on systems with the X Window System and the GLX extension (after - * recompilation). The intention is to allow flexibility for - * prototyping and testing. - * - * The files in the src/miniglx/ directory are compiled to build the - * libGL.so library. This is the library which applications link with. - * libGL.so in turn, loads the hardware-specific device driver. - * - * - * \section miniglxDoxygen About Doxygen - * - * For a list of all files, select <b>File List</b>. Choose a file from - * the list for a list of all functions in the file. - * - * For a list of all functions, types, constants, etc. - * select <b>File Members</b>. - * - * - * \section miniglxReferences References - * - * - <A HREF="file:../../docs/MiniGLX.html">Mini GLX Specification</A>, - * Tungsten Graphics, Inc. - * - OpenGL Graphics with the X Window System, Silicon Graphics, Inc., - * ftp://ftp.sgi.com/opengl/doc/opengl1.2/glx1.3.ps - * - Xlib - C Language X Interface, X Consortium Standard, X Version 11, - * Release 6.4, ftp://ftp.x.org/pub/R6.4/xc/doc/hardcopy/X11/xlib.PS.gz - * - XFree86 Man pages, The XFree86 Project, Inc., - * http://www.xfree86.org/current/manindex3.html - * - */ - -/** - * \page datatypes Notes on the XVisualInfo, Visual, and __GLXvisualConfig data types - * - * -# X (unfortunately) has two (or three) data types which - * describe visuals. Ideally, there would just be one. - * -# We need the #__GLXvisualConfig type to augment #XVisualInfo and #Visual - * because we need to describe the GLX-specific attributes of visuals. - * -# In this interface there is a one-to-one-to-one correspondence between - * the three types and they're all interconnected. - * -# The #XVisualInfo type has a pointer to a #Visual. The #Visual structure - * (aka MiniGLXVisualRec) has a pointer to the #__GLXvisualConfig. The - * #Visual structure also has a pointer pointing back to the #XVisualInfo. - * -# The #XVisualInfo structure is the only one who's contents are public. - * -# The glXChooseVisual() and XGetVisualInfo() are the only functions that - * return #XVisualInfo structures. They can be freed with XFree(), though - * there is a small memory leak. - */ - - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/time.h> /* for gettimeofday */ -#include <linux/kd.h> -#include <linux/vt.h> - -#include "miniglxP.h" -#include "dri_util.h" - -#include "imports.h" -#include "glcontextmodes.h" -#include "glapi.h" - -#include "pciaccess.h" - -static GLboolean __glXCreateContextWithConfig(__DRInativeDisplay *dpy, - int screen, int fbconfigID, void *contextID, - drm_context_t *hHWContext); - -static GLboolean __glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, unsigned int * index, unsigned int * stamp, - int * x, int * y, int * width, int * height, - int * numClipRects, drm_clip_rect_t ** pClipRects, - int * backX, int * backY, - int * numBackClipRects, drm_clip_rect_t ** pBackClipRects); - -static __DRIscreen * __glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn); - -static GLboolean __glXWindowExists(__DRInativeDisplay *dpy, __DRIid draw); - -static int __glXGetUST( int64_t * ust ); - -static GLboolean __glXGetMscRate(__DRInativeDisplay * dpy, __DRIid drawable, - int32_t * numerator, int32_t * denominator); - -static GLboolean xf86DRI_DestroyContext(__DRInativeDisplay *dpy, int screen, - __DRIid context_id ); - -static GLboolean xf86DRI_CreateDrawable(__DRInativeDisplay *dpy, int screen, - __DRIid drawable, drm_drawable_t *hHWDrawable ); - -static GLboolean xf86DRI_DestroyDrawable(__DRInativeDisplay *dpy, int screen, - __DRIid drawable); - - -/** Wrapper around either malloc() */ -void * -_mesa_malloc(size_t bytes) -{ - return malloc(bytes); -} - -/** Wrapper around either calloc() */ -void * -_mesa_calloc(size_t bytes) -{ - return calloc(1, bytes); -} - -/** Wrapper around either free() */ -void -_mesa_free(void *ptr) -{ - free(ptr); -} - - -/** - * \brief Current GLX context. - * - * \sa glXGetCurrentContext(). - */ -static GLXContext CurrentContext = NULL; - - - -static Display *SignalDisplay = 0; - -static void SwitchVT(int sig) -{ - fprintf(stderr, "SwitchVT %d dpy %p\n", sig, SignalDisplay); - - if (SignalDisplay) { - SignalDisplay->vtSignalFlag = 1; - switch( sig ) - { - case SIGUSR1: /* vt has been released */ - SignalDisplay->haveVT = 0; - break; - case SIGUSR2: /* vt has been acquired */ - SignalDisplay->haveVT = 1; - break; - } - } -} - -/**********************************************************************/ -/** \name Framebuffer device functions */ -/**********************************************************************/ -/*@{*/ - -/** - * \brief Do the first part of setting up the framebuffer device. - * - * \param dpy the display handle. - * \param use_vt use a VT for display or not - * - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \sa This is called during XOpenDisplay(). - * - * \internal - * Gets the VT number, opens the respective console TTY device. Saves its state - * to restore when exiting and goes into graphics mode. - * - * Opens the framebuffer device and make a copy of the original variable screen - * information and gets the fixed screen information. Maps the framebuffer and - * MMIO region into the process address space. - */ -static GLboolean -OpenFBDev( Display *dpy, int use_vt ) -{ - char ttystr[1000]; - int fd, vtnumber, ttyfd; - - assert(dpy); - - if (geteuid()) { - fprintf(stderr, "error: you need to be root\n"); - return GL_FALSE; - } - - if (use_vt) { - - /* open /dev/tty0 and get the VT number */ - if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) { - fprintf(stderr, "error opening /dev/tty0\n"); - return GL_FALSE; - } - if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) { - fprintf(stderr, "error: couldn't get a free vt\n"); - return GL_FALSE; - } - - fprintf(stderr, "*** got vt nr: %d\n", vtnumber); - close(fd); - - /* open the console tty */ - sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */ - dpy->ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0); - if (dpy->ConsoleFD < 0) { - fprintf(stderr, "error couldn't open console fd\n"); - return GL_FALSE; - } - - /* save current vt number */ - { - struct vt_stat vts; - if (ioctl(dpy->ConsoleFD, VT_GETSTATE, &vts) == 0) - dpy->OriginalVT = vts.v_active; - } - - /* disconnect from controlling tty */ - ttyfd = open("/dev/tty", O_RDWR); - if (ttyfd >= 0) { - ioctl(ttyfd, TIOCNOTTY, 0); - close(ttyfd); - } - - /* some magic to restore the vt when we exit */ - { - struct vt_mode vt; - struct sigaction sig_tty; - - /* Set-up tty signal handler to catch the signal we request below */ - SignalDisplay = dpy; - memset( &sig_tty, 0, sizeof( sig_tty ) ); - sig_tty.sa_handler = SwitchVT; - sigemptyset( &sig_tty.sa_mask ); - if( sigaction( SIGUSR1, &sig_tty, &dpy->OrigSigUsr1 ) || - sigaction( SIGUSR2, &sig_tty, &dpy->OrigSigUsr2 ) ) - { - fprintf(stderr, "error: can't set up signal handler (%s)", - strerror(errno) ); - return GL_FALSE; - } - - - - vt.mode = VT_PROCESS; - vt.waitv = 0; - vt.relsig = SIGUSR1; - vt.acqsig = SIGUSR2; - if (ioctl(dpy->ConsoleFD, VT_SETMODE, &vt) < 0) { - fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - - if (ioctl(dpy->ConsoleFD, VT_ACTIVATE, vtnumber) != 0) - printf("ioctl VT_ACTIVATE: %s\n", strerror(errno)); - if (ioctl(dpy->ConsoleFD, VT_WAITACTIVE, vtnumber) != 0) - printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno)); - - if (ioctl(dpy->ConsoleFD, VT_GETMODE, &vt) < 0) { - fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno)); - return GL_FALSE; - } - - - - } - - /* go into graphics mode */ - if (ioctl(dpy->ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) { - fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - } - - /* open the framebuffer device */ - dpy->FrameBufferFD = open(dpy->fbdevDevice, O_RDWR); - if (dpy->FrameBufferFD < 0) { - fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno)); - return GL_FALSE; - } - - /* get the original variable screen info */ - if (ioctl(dpy->FrameBufferFD, FBIOGET_VSCREENINFO, &dpy->OrigVarInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - /* make copy */ - dpy->VarInfo = dpy->OrigVarInfo; /* structure copy */ - - /* Turn off hw accels (otherwise mmap of mmio region will be - * refused) - */ - dpy->VarInfo.accel_flags = 0; - if (ioctl(dpy->FrameBufferFD, FBIOPUT_VSCREENINFO, &dpy->VarInfo)) { - fprintf(stderr, "error: ioctl(FBIOPUT_VSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - - - /* Get the fixed screen info */ - if (ioctl(dpy->FrameBufferFD, FBIOGET_FSCREENINFO, &dpy->FixedInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - - - /* mmap the framebuffer into our address space */ - dpy->driverContext.FBStart = dpy->FixedInfo.smem_start; - dpy->driverContext.FBSize = dpy->FixedInfo.smem_len; - dpy->driverContext.shared.fbSize = dpy->FixedInfo.smem_len; - dpy->driverContext.FBAddress = (caddr_t) mmap(0, /* start */ - dpy->driverContext.shared.fbSize, /* bytes */ - PROT_READ | PROT_WRITE, /* prot */ - MAP_SHARED, /* flags */ - dpy->FrameBufferFD, /* fd */ - 0 /* offset */); - if (dpy->driverContext.FBAddress == (caddr_t) - 1) { - fprintf(stderr, "error: unable to mmap framebuffer: %s\n", - strerror(errno)); - return GL_FALSE; - } - - /* mmap the MMIO region into our address space */ - dpy->driverContext.MMIOStart = dpy->FixedInfo.mmio_start; - dpy->driverContext.MMIOSize = dpy->FixedInfo.mmio_len; - dpy->driverContext.MMIOAddress = (caddr_t) mmap(0, /* start */ - dpy->driverContext.MMIOSize, /* bytes */ - PROT_READ | PROT_WRITE, /* prot */ - MAP_SHARED, /* flags */ - dpy->FrameBufferFD, /* fd */ - dpy->FixedInfo.smem_len /* offset */); - if (dpy->driverContext.MMIOAddress == (caddr_t) - 1) { - fprintf(stderr, "error: unable to mmap mmio region: %s\n", - strerror(errno)); - return GL_FALSE; - } - - fprintf(stderr, "got MMIOAddress %p offset %d\n", - dpy->driverContext.MMIOAddress, - dpy->FixedInfo.smem_len); - - return GL_TRUE; -} - - - - -/** - * \brief Setup up the desired framebuffer device mode. - * - * \param dpy the display handle. - * - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \sa This is called during __miniglx_StartServer(). - * - * \internal - * - * Bumps the size of the window the the next supported mode. Sets the - * variable screen information according to the desired mode and asks - * the driver to validate the mode. Certifies that a DirectColor or - * TrueColor visual is used from the updated fixed screen information. - * In the case of DirectColor visuals, sets up an 'identity' colormap to - * mimic a TrueColor visual. - * - * Calls the driver hooks 'ValidateMode' and 'PostValidateMode' to - * allow the driver to make modifications to the chosen mode according - * to hardware constraints, or to save and restore videocard registers - * that may be clobbered by the fbdev driver. - * - * \todo Timings are hard-coded in the source for a set of supported modes. - */ -static GLboolean -SetupFBDev( Display *dpy ) -{ - int width, height; - - assert(dpy); - - width = dpy->driverContext.shared.virtualWidth; - height = dpy->driverContext.shared.virtualHeight; - - if (width==832) - width=800; -#if 0 - /* Bump size up to next supported mode. - */ - if (width <= 720 && height <= 480) { - width = 720; height = 480; - } - else if (width <= 960 && height <= 540) { - width = 960; height = 540; - } - else if (width <= 800 && height <= 600) { - width = 800; height = 600; - } - else if (width <= 1024 && height <= 768) { - width = 1024; height = 768; - } - else if (width <= 768 && height <= 1024) { - width = 768; height = 1024; - } - else if (width <= 1280 && height <= 1024) { - width = 1280; height = 1024; - } -#endif - - dpy->driverContext.shared.fbStride = width * (dpy->driverContext.bpp / 8); - - /* set the depth, resolution, etc */ - dpy->VarInfo = dpy->OrigVarInfo; - dpy->VarInfo.bits_per_pixel = dpy->driverContext.bpp; - dpy->VarInfo.xres_virtual = dpy->driverContext.shared.virtualWidth; - dpy->VarInfo.yres_virtual = dpy->driverContext.shared.virtualHeight; - dpy->VarInfo.xres = dpy->driverContext.shared.Width; - dpy->VarInfo.yres = height; - dpy->VarInfo.xoffset = 0; - dpy->VarInfo.yoffset = 0; - dpy->VarInfo.nonstd = 0; - dpy->VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */ - - if (dpy->VarInfo.bits_per_pixel == 32) { - dpy->VarInfo.red.offset = 16; - dpy->VarInfo.green.offset = 8; - dpy->VarInfo.blue.offset = 0; - dpy->VarInfo.transp.offset = 24; - dpy->VarInfo.red.length = 8; - dpy->VarInfo.green.length = 8; - dpy->VarInfo.blue.length = 8; - dpy->VarInfo.transp.length = 8; - } - else if (dpy->VarInfo.bits_per_pixel == 16) { - dpy->VarInfo.red.offset = 11; - dpy->VarInfo.green.offset = 5; - dpy->VarInfo.blue.offset = 0; - dpy->VarInfo.red.length = 5; - dpy->VarInfo.green.length = 6; - dpy->VarInfo.blue.length = 5; - dpy->VarInfo.transp.offset = 0; - dpy->VarInfo.transp.length = 0; - } - else { - fprintf(stderr, "Only 32bpp and 16bpp modes supported at the moment\n"); - return 0; - } - - if (!dpy->driver->validateMode( &dpy->driverContext )) { - fprintf(stderr, "Driver validateMode() failed\n"); - return 0; - } - - /* These should be calculated with the gtf.c program, and then we could - remove all this... AlanH. */ - if (dpy->VarInfo.xres == 1280 && - dpy->VarInfo.yres == 1024) { - /* timing values taken from /etc/fb.modes (1280x1024 @ 75Hz) */ - dpy->VarInfo.pixclock = 7408; - dpy->VarInfo.left_margin = 248; - dpy->VarInfo.right_margin = 16; - dpy->VarInfo.upper_margin = 38; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 144; - dpy->VarInfo.vsync_len = 3; - } - else if (dpy->VarInfo.xres == 1024 && - dpy->VarInfo.yres == 768) { - /* timing values taken from /etc/fb.modes (1024x768 @ 75Hz) */ - dpy->VarInfo.pixclock = 12699; - dpy->VarInfo.left_margin = 176; - dpy->VarInfo.right_margin = 16; - dpy->VarInfo.upper_margin = 28; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 96; - dpy->VarInfo.vsync_len = 3; - } - else if (dpy->VarInfo.xres == 800 && - dpy->VarInfo.yres == 600) { - /* timing values taken from /etc/fb.modes (800x600 @ 75Hz) */ - dpy->VarInfo.pixclock = 27778; - dpy->VarInfo.left_margin = 128; - dpy->VarInfo.right_margin = 24; - dpy->VarInfo.upper_margin = 22; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 72; - dpy->VarInfo.vsync_len = 2; - } - else if (dpy->VarInfo.xres == 720 && - dpy->VarInfo.yres == 480) { - dpy->VarInfo.pixclock = 37202; - dpy->VarInfo.left_margin = 88; - dpy->VarInfo.right_margin = 16; - dpy->VarInfo.upper_margin = 14; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 72; - dpy->VarInfo.vsync_len = 3; - } - else if (dpy->VarInfo.xres == 960 && - dpy->VarInfo.yres == 540) { - dpy->VarInfo.pixclock = 24273; - dpy->VarInfo.left_margin = 128; - dpy->VarInfo.right_margin = 32; - dpy->VarInfo.upper_margin = 16; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 96; - dpy->VarInfo.vsync_len = 3; - } - else if (dpy->VarInfo.xres == 768 && - dpy->VarInfo.yres == 1024) { - /* timing values for 768x1024 @ 75Hz */ - dpy->VarInfo.pixclock = 11993; - dpy->VarInfo.left_margin = 136; - dpy->VarInfo.right_margin = 32; - dpy->VarInfo.upper_margin = 41; - dpy->VarInfo.lower_margin = 1; - dpy->VarInfo.hsync_len = 80; - dpy->VarInfo.vsync_len = 3; - } - else { - /* XXX need timings for other screen sizes */ - fprintf(stderr, "XXXX screen size %d x %d not supported at this time!\n", - dpy->VarInfo.xres, dpy->VarInfo.yres); - return GL_FALSE; - } - - fprintf(stderr, "[miniglx] Setting mode: visible %dx%d virtual %dx%dx%d\n", - dpy->VarInfo.xres, dpy->VarInfo.yres, - dpy->VarInfo.xres_virtual, dpy->VarInfo.yres_virtual, - dpy->VarInfo.bits_per_pixel); - - /* set variable screen info */ - if (ioctl(dpy->FrameBufferFD, FBIOPUT_VSCREENINFO, &dpy->VarInfo)) { - fprintf(stderr, "error: ioctl(FBIOPUT_VSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - /* get the variable screen info, in case it has been modified */ - if (ioctl(dpy->FrameBufferFD, FBIOGET_VSCREENINFO, &dpy->VarInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - - fprintf(stderr, "[miniglx] Readback mode: visible %dx%d virtual %dx%dx%d\n", - dpy->VarInfo.xres, dpy->VarInfo.yres, - dpy->VarInfo.xres_virtual, dpy->VarInfo.yres_virtual, - dpy->VarInfo.bits_per_pixel); - - /* Get the fixed screen info */ - if (ioctl(dpy->FrameBufferFD, FBIOGET_FSCREENINFO, &dpy->FixedInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - return GL_FALSE; - } - - if (dpy->FixedInfo.visual != FB_VISUAL_TRUECOLOR && - dpy->FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) { - fprintf(stderr, "non-TRUECOLOR visuals not supported.\n"); - return GL_FALSE; - } - - if (dpy->FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) { - struct fb_cmap cmap; - unsigned short red[256], green[256], blue[256]; - int rcols = 1 << dpy->VarInfo.red.length; - int gcols = 1 << dpy->VarInfo.green.length; - int bcols = 1 << dpy->VarInfo.blue.length; - int i; - - cmap.start = 0; - cmap.len = gcols; - cmap.red = red; - cmap.green = green; - cmap.blue = blue; - cmap.transp = NULL; - - for (i = 0; i < rcols ; i++) - red[i] = (65536/(rcols-1)) * i; - - for (i = 0; i < gcols ; i++) - green[i] = (65536/(gcols-1)) * i; - - for (i = 0; i < bcols ; i++) - blue[i] = (65536/(bcols-1)) * i; - - if (ioctl(dpy->FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) { - fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i); - exit(1); - } - } - - /* May need to restore regs fbdev has clobbered: - */ - if (!dpy->driver->postValidateMode( &dpy->driverContext )) { - fprintf(stderr, "Driver postValidateMode() failed\n"); - return 0; - } - - return GL_TRUE; -} - - -/** - * \brief Restore the framebuffer device to state it was in before we started - * - * Undoes the work done by SetupFBDev(). - * - * \param dpy the display handle. - * - * \return GL_TRUE on success, or GL_FALSE on failure. - * - * \sa Called from XDestroyWindow(). - * - * \internal - * Restores the original variable screen info. - */ -static GLboolean -RestoreFBDev( Display *dpy ) -{ - /* restore original variable screen info */ - if (ioctl(dpy->FrameBufferFD, FBIOPUT_VSCREENINFO, &dpy->OrigVarInfo)) { - fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n", - strerror(errno)); - return GL_FALSE; - } - dpy->VarInfo = dpy->OrigVarInfo; - - return GL_TRUE; -} - - -/** - * \brief Close the framebuffer device. - * - * \param dpy the display handle. - * - * \sa Called from XCloseDisplay(). - * - * \internal - * Unmaps the framebuffer and MMIO region. Restores the text mode and the - * original virtual terminal. Closes the console and framebuffer devices. - */ -static void -CloseFBDev( Display *dpy ) -{ - struct vt_mode VT; - - munmap(dpy->driverContext.FBAddress, dpy->driverContext.FBSize); - munmap(dpy->driverContext.MMIOAddress, dpy->driverContext.MMIOSize); - - if (dpy->ConsoleFD) { - /* restore text mode */ - ioctl(dpy->ConsoleFD, KDSETMODE, KD_TEXT); - - /* set vt */ - if (ioctl(dpy->ConsoleFD, VT_GETMODE, &VT) != -1) { - VT.mode = VT_AUTO; - ioctl(dpy->ConsoleFD, VT_SETMODE, &VT); - } - - /* restore original vt */ - if (dpy->OriginalVT >= 0) { - ioctl(dpy->ConsoleFD, VT_ACTIVATE, dpy->OriginalVT); - dpy->OriginalVT = -1; - } - - close(dpy->ConsoleFD); - } - close(dpy->FrameBufferFD); -} - -/*@}*/ - - -/**********************************************************************/ -/** \name Misc functions needed for DRI drivers */ -/**********************************************************************/ -/*@{*/ - -/** - * \brief Find the DRI screen dependent methods associated with the display. - * - * \param dpy a display handle, as returned by XOpenDisplay(). - * \param scrn the screen number. Not referenced. - * - * \returns a pointer to a __DRIscreenRec structure. - * - * \internal - * Returns the MiniGLXDisplayRec::driScreen attribute. - */ -static __DRIscreen * -__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn) -{ - (void) scrn; - return &((Display*)dpy)->driScreen; -} - -/** - * \brief Validate a drawable. - * - * \param dpy a display handle, as returned by XOpenDisplay(). - * \param draw drawable to validate. - * - * \internal - * Since Mini GLX only supports one window, compares the specified drawable with - * the MiniGLXDisplayRec::TheWindow attribute. - */ -static GLboolean -__glXWindowExists(__DRInativeDisplay *dpy, __DRIid draw) -{ - const Display * const display = (Display*)dpy; - if (display->TheWindow == (Window) draw) - return True; - else - return False; -} - -/** - * \brief Get current thread ID. - * - * \return thread ID. - * - * \internal - * Always returns 0. - */ -/*unsigned long -_glthread_GetID(void) -{ - return 0; -}*/ - -/*@}*/ - - -/** - * \brief Scan Linux /prog/bus/pci/devices file to determine hardware - * chipset based on supplied bus ID. - * - * \return probed chipset (non-zero) on success, zero otherwise. - * - * \internal - */ -static int get_chipset_from_busid( Display *dpy ) -{ - char buf[0x200]; - FILE *file; - const char *fname = "/proc/bus/pci/devices"; - int retval = 0; - - if (!(file = fopen(fname,"r"))) { - fprintf(stderr, "couldn't open %s: %s\n", fname, strerror(errno)); - return 0; - } - - while (fgets(buf, sizeof(buf)-1, file)) { - unsigned int nr, bus, dev, fn, vendor, device, encode; - nr = sscanf(buf, "%04x\t%04x%04x", &encode, - &vendor, &device); - - bus = encode >> 8; - dev = (encode & 0xFF) >> 3; - fn = encode & 0x7; - - if (nr != 3) - break; - - if (bus == dpy->driverContext.pciBus && - dev == dpy->driverContext.pciDevice && - fn == dpy->driverContext.pciFunc) { - retval = device; - break; - } - } - - fclose(file); - - if (retval) - fprintf(stderr, "[miniglx] probed chipset 0x%x\n", retval); - else - fprintf(stderr, "[miniglx] failed to probe chipset\n"); - - return retval; -} - - -/** - * \brief Read settings from a configuration file. - * - * The configuration file is usually "/etc/miniglx.conf", but can be overridden - * with the MINIGLX_CONF environment variable. - * - * The format consists in \code option = value \endcode lines. The option names - * corresponds to the fields in MiniGLXDisplayRec. - * - * \param dpy the display handle as. - * - * \return non-zero on success, zero otherwise. - * - * \internal - * Sets some defaults. Opens and parses the the Mini GLX configuration file and - * fills in the MiniGLXDisplayRec field that corresponds for each option. - */ -static int __read_config_file( Display *dpy ) -{ - FILE *file; - const char *fname; - - /* Fallback/defaults - */ - dpy->fbdevDevice = "/dev/fb0"; - dpy->clientDriverName = "fb_dri.so"; - dpy->driverContext.pciBus = 0; - dpy->driverContext.pciDevice = 0; - dpy->driverContext.pciFunc = 0; - dpy->driverContext.chipset = 0; - dpy->driverContext.pciBusID = 0; - dpy->driverContext.shared.virtualWidth = 1280; - dpy->driverContext.shared.virtualHeight = 1024; - dpy->driverContext.bpp = 32; - dpy->driverContext.cpp = 4; - dpy->rotateMode = 0; - dpy->driverContext.agpmode = 1; - dpy->driverContext.isPCI = 0; - dpy->driverContext.colorTiling = 0; - - fname = getenv("MINIGLX_CONF"); - if (!fname) fname = "/etc/miniglx.conf"; - - file = fopen(fname, "r"); - if (!file) { - fprintf(stderr, "couldn't open config file %s: %s\n", fname, strerror(errno)); - return 0; - } - - - while (!feof(file)) { - char buf[81], *opt = buf, *val, *tmp1, *tmp2; - fgets(buf, sizeof(buf), file); - - /* Parse 'opt = val' -- must be easier ways to do this. - */ - while (isspace(*opt)) opt++; - val = opt; - if (*val == '#') continue; /* comment */ - while (!isspace(*val) && *val != '=' && *val) val++; - tmp1 = val; - while (isspace(*val)) val++; - if (*val != '=') continue; - *tmp1 = 0; - val++; - while (isspace(*val)) val++; - tmp2 = val; - while (!isspace(*tmp2) && *tmp2 != '\n' && *tmp2) tmp2++; - *tmp2 = 0; - - - if (strcmp(opt, "fbdevDevice") == 0) - dpy->fbdevDevice = strdup(val); - else if (strcmp(opt, "clientDriverName") == 0) - dpy->clientDriverName = strdup(val); - else if (strcmp(opt, "rotateMode") == 0) - dpy->rotateMode = atoi(val) ? 1 : 0; - else if (strcmp(opt, "pciBusID") == 0) { - if (sscanf(val, "PCI:%d:%d:%d", - &dpy->driverContext.pciBus, - &dpy->driverContext.pciDevice, - &dpy->driverContext.pciFunc) != 3) { - fprintf(stderr, "malformed bus id: %s\n", val); - continue; - } - dpy->driverContext.pciBusID = strdup(val); - } - else if (strcmp(opt, "chipset") == 0) { - if (sscanf(val, "0x%x", &dpy->driverContext.chipset) != 1) - fprintf(stderr, "malformed chipset: %s\n", opt); - } - else if (strcmp(opt, "virtualWidth") == 0) { - if (sscanf(val, "%d", &dpy->driverContext.shared.virtualWidth) != 1) - fprintf(stderr, "malformed virtualWidth: %s\n", opt); - } - else if (strcmp(opt, "virtualHeight") == 0) { - if (sscanf(val, "%d", &dpy->driverContext.shared.virtualHeight) != 1) - fprintf(stderr, "malformed virutalHeight: %s\n", opt); - } - else if (strcmp(opt, "bpp") == 0) { - if (sscanf(val, "%d", &dpy->driverContext.bpp) != 1) - fprintf(stderr, "malformed bpp: %s\n", opt); - dpy->driverContext.cpp = dpy->driverContext.bpp / 8; - } - else if (strcmp(opt, "agpmode") == 0) { - if (sscanf(val, "%d", &dpy->driverContext.agpmode) != 1) - fprintf(stderr, "malformed agpmode: %s\n", opt); - } - else if (strcmp(opt, "isPCI") == 0) { - dpy->driverContext.isPCI = atoi(val) ? 1 : 0; - } - else if (strcmp(opt, "colorTiling") == 0) { - dpy->driverContext.colorTiling = atoi(val) ? 1 : 0; - } - } - - fclose(file); - - if (dpy->driverContext.chipset == 0 && dpy->driverContext.pciBusID != 0) - dpy->driverContext.chipset = get_chipset_from_busid( dpy ); - - return 1; -} - -/** - * Versioned name of the expected \c __driCreateNewScreen function. - * - * The version of the last incompatible loader/driver inteface change is - * appended to the name of the \c __driCreateNewScreen function. This - * prevents loaders from trying to load drivers that are too old. - * - * \todo - * Create a macro or something so that this is automatically updated. - */ -static const char createNewScreenName[] = "__driCreateNewScreen_20050727"; - - -static int InitDriver( Display *dpy ) -{ - /* - * Begin DRI setup. - * We're kind of combining the per-display and per-screen information - * which was kept separate in XFree86/DRI's libGL. - */ - dpy->dlHandle = dlopen(dpy->clientDriverName, RTLD_NOW | RTLD_GLOBAL); - if (!dpy->dlHandle) { - fprintf(stderr, "Unable to open %s: %s\n", dpy->clientDriverName, - dlerror()); - goto failed; - } - - /* Pull in Mini GLX specific hooks: - */ - dpy->driver = (struct DRIDriverRec *) dlsym(dpy->dlHandle, - "__driDriver"); - if (!dpy->driver) { - fprintf(stderr, "Couldn't find __driDriver in %s\n", - dpy->clientDriverName); - goto failed; - } - - /* Pull in standard DRI client-side driver hooks: - */ - dpy->createNewScreen = (PFNCREATENEWSCREENFUNC) - dlsym(dpy->dlHandle, createNewScreenName); - if (!dpy->createNewScreen) { - fprintf(stderr, "Couldn't find %s in %s\n", createNewScreenName, - dpy->clientDriverName); - goto failed; - } - - return GL_TRUE; - -failed: - if (dpy->dlHandle) { - dlclose(dpy->dlHandle); - dpy->dlHandle = 0; - } - return GL_FALSE; -} - - -/**********************************************************************/ -/** \name Public API functions (Xlib and GLX) */ -/**********************************************************************/ -/*@{*/ - - -/** - * \brief Initialize the graphics system. - * - * \param display_name currently ignored. It is recommended to pass it as NULL. - * \return a pointer to a #Display if the function is able to initialize - * the graphics system, NULL otherwise. - * - * Allocates a MiniGLXDisplayRec structure and fills in with information from a - * configuration file. - * - * Calls OpenFBDev() to open the framebuffer device and calls - * DRIDriverRec::initFBDev to do the client-side initialization on it. - * - * Loads the DRI driver and pulls in Mini GLX specific hooks into a - * DRIDriverRec structure, and the standard DRI \e __driCreateScreen hook. - * Asks the driver for a list of supported visuals. Performs the per-screen - * client-side initialization. Also setups the callbacks in the screen private - * information. - * - * Does the framebuffer device setup. Calls __miniglx_open_connections() to - * serve clients. - */ -Display * -__miniglx_StartServer( const char *display_name ) -{ - Display *dpy; - int use_vt = 0; - - pci_system_init(); - - dpy = (Display *)calloc(1, sizeof(Display)); - if (!dpy) - return NULL; - - dpy->IsClient = False; - - if (!__read_config_file( dpy )) { - fprintf(stderr, "Couldn't get configuration details\n"); - free(dpy); - return NULL; - } - - /* Open the fbdev device - */ - if (!OpenFBDev(dpy, use_vt)) { - fprintf(stderr, "OpenFBDev failed\n"); - free(dpy); - return NULL; - } - - if (!InitDriver(dpy)) { - fprintf(stderr, "InitDriver failed\n"); - free(dpy); - return NULL; - } - - /* Perform the initialization normally done in the X server - */ - if (!dpy->driver->initFBDev( &dpy->driverContext )) { - fprintf(stderr, "%s: __driInitFBDev failed\n", __FUNCTION__); - dlclose(dpy->dlHandle); - return GL_FALSE; - } - - /* do fbdev setup - */ - if (!SetupFBDev(dpy)) { - fprintf(stderr, "SetupFBDev failed\n"); - free(dpy); - return NULL; - } - - /* unlock here if not using VT -- JDS */ - if (!use_vt) { - if (dpy->driver->restoreHardware) - dpy->driver->restoreHardware( &dpy->driverContext ); - DRM_UNLOCK( dpy->driverContext.drmFD, - dpy->driverContext.pSAREA, - dpy->driverContext.serverContext ); - dpy->hwActive = 1; - } - - /* Ready for clients: - */ - if (!__miniglx_open_connections(dpy)) { - free(dpy); - return NULL; - } - - return dpy; -} - - -/** - * Implement \c __DRIinterfaceMethods::getProcAddress. - */ -static __DRIfuncPtr get_proc_address( const char * proc_name ) -{ - (void) proc_name; - return NULL; -} - - -/** - * Table of functions exported by the loader to the driver. - */ -static const __DRIinterfaceMethods interface_methods = { - get_proc_address, - - _gl_context_modes_create, - _gl_context_modes_destroy, - - __glXFindDRIScreen, - __glXWindowExists, - - __glXCreateContextWithConfig, - xf86DRI_DestroyContext, - - xf86DRI_CreateDrawable, - xf86DRI_DestroyDrawable, - __glXGetDrawableInfo, - - __glXGetUST, - __glXGetMscRate, -}; - - -static void * -CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc) -{ - void *psp = NULL; - drm_handle_t hSAREA; - drmAddress pSAREA; - const char *BusID; - int i; - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - __DRIframebuffer framebuffer; - int fd = -1; - int status; - const char * err_msg; - const char * err_extra; - drmVersionPtr version; - drm_handle_t hFB; - drm_magic_t magic; - - - hSAREA = dpy->driverContext.shared.hSAREA; - BusID = dpy->driverContext.pciBusID; - - fd = drmOpen(NULL, BusID); - - err_msg = "open DRM"; - err_extra = strerror( -fd ); - - if (fd < 0) goto done; - - err_msg = "drmGetMagic"; - err_extra = NULL; - - if (drmGetMagic(fd, &magic)) goto done; - - dpy->authorized = False; - send_char_msg( dpy, 0, _Authorize ); - send_msg( dpy, 0, &magic, sizeof(magic)); - - /* force net buffer flush */ - while (!dpy->authorized) - handle_fd_events( dpy, 0 ); - - version = drmGetVersion(fd); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - } - - /* - * Get device name (like "tdfx") and the ddx version numbers. - * We'll check the version in each DRI driver's "createScreen" - * function. - */ - ddx_version.major = -1; - ddx_version.minor = 0; - ddx_version.patch = 0; - - /* - * Get the DRI X extension version. - */ - dri_version.major = 4; - dri_version.minor = 0; - dri_version.patch = 0; - - /* - * Get device-specific info. pDevPriv will point to a struct - * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) - * that has information about the screen size, depth, pitch, - * ancilliary buffers, DRM mmap handles, etc. - */ - hFB = dpy->driverContext.shared.hFrameBuffer; - framebuffer.size = dpy->driverContext.shared.fbSize; - framebuffer.stride = dpy->driverContext.shared.fbStride; - framebuffer.dev_priv_size = dpy->driverContext.driverClientMsgSize; - framebuffer.dev_priv = dpy->driverContext.driverClientMsg; - framebuffer.width = dpy->driverContext.shared.virtualWidth; - framebuffer.height = dpy->driverContext.shared.virtualHeight; - - /* - * Map the framebuffer region. - */ - status = drmMap(fd, hFB, framebuffer.size, - (drmAddressPtr)&framebuffer.base); - - err_msg = "drmMap of framebuffer"; - err_extra = strerror( -status ); - - if ( status != 0 ) goto done; - - /* - * Map the SAREA region. Further mmap regions may be setup in - * each DRI driver's "createScreen" function. - */ - status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); - - err_msg = "drmMap of sarea"; - err_extra = strerror( -status ); - - if ( status == 0 ) { - err_msg = "InitDriver"; - err_extra = NULL; - psp = dpy->createNewScreen(dpy, scrn, psc, NULL, - & ddx_version, - & dri_version, - & drm_version, - & framebuffer, - pSAREA, - fd, - 20050727, - & interface_methods, - (__GLcontextModes **) &dpy->driver_modes); - - /* fill in dummy visual ids */ - { - __GLcontextModes *temp; - temp = (__GLcontextModes *)dpy->driver_modes; - i = 1; - while (temp) - { - temp->visualID = i++; - temp=temp->next; - } - } - } - -done: - if ( psp == NULL ) { - if ( pSAREA != MAP_FAILED ) { - (void)drmUnmap(pSAREA, SAREA_MAX); - } - - if ( framebuffer.base != MAP_FAILED ) { - (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); - } - - if ( framebuffer.dev_priv != NULL ) { - free(framebuffer.dev_priv); - } - - if ( fd >= 0 ) { - (void)drmClose(fd); - } - - if ( err_extra != NULL ) { - fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg, - err_extra); - } - else { - fprintf(stderr, "libGL error: %s failed\n", err_msg ); - } - - fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); - } - - return psp; -} - -/** - * \brief Initialize the graphics system. - * - * \param display_name currently ignored. It is recommended to pass it as NULL. - * \return a pointer to a #Display if the function is able to initialize - * the graphics system, NULL otherwise. - * - * Allocates a MiniGLXDisplayRec structure and fills in with information from a - * configuration file. - * - * Calls __miniglx_open_connections() to connect to the server. - * - * Loads the DRI driver and pulls in Mini GLX specific hooks into a - * DRIDriverRec structure, and the standard DRI \e __driCreateScreen hook. - * Asks the driver for a list of supported visuals. Performs the per-screen - * client-side initialization. Also setups the callbacks in the screen private - * information. - * - * \todo - * - read config file - * - what about virtualWidth, etc? - * - determine dpy->driverClientMsgSize, - * - allocate dpy->driverClientMsg - */ -Display * -XOpenDisplay( const char *display_name ) -{ - Display *dpy; - - dpy = (Display *)calloc(1, sizeof(Display)); - if (!dpy) - return NULL; - - dpy->IsClient = True; - - /* read config file - */ - if (!__read_config_file( dpy )) { - fprintf(stderr, "Couldn't get configuration details\n"); - free(dpy); - return NULL; - } - - /* Connect to the server and receive driverClientMsg - */ - if (!__miniglx_open_connections(dpy)) { - free(dpy); - return NULL; - } - - /* dlopen the driver .so file - */ - if (!InitDriver(dpy)) { - fprintf(stderr, "InitDriver failed\n"); - free(dpy); - return NULL; - } - - /* Perform the client-side initialization. - * - * Clearly there is a limit of one on the number of windows in - * existence at any time. - * - * Need to shut down DRM and free DRI data in XDestroyWindow(), too. - */ - dpy->driScreen.private = CallCreateNewScreen(dpy, 0, &dpy->driScreen); - if (!dpy->driScreen.private) { - fprintf(stderr, "%s: __driCreateScreen failed\n", __FUNCTION__); - dlclose(dpy->dlHandle); - free(dpy); - return NULL; - } - - /* Anything more to do? - */ - return dpy; -} - - -/** - * \brief Release display resources. - * - * When the application is about to exit, the resources associated with the - * graphics system can be released by calling this function. - * - * \param dpy display handle. It becomes invalid at this point. - * - * Destroys the window if any, and destroys the per-screen - * driver private information. - * Calls __miniglx_close_connections(). - * - * If a server, puts the the framebuffer back into the initial state. - * - * Finally frees the display structure. - */ -void -XCloseDisplay( Display *dpy ) -{ - glXMakeCurrent( dpy, NULL, NULL); - - if (dpy->NumWindows) - XDestroyWindow( dpy, dpy->TheWindow ); - - /* As this is done in XOpenDisplay, need to undo it here: - */ - dpy->driScreen.destroyScreen(dpy, 0, dpy->driScreen.private); - - __miniglx_close_connections( dpy ); - - if (!dpy->IsClient) { - /* put framebuffer back to initial state - */ - (*dpy->driver->haltFBDev)( &dpy->driverContext ); - RestoreFBDev(dpy); - CloseFBDev(dpy); - } - - dlclose(dpy->dlHandle); - free(dpy); -} - - -/** - * \brief Window creation. - * - * \param display a display handle, as returned by XOpenDisplay(). - * \param parent the parent window for the new window. For Mini GLX this should - * be - * \code RootWindow(display, 0) \endcode - * \param x the window abscissa. For Mini GLX, it should be zero. - * \param y the window ordinate. For Mini GLX, it should be zero. - * \param width the window width. For Mini GLX, this specifies the desired - * screen width such as 1024 or 1280. - * \param height the window height. For Mini GLX, this specifies the desired - * screen height such as 768 or 1024. - * \param border_width the border width. For Mini GLX, it should be zero. - * \param depth the window pixel depth. For Mini GLX, this should be the depth - * found in the #XVisualInfo object returned by glXChooseVisual() - * \param winclass the window class. For Mini GLX this value should be - * #InputOutput. - * \param visual the visual type. It should be the visual field of the - * #XVisualInfo object returned by glXChooseVisual(). - * \param valuemask which fields of the XSetWindowAttributes() are to be used. - * For Mini GLX this is typically the bitmask - * \code CWBackPixel | CWBorderPixel | CWColormap \endcode - * \param attributes initial window attributes. The - * XSetWindowAttributes::background_pixel, XSetWindowAttributes::border_pixel - * and XSetWindowAttributes::colormap fields should be set. - * - * \return a window handle if it succeeds or zero if it fails. - * - * \note For Mini GLX, windows are full-screen; they cover the entire frame - * buffer. Also, Mini GLX imposes a limit of one window. A second window - * cannot be created until the first one is destroyed. - * - * This function creates and initializes a ::MiniGLXWindowRec structure after - * ensuring that there is no other window created. Performs the per-drawable - * client-side initialization calling the __DRIscreenRec::createDrawable - * method. - * - */ -Window -XCreateWindow( Display *dpy, Window parent, int x, int y, - unsigned int width, unsigned int height, - unsigned int border_width, int depth, unsigned int winclass, - Visual *visual, unsigned long valuemask, - XSetWindowAttributes *attributes ) -{ - const int empty_attribute_list[1] = { None }; - - Window win; - - /* ignored */ - (void) x; - (void) y; - (void) border_width; - (void) depth; - (void) winclass; - (void) valuemask; - (void) attributes; - - if (!dpy->IsClient) { - fprintf(stderr, "Server process may not create windows (currently)\n"); - return NULL; - } - - if (dpy->NumWindows > 0) - return NULL; /* only allow one window */ - - assert(dpy->TheWindow == NULL); - - win = malloc(sizeof(struct MiniGLXWindowRec)); - if (!win) - return NULL; - - /* In rotated mode, translate incoming x,y,width,height into - * 'normal' coordinates. - */ - if (dpy->rotateMode) { - int tmp; - tmp = width; width = height; height = tmp; - tmp = x; x = y; y = tmp; - } - - /* init other per-window fields */ - win->x = x; - win->y = y; - win->w = width; - win->h = height; - win->visual = visual; /* ptr assignment */ - - win->bytesPerPixel = dpy->driverContext.cpp; - win->rowStride = dpy->driverContext.shared.virtualWidth * win->bytesPerPixel; - win->size = win->rowStride * height; - win->frontStart = dpy->driverContext.FBAddress + (win->rowStride * win->x) + (win->y * win->bytesPerPixel); - win->frontBottom = (GLubyte *) win->frontStart + (height-1) * win->rowStride; - - /* This is incorrect: the hardware driver could put the backbuffer - * just about anywhere. These fields, including the above are - * hardware dependent & don't really belong here. - */ - if (visual->mode->doubleBufferMode) { - win->backStart = (GLubyte *) win->frontStart + - win->rowStride * dpy->driverContext.shared.virtualHeight; - win->backBottom = (GLubyte *) win->backStart - + (height - 1) * win->rowStride; - win->curBottom = win->backBottom; - } - else { - /* single buffered */ - win->backStart = NULL; - win->backBottom = NULL; - win->curBottom = win->frontBottom; - } - - dpy->driScreen.createNewDrawable(dpy, visual->mode, (int) win, - &win->driDrawable, GLX_WINDOW_BIT, empty_attribute_list); - - if (!win->driDrawable.private) { - fprintf(stderr, "%s: dri.createDrawable failed\n", __FUNCTION__); - free(win); - return NULL; - } - - dpy->NumWindows++; - dpy->TheWindow = win; - - return win; -} - - -/** - * \brief Destroy window. - * - * \param display display handle. - * \param w window handle. - * - * This function calls XUnmapWindow() and frees window \p w. - * - * In case of destroying the current buffer first unbinds the GLX context - * by calling glXMakeCurrent() with no drawable. - */ -void -XDestroyWindow( Display *display, Window win ) -{ - if (display && display->IsClient && win) { - /* check if destroying the current buffer */ - Window curDraw = glXGetCurrentDrawable(); - if (win == curDraw) { - glXMakeCurrent( display, NULL, NULL); - } - - XUnmapWindow( display, win ); - - /* Destroy the drawable. */ - win->driDrawable.destroyDrawable(display, win->driDrawable.private); - free(win); - - /* unlink window from display */ - display->NumWindows--; - assert(display->NumWindows == 0); - display->TheWindow = NULL; - } -} - - - - -/** - * \brief Create color map structure. - * - * \param dpy the display handle as returned by XOpenDisplay(). - * \param w the window on whose screen you want to create a color map. This - * parameter is ignored by Mini GLX but should be the value returned by the - * \code RootWindow(display, 0) \endcode macro. - * \param visual a visual type supported on the screen. This parameter is - * ignored by Mini GLX but should be the XVisualInfo::visual returned by - * glXChooseVisual(). - * \param alloc the color map entries to be allocated. This parameter is ignored - * by Mini GLX but should be set to #AllocNone. - * - * \return the color map. - * - * This function is only provided to ease porting. Practically a no-op - - * returns a pointer to a dynamically allocated chunk of memory (one byte). - */ -Colormap -XCreateColormap( Display *dpy, Window w, Visual *visual, int alloc ) -{ - (void) dpy; - (void) w; - (void) visual; - (void) alloc; - return (Colormap) malloc(1); -} - - -/** - * \brief Destroy color map structure. - * - * \param display The display handle as returned by XOpenDisplay(). - * \param colormap the color map to destroy. - * - * This function is only provided to ease porting. Practically a no-op. - * - * Frees the memory pointed by \p colormap. - */ -void -XFreeColormap( Display *display, Colormap colormap ) -{ - (void) display; - (void) colormap; - free(colormap); -} - - -/** - * \brief Free client data. - * - * \param data the data that is to be freed. - * - * Frees the memory pointed by \p data. - */ -void -XFree( void *data ) -{ - free(data); -} - - -/** - * \brief Query available visuals. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param vinfo_mask a bitmask indicating which fields of the \p vinfo_template - * are to be matched. The value must be \c VisualScreenMask. - * \param vinfo_template a template whose fields indicate which visual - * attributes must be matched by the results. The XVisualInfo::screen field of - * this structure must be zero. - * \param nitens_return will hold the number of visuals returned. - * - * \return the address of an array of all available visuals. - * - * An example of using XGetVisualInfo() to get all available visuals follows: - * - * \code - * XVisualInfo vinfo_template, *results; - * int nitens_return; - * Display *dpy = XOpenDisplay(NULL); - * vinfo_template.screen = 0; - * results = XGetVisualInfo(dpy, VisualScreenMask, &vinfo_template, &nitens_return); - * \endcode - * - * Returns the list of all ::XVisualInfo available, one per - * ::__GLcontextMode stored in MiniGLXDisplayRec::modes. - */ -XVisualInfo * -XGetVisualInfo( Display *dpy, long vinfo_mask, XVisualInfo *vinfo_template, int *nitens_return ) -{ - const __GLcontextModes *mode; - XVisualInfo *results; - Visual *visResults; - int i, n=0; - - // ASSERT(vinfo_mask == VisualScreenMask); - ASSERT(vinfo_template.screen == 0); - - if (vinfo_mask == VisualIDMask) - { - for ( mode = dpy->driver_modes ; mode != NULL ; mode= mode->next ) - if (mode->visualID == vinfo_template->visualid) - n=1; - - if (n==0) - return NULL; - - results = (XVisualInfo *)calloc(1, n * sizeof(XVisualInfo)); - if (!results) { - *nitens_return = 0; - return NULL; - } - - visResults = (Visual *)calloc(1, n * sizeof(Visual)); - if (!results) { - free(results); - *nitens_return = 0; - return NULL; - } - - for ( mode = dpy->driver_modes ; mode != NULL ; mode= mode->next ) - if (mode->visualID == vinfo_template->visualid) - { - visResults[0].mode=mode; - visResults[0].visInfo = results; - visResults[0].dpy = dpy; - if (dpy->driverContext.bpp == 32) - visResults[0].pixelFormat = PF_B8G8R8A8; /* XXX: FIX ME */ - else - visResults[0].pixelFormat = PF_B5G6R5; /* XXX: FIX ME */ - - results[0].visual = visResults; - results[0].visualid = mode->visualID; -#if defined(__cplusplus) || defined(c_plusplus) - results[0].c_class = TrueColor; -#else - results[0].class = TrueColor; -#endif - results[0].depth = mode->redBits + - mode->redBits + - mode->redBits + - mode->redBits; - results[0].bits_per_rgb = dpy->driverContext.bpp; - - } - - } - else // if (vinfo_mask == VisualScreenMask) - { - n = 0; - for ( mode = dpy->driver_modes ; mode != NULL ; mode = mode->next ) - n++; - - results = (XVisualInfo *)calloc(1, n * sizeof(XVisualInfo)); - if (!results) { - *nitens_return = 0; - return NULL; - } - - visResults = (Visual *)calloc(1, n * sizeof(Visual)); - if (!results) { - free(results); - *nitens_return = 0; - return NULL; - } - - for ( mode = dpy->driver_modes, i = 0 ; mode != NULL ; mode = mode->next, i++ ) { - visResults[i].mode = mode; - visResults[i].visInfo = results + i; - visResults[i].dpy = dpy; - - if (dpy->driverContext.bpp == 32) - visResults[i].pixelFormat = PF_B8G8R8A8; /* XXX: FIX ME */ - else - visResults[i].pixelFormat = PF_B5G6R5; /* XXX: FIX ME */ - - results[i].visual = visResults + i; - results[i].visualid = mode->visualID; -#if defined(__cplusplus) || defined(c_plusplus) - results[i].c_class = TrueColor; -#else - results[i].class = TrueColor; -#endif - results[i].depth = mode->redBits + - mode->redBits + - mode->redBits + - mode->redBits; - results[i].bits_per_rgb = dpy->driverContext.bpp; - } - } - *nitens_return = n; - return results; -} - - -/** - * \brief Return a visual that matches specified attributes. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param screen the screen number. It is currently ignored by Mini GLX and - * should be zero. - * \param attribList a list of GLX attributes which describe the desired pixel - * format. It is terminated by the token \c None. - * - * The attributes are as follows: - * \arg GLX_USE_GL: - * This attribute should always be present in order to maintain compatibility - * with GLX. - * \arg GLX_RGBA: - * If present, only RGBA pixel formats will be considered. Otherwise, only - * color index formats are considered. - * \arg GLX_DOUBLEBUFFER: - * if present, only double-buffered pixel formats will be chosen. - * \arg GLX_RED_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per red pixel component that is acceptable. - * \arg GLX_GREEN_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per green pixel component that is acceptable. - * \arg GLX_BLUE_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per blue pixel component that is acceptable. - * \arg GLX_ALPHA_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per alpha pixel component that is acceptable. - * \arg GLX_STENCIL_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per stencil value that is acceptable. - * \arg GLX_DEPTH_SIZE \e n: - * Must be followed by a non-negative integer indicating the minimum number of - * bits per depth component that is acceptable. - * \arg None: - * This token is used to terminate the attribute list. - * - * \return a pointer to an #XVisualInfo object which most closely matches the - * requirements of the attribute list. If there is no visual which matches the - * request, \c NULL will be returned. - * - * \note Visuals with accumulation buffers are not available. - * - * This function searches the list of available visual configurations in - * MiniGLXDisplayRec::configs for a configuration which best matches the GLX - * attribute list parameter. A new ::XVisualInfo object is created which - * describes the visual configuration. The match criteria is described in the - * specification. - */ -XVisualInfo* -glXChooseVisual( Display *dpy, int screen, int *attribList ) -{ - const __GLcontextModes *mode; - Visual *vis; - XVisualInfo *visInfo; - const int *attrib; - GLboolean rgbFlag = GL_FALSE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE; - GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0; - GLint indexBits = 0, depthBits = 0, stencilBits = 0; - GLint numSamples = 0; - int i=0; - - /* - * XXX in the future, <screen> might be interpreted as a VT - */ - ASSERT(dpy); - ASSERT(screen == 0); - - vis = (Visual *)calloc(1, sizeof(Visual)); - if (!vis) - return NULL; - - visInfo = (XVisualInfo *)malloc(sizeof(XVisualInfo)); - if (!visInfo) { - free(vis); - return NULL; - } - - visInfo->visual = vis; - vis->visInfo = visInfo; - vis->dpy = dpy; - - /* parse the attribute list */ - for (attrib = attribList; attrib && *attrib != None; attrib++) { - switch (attrib[0]) { - case GLX_DOUBLEBUFFER: - dbFlag = GL_TRUE; - break; - case GLX_RGBA: - rgbFlag = GL_TRUE; - break; - case GLX_RED_SIZE: - redBits = attrib[1]; - attrib++; - break; - case GLX_GREEN_SIZE: - greenBits = attrib[1]; - attrib++; - break; - case GLX_BLUE_SIZE: - blueBits = attrib[1]; - attrib++; - break; - case GLX_ALPHA_SIZE: - alphaBits = attrib[1]; - attrib++; - break; - case GLX_STENCIL_SIZE: - stencilBits = attrib[1]; - attrib++; - break; - case GLX_DEPTH_SIZE: - depthBits = attrib[1]; - attrib++; - break; -#if 0 - case GLX_ACCUM_RED_SIZE: - accumRedBits = attrib[1]; - attrib++; - break; - case GLX_ACCUM_GREEN_SIZE: - accumGreenBits = attrib[1]; - attrib++; - break; - case GLX_ACCUM_BLUE_SIZE: - accumBlueBits = attrib[1]; - attrib++; - break; - case GLX_ACCUM_ALPHA_SIZE: - accumAlphaBits = attrib[1]; - attrib++; - break; - case GLX_LEVEL: - /* ignored for now */ - break; -#endif - default: - /* unexpected token */ - fprintf(stderr, "unexpected token in glXChooseVisual attrib list\n"); - free(vis); - free(visInfo); - return NULL; - } - } - - /* search screen configs for suitable visual */ - (void) numSamples; - (void) indexBits; - (void) redBits; - (void) greenBits; - (void) blueBits; - (void) alphaBits; - (void) stereoFlag; - for ( mode = dpy->driver_modes ; mode != NULL ; mode = mode->next ) { - i++; - if (mode->rgbMode == rgbFlag && - mode->doubleBufferMode == dbFlag && - mode->redBits >= redBits && - mode->greenBits >= greenBits && - mode->blueBits >= blueBits && - mode->alphaBits >= alphaBits && - mode->depthBits >= depthBits && - mode->stencilBits >= stencilBits) { - /* found it */ - visInfo->visualid = i; - vis->mode = mode; - break; - } - } - if (!vis->mode) - return NULL; - - /* compute depth and bpp */ - if (rgbFlag) { - /* XXX maybe support depth 16 someday */ -#if defined(__cplusplus) || defined(c_plusplus) - visInfo->c_class = TrueColor; -#else - visInfo->class = TrueColor; -#endif - visInfo->depth = dpy->driverContext.bpp; - visInfo->bits_per_rgb = dpy->driverContext.bpp; - if (dpy->driverContext.bpp == 32) - vis->pixelFormat = PF_B8G8R8A8; - else - vis->pixelFormat = PF_B5G6R5; - } - else { - /* color index mode */ -#if defined(__cplusplus) || defined(c_plusplus) - visInfo->c_class = PseudoColor; -#else - visInfo->class = PseudoColor; -#endif - visInfo->depth = 8; - visInfo->bits_per_rgb = 8; /* bits/pixel */ - vis->pixelFormat = PF_CI8; - } - - return visInfo; -} - - -/** - * \brief Return information about GLX visuals. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param vis the visual to be queried, as returned by glXChooseVisual(). - * \param attrib the visual attribute to be returned. - * \param value pointer to an integer in which the result of the query will be - * stored. - * - * \return zero if no error occurs, \c GLX_INVALID_ATTRIBUTE if the attribute - * parameter is invalid, or \c GLX_BAD_VISUAL if the \p vis parameter is - * invalid. - * - * Returns the appropriate attribute of ::__GLXvisualConfig pointed by - * MiniGLXVisualRec::glxConfig of XVisualInfo::visual. - * - * \sa data types. - */ -int -glXGetConfig( Display *dpy, XVisualInfo *vis, int attrib, int *value ) -{ - const __GLcontextModes *mode = vis->visual->mode; - if (!mode) { - *value = 0; - return GLX_BAD_VISUAL; - } - - switch (attrib) { - case GLX_USE_GL: - *value = True; - return 0; - case GLX_RGBA: - *value = mode->rgbMode; - return 0; - case GLX_DOUBLEBUFFER: - *value = mode->doubleBufferMode; - return 0; - case GLX_RED_SIZE: - *value = mode->redBits; - return 0; - case GLX_GREEN_SIZE: - *value = mode->greenBits; - return 0; - case GLX_BLUE_SIZE: - *value = mode->blueBits; - return 0; - case GLX_ALPHA_SIZE: - *value = mode->alphaBits; - return 0; - case GLX_DEPTH_SIZE: - *value = mode->depthBits; - return 0; - case GLX_STENCIL_SIZE: - *value = mode->stencilBits; - return 0; - default: - *value = 0; - return GLX_BAD_ATTRIBUTE; - } - return 0; -} - - -/** - * \brief Create a new GLX rendering context. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param vis the visual that defines the frame buffer resources available to - * the rendering context, as returned by glXChooseVisual(). - * \param shareList If non-zero, texture objects and display lists are shared - * with the named rendering context. If zero, texture objects and display lists - * will (initially) be private to this context. They may be shared when a - * subsequent context is created. - * \param direct whether direct or indirect rendering is desired. For Mini GLX - * this value is ignored but it should be set to \c True. - * - * \return a ::GLXContext handle if it succeeds or zero if it fails due to - * invalid parameter or insufficient resources. - * - * This function creates and initializes a ::MiniGLXContextRec structure and - * calls the __DRIscreenRec::createContext method to initialize the client - * private data. - */ -GLXContext -glXCreateContext( Display *dpy, XVisualInfo *vis, - GLXContext shareList, Bool direct ) -{ - GLXContext ctx; - void *sharePriv; - - ASSERT(vis); - - ctx = (struct MiniGLXContextRec *)calloc(1, sizeof(struct MiniGLXContextRec)); - if (!ctx) - return NULL; - - ctx->vid = vis->visualid; - - if (shareList) - sharePriv = shareList->driContext.private; - else - sharePriv = NULL; - - ctx->driContext.mode = vis->visual->mode; - ctx->driContext.private = dpy->driScreen.createNewContext(dpy, vis->visual->mode, - GLX_WINDOW_BIT, sharePriv, &ctx->driContext); - - if (!ctx->driContext.private) { - free(ctx); - return NULL; - } - - return ctx; -} - - -/** - * \brief Destroy a GLX context. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param ctx the GLX context to be destroyed. - * - * This function frees the \p ctx parameter after unbinding the current context - * by calling the __DRIcontextRec::bindContext method with zeros and calling - * the __DRIcontextRec::destroyContext method. - */ -void -glXDestroyContext( Display *dpy, GLXContext ctx ) -{ - GLXContext glxctx = glXGetCurrentContext(); - - if (ctx) { - if (glxctx == ctx) { - /* destroying current context */ - ctx->driContext.bindContext(dpy, 0, 0, 0, 0); - CurrentContext = 0; - } - ctx->driContext.destroyContext(dpy, 0, ctx->driContext.private); - free(ctx); - } -} - - -/** - * \brief Bind a GLX context to a window or a pixmap. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param drawable the window or drawable to bind to the rendering context. - * This should be the value returned by XCreateWindow(). - * \param ctx the GLX context to be destroyed. - * - * \return \c True if it succeeds, \c False otherwise to indicate an invalid - * display, window or context parameter. - * - * The current rendering context may be unbound by calling glXMakeCurrent() - * with the window and context parameters set to zero. - * - * An application may create any number of rendering contexts and bind them as - * needed. Note that binding a rendering context is generally not a - * light-weight operation. Most simple OpenGL applications create only one - * rendering context. - * - * This function first unbinds any old context via - * __DRIcontextRec::unbindContext and binds the new one via - * __DRIcontextRec::bindContext. - * - * If \p drawable is zero it unbinds the GLX context by calling - * __DRIcontextRec::bindContext with zeros. - */ -Bool -glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx) -{ - if (dpy && drawable && ctx) { - GLXContext oldContext = glXGetCurrentContext(); - GLXDrawable oldDrawable = glXGetCurrentDrawable(); - /* unbind old */ - if (oldContext) { - oldContext->driContext.unbindContext(dpy, 0, - (__DRIid) oldDrawable, (__DRIid) oldDrawable, - &oldContext->driContext); - } - /* bind new */ - CurrentContext = ctx; - ctx->driContext.bindContext(dpy, 0, (__DRIid) drawable, - (__DRIid) drawable, &ctx->driContext); - ctx->drawBuffer = drawable; - ctx->curBuffer = drawable; - } - else if (ctx && dpy) { - /* unbind */ - ctx->driContext.bindContext(dpy, 0, 0, 0, 0); - } - else if (dpy) { - CurrentContext = 0; /* kw: this seems to be intended??? */ - } - - return True; -} - - -/** - * \brief Exchange front and back buffers. - * - * \param dpy the display handle, as returned by XOpenDisplay(). - * \param drawable the drawable whose buffers are to be swapped. - * - * Any pending rendering commands will be completed before the buffer swap - * takes place. - * - * Calling glXSwapBuffers() on a window which is single-buffered has no effect. - * - * This function just calls the __DRIdrawableRec::swapBuffers method to do the - * work. - */ -void -glXSwapBuffers( Display *dpy, GLXDrawable drawable ) -{ - if (!dpy || !drawable) - return; - - drawable->driDrawable.swapBuffers(dpy, drawable->driDrawable.private); -} - - -/** - * \brief Return the current context - * - * \return the current context, as specified by glXMakeCurrent(), or zero if no - * context is currently bound. - * - * \sa glXCreateContext(), glXMakeCurrent() - * - * Returns the value of the ::CurrentContext global variable. - */ -GLXContext -glXGetCurrentContext( void ) -{ - return CurrentContext; -} - - -/** - * \brief Return the current drawable. - * - * \return the current drawable, as specified by glXMakeCurrent(), or zero if - * no drawable is currently bound. - * - * This function gets the current context via glXGetCurrentContext() and - * returns the MiniGLXContextRec::drawBuffer attribute. - */ -GLXDrawable -glXGetCurrentDrawable( void ) -{ - GLXContext glxctx = glXGetCurrentContext(); - if (glxctx) - return glxctx->drawBuffer; - else - return NULL; -} - - -static GLboolean -__glXCreateContextWithConfig(__DRInativeDisplay *dpy, int screen, - int fbconfigID, void *contextID, drm_context_t *hHWContext) -{ - __DRIscreen *pDRIScreen; - __DRIscreen *psp; - - pDRIScreen = __glXFindDRIScreen(dpy, screen); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - return GL_FALSE; - } - - psp = (__DRIscreen *) pDRIScreen->private; - - if (psp->fd) { - if (drmCreateContext(psp->fd, hHWContext)) { - fprintf(stderr, ">>> drmCreateContext failed\n"); - return GL_FALSE; - } - *(void**)contextID = (void*) *hHWContext; - } - - return GL_TRUE; -} - - -static GLboolean -__glXGetDrawableInfo(__DRInativeDisplay *dpy, int scrn, - __DRIid draw, unsigned int * index, unsigned int * stamp, - int * x, int * y, int * width, int * height, - int * numClipRects, drm_clip_rect_t ** pClipRects, - int * backX, int * backY, - int * numBackClipRects, drm_clip_rect_t ** pBackClipRects) -{ - GLXDrawable drawable = (GLXDrawable) draw; - drm_clip_rect_t * cliprect; - Display* display = (Display*)dpy; - __DRIscreen *psp = display->driScreen.private; - __DRIcontext *pcp = (__DRIcontext *)CurrentContext->driContext.private; - __DRIdrawable *pdp = pcp->driDrawablePriv; - if (drawable == 0) { - return GL_FALSE; - } - - cliprect = (drm_clip_rect_t*) _mesa_malloc(sizeof(drm_clip_rect_t)); - cliprect->x1 = drawable->x; - cliprect->y1 = drawable->y; - cliprect->x2 = drawable->x + drawable->w; - cliprect->y2 = drawable->y + drawable->h; - - /* the drawable index is by client id */ - *index = display->clientID; - - *stamp = pcp->driScreenPriv->pSAREA->drawableTable[display->clientID].stamp; - drmUpdateDrawableInfo(psp->fd, pdp->hHWDrawable, DRM_DRAWABLE_CLIPRECTS, 1, cliprect); - *x = drawable->x; - *y = drawable->y; - *width = drawable->w; - *height = drawable->h; - *numClipRects = 1; - *pClipRects = cliprect; - - *backX = drawable->x; - *backY = drawable->y; - *numBackClipRects = 0; - *pBackClipRects = 0; - - return GL_TRUE; -} - - -static GLboolean -xf86DRI_DestroyContext(__DRInativeDisplay *dpy, int screen, __DRIid context_id ) -{ - return GL_TRUE; -} - - -static GLboolean -xf86DRI_CreateDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable, - drm_drawable_t *hHWDrawable ) -{ - - Display *display = (Display *)dpy; - __DRIscreen *psp = display->driScreen.private; - int ret; - ret = drmCreateDrawable(psp->fd, hHWDrawable); - - fprintf(stderr, "drawable is %d %08X ret is %d\n", *hHWDrawable, drawable, -ret); - if (ret != 0) - return GL_FALSE; - return GL_TRUE; -} - - -static GLboolean -xf86DRI_DestroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable) -{ - return GL_TRUE; -} - - -/** - * \brief Query function address. - * - * The glXGetProcAddress() function will return the address of any available - * OpenGL or Mini GLX function. - * - * \param procName name of the function to be returned. - * - * \return If \p procName is a valid function name, a pointer to that function - * will be returned. Otherwise, \c NULL will be returned. - * - * The purpose of glXGetProcAddress() is to facilitate using future extensions - * to OpenGL or Mini GLX. If a future version of the library adds new extension - * functions they'll be accessible via glXGetProcAddress(). The alternative is - * to hard-code calls to the new functions in the application but doing so will - * prevent linking the application with older versions of the library. - * - * Returns the function address by looking up its name in a static (name, - * address) pair list. - */ -void (*glXGetProcAddress(const GLubyte *procname))( void ) -{ - struct name_address { - const char *name; - const void *func; - }; - static const struct name_address functions[] = { - { "glXChooseVisual", (void *) glXChooseVisual }, - { "glXCreateContext", (void *) glXCreateContext }, - { "glXDestroyContext", (void *) glXDestroyContext }, - { "glXMakeCurrent", (void *) glXMakeCurrent }, - { "glXSwapBuffers", (void *) glXSwapBuffers }, - { "glXGetCurrentContext", (void *) glXGetCurrentContext }, - { "glXGetCurrentDrawable", (void *) glXGetCurrentDrawable }, - { "glXGetProcAddress", (void *) glXGetProcAddress }, - { "XOpenDisplay", (void *) XOpenDisplay }, - { "XCloseDisplay", (void *) XCloseDisplay }, - { "XCreateWindow", (void *) XCreateWindow }, - { "XDestroyWindow", (void *) XDestroyWindow }, - { "XMapWindow", (void *) XMapWindow }, - { "XCreateColormap", (void *) XCreateColormap }, - { "XFreeColormap", (void *) XFreeColormap }, - { "XFree", (void *) XFree }, - { "XGetVisualinfo", (void *) XGetVisualInfo }, - { "glXCreatePbuffer", (void *) glXCreatePbuffer }, - { "glXDestroyPbuffer", (void *) glXDestroyPbuffer }, - { "glXChooseFBConfig", (void *) glXChooseFBConfig }, - { "glXGetVisualFromFBConfig", (void *) glXGetVisualFromFBConfig }, - { NULL, NULL } - }; - const struct name_address *entry; - for (entry = functions; entry->name; entry++) { - if (strcmp(entry->name, (const char *) procname) == 0) { - return entry->func; - } - } - return _glapi_get_proc_address((const char *) procname); -} - -void (*glXGetProcAddressARB(const GLubyte *procName))( void ) __attribute__ ((alias ("glXGetProcAddress"))); - -/** - * \brief Query the Mini GLX version. - * - * \param dpy the display handle. It is currently ignored, but should be the - * value returned by XOpenDisplay(). - * \param major receives the major version number of Mini GLX. - * \param minor receives the minor version number of Mini GLX. - * - * \return \c True if the function succeeds, \c False if the function fails due - * to invalid parameters. - * - * \sa #MINI_GLX_VERSION_1_0. - * - * Returns the hard-coded Mini GLX version. - */ -Bool -glXQueryVersion( Display *dpy, int *major, int *minor ) -{ - (void) dpy; - *major = 1; - *minor = 0; - return True; -} - - -/** - * \brief Create a new pbuffer. - */ -GLXPbuffer -glXCreatePbuffer( Display *dpy, GLXFBConfig config, const int *attribList ) -{ - return NULL; -} - - -void -glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) -{ - free(pbuf); -} - - -GLXFBConfig * -glXChooseFBConfig( Display *dpy, int screen, const int *attribList, - int *nitems ) -{ - GLXFBConfig *f = (GLXFBConfig *) malloc(sizeof(GLXFBConfig)); - f->visInfo = glXChooseVisual( dpy, screen, (int *) attribList ); - if (f->visInfo) { - *nitems = 1; - return f; - } - else { - *nitems = 0; - free(f); - return NULL; - } -} - - -XVisualInfo * -glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) -{ - /* XVisualInfo and GLXFBConfig are the same structure */ - (void) dpy; - return config.visInfo; -} - -void *glXAllocateMemoryMESA(Display *dpy, int scrn, - size_t size, float readFreq, - float writeFreq, float priority) -{ - if (dpy->driScreen.private && dpy->driScreen.allocateMemory) { - return (*dpy->driScreen.allocateMemory)( dpy, scrn, size, - readFreq, writeFreq, - priority ); - } - - return NULL; -} - -void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) -{ - if (dpy->driScreen.private && dpy->driScreen.freeMemory) { - (*dpy->driScreen.freeMemory)( dpy, scrn, pointer ); - } -} - -GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, - const void *pointer ) -{ - if (dpy->driScreen.private && dpy->driScreen.memoryOffset) { - return (*dpy->driScreen.memoryOffset)( dpy, scrn, pointer ); - } - - return 0; -} - - -/** - * Get the unadjusted system time (UST). Currently, the UST is measured in - * microseconds since Epoc. The actual resolution of the UST may vary from - * system to system, and the units may vary from release to release. - * Drivers should not call this function directly. They should instead use - * \c glXGetProcAddress to obtain a pointer to the function. - * - * \param ust Location to store the 64-bit UST - * \returns Zero on success or a negative errno value on failure. - * - * \note - * This function was copied directly from src/glx/x11/glxcmds.c. - */ -static int __glXGetUST( int64_t * ust ) -{ - struct timeval tv; - - if ( ust == NULL ) { - return -EFAULT; - } - - if ( gettimeofday( & tv, NULL ) == 0 ) { - ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; - return 0; - } else { - return -errno; - } -} - - -/** - * - * \bug - * This needs to be implemented for miniGlx. - */ -static GLboolean __glXGetMscRate(__DRInativeDisplay * dpy, __DRIid drawable, - int32_t * numerator, int32_t * denominator) -{ - *numerator = 0; - *denominator = 0; - return False; -} -/*@}*/ diff --git a/src/glx/mini/miniglxP.h b/src/glx/mini/miniglxP.h deleted file mode 100644 index 96ed0e81cd..0000000000 --- a/src/glx/mini/miniglxP.h +++ /dev/null @@ -1,205 +0,0 @@ -/** - * \file miniglxP.h - * \brief Define replacements for some X data types and define the DRI-related - * data structures. - * - * \note Cut down version of glxclient.h. - * - */ - -#ifndef _mini_GLX_client_h_ -#define _mini_GLX_client_h_ - -#include <signal.h> -#include <linux/fb.h> - -#include <GL/miniglx.h> -#include "glheader.h" -#include "mtypes.h" - -#include "driver.h" -#include "GL/internal/dri_interface.h" - -/** - * \brief Supported pixel formats. - */ -enum PixelFormat { - PF_B8G8R8, /**< \brief 24-bit BGR */ - PF_B8G8R8A8, /**< \brief 32-bit BGRA */ - PF_B5G6R5, /**< \brief 16-bit BGR */ - PF_B5G5R5, /**< \brief 15-bit BGR */ - PF_CI8 /**< \brief 8-bit color index */ -}; - -/** - * \brief X Visual type. - * - * \sa ::Visual, \ref datatypes. - */ -struct MiniGLXVisualRec { - /** \brief GLX visual information */ - const __GLcontextModes *mode; - - /** \brief pointer back to corresponding ::XVisualInfo */ - XVisualInfo *visInfo; - - /** \brief display handle */ - Display *dpy; - - /** \brief pixel format */ - enum PixelFormat pixelFormat; -}; - - - -/** - * \brief X Window type. - * - * \sa ::Window, \ref datatypes. - */ -struct MiniGLXWindowRec { - Visual *visual; - /** \brief position (always 0,0) */ - int x, y; - /** \brief size */ - unsigned int w, h; - void *frontStart; /**< \brief start of front color buffer */ - void *backStart; /**< \brief start of back color buffer */ - size_t size; /**< \brief color buffer size, in bytes */ - GLuint bytesPerPixel; - GLuint rowStride; /**< \brief in bytes */ - GLubyte *frontBottom; /**< \brief pointer to last row */ - GLubyte *backBottom; /**< \brief pointer to last row */ - GLubyte *curBottom; /**< = frontBottom or backBottom */ - __DRIdrawable driDrawable; - GLuint ismapped; -}; - - -/** - * \brief GLXContext type. - * - * \sa ::GLXContext, \ref datatypes. - */ -struct MiniGLXContextRec { - Window drawBuffer; /**< \brief drawing buffer */ - Window curBuffer; /**< \brief current buffer */ - VisualID vid; /**< \brief visual ID */ - __DRIcontext driContext; /**< \brief context dependent methods */ -}; - -#define MINIGLX_BUF_SIZE 512 -#define MINIGLX_MAX_SERVER_FDS 10 -#define MINIGLX_MAX_CLIENT_FDS 1 -#define MINIGLX_EVENT_QUEUE_SZ 16 -#define MINIGLX_EVENT_QUEUE_MASK (MINIGLX_EVENT_QUEUE_SZ-1) - -/** - * A connection to/from the server - * - * All information is to/from the server is buffered and then dispatched by - * __miniglx_Select() to avoid blocking the server. - */ -struct MiniGLXConnection { - int fd; /**< \brief file descriptor */ - char readbuf[MINIGLX_BUF_SIZE]; /**< \brief read buffer */ - char writebuf[MINIGLX_BUF_SIZE]; /**< \brief write buffer */ - int readbuf_count; /**< \brief count of bytes waiting to be read */ - int writebuf_count; /**< \brief count of bytes waiting to be written */ -}; - - -/** - * \brief X Display type - * - * \sa ::Display, \ref datatypes. - */ -struct MiniGLXDisplayRec { - /** \brief fixed framebuffer screen info */ - struct fb_fix_screeninfo FixedInfo; - /** \brief original and current variable framebuffer screen info */ - struct fb_var_screeninfo OrigVarInfo, VarInfo; - struct sigaction OrigSigUsr1; - struct sigaction OrigSigUsr2; - int OriginalVT; - int ConsoleFD; /**< \brief console TTY device file descriptor */ - int FrameBufferFD; /**< \brief framebuffer device file descriptor */ - int NumWindows; /**< \brief number of open windows */ - Window TheWindow; /**< \brief open window - only allow one window for now */ - int rotateMode; - - - volatile int vtSignalFlag; - volatile int haveVT; /**< \brief whether the VT is hold */ - int hwActive; /**< \brief whether the hardware is active -- mimics - the variations of MiniGLXDisplayRec::haveVT */ - - - int IsClient; /**< \brief whether it's a client or the server */ - int clientID; - int nrFds; /**< \brief number of connections (usually just one for the clients) */ - struct MiniGLXConnection *fd; /**< \brief connections */ - int drmFd; /**< \brief handle to drm device */ - int authorized; /**< \brief has server authorized this process? */ - - struct { - int nr, head, tail; - XEvent queue[MINIGLX_EVENT_QUEUE_SZ]; - } eventqueue; - - /** - * \name Visuals - * - * Visuals (configs) in this screen. - */ - /*@{*/ - const __GLcontextModes *driver_modes; /**< \brief Modes filtered by driver. */ - /*@}*/ - - /** - * \name From __GLXdisplayPrivate - */ - /*@{*/ - PFNCREATENEWSCREENFUNC createNewScreen; /**< \brief \e __driCreateScreen hook */ - __DRIscreen driScreen; /**< \brief Screen dependent methods */ - void *dlHandle; /**< - * \brief handle to the client dynamic - * library - */ - /*@}*/ - - /** - * \brief Mini GLX specific driver hooks - */ - struct DRIDriverRec *driver; - struct DRIDriverContextRec driverContext; - - /** - * \name Configuration details - * - * They are read from a configuration file by __read_config_file(). - */ - /*@{*/ - const char *fbdevDevice; - const char *clientDriverName; - /*@}*/ -}; - -/** Character messages. */ -enum msgs { - _CanIHaveFocus, - _IDontWantFocus, - _YouveGotFocus, - _YouveLostFocus, - _RepaintPlease, - _Authorize, -}; -extern int send_msg( Display *dpy, int i, const void *msg, size_t sz ); -extern int send_char_msg( Display *dpy, int i, char msg ); -extern int blocking_read( Display *dpy, int connection, char *msg, size_t msg_size ); -extern int handle_fd_events( Display *dpy, int nonblock ); - -extern int __miniglx_open_connections( Display *dpy ); -extern void __miniglx_close_connections( Display *dpy ); - -#endif /* !_mini_GLX_client_h_ */ diff --git a/src/glx/mini/miniglx_events.c b/src/glx/mini/miniglx_events.c deleted file mode 100644 index a20d5847b3..0000000000 --- a/src/glx/mini/miniglx_events.c +++ /dev/null @@ -1,983 +0,0 @@ -/** - * \file miniglx_events.c - * \brief Mini GLX client/server communication functions. - * \author Keith Whitwell - * - * The Mini GLX interface is a subset of the GLX interface, plus a - * minimal set of Xlib functions. This file adds interfaces to - * arbitrate a single cliprect between multiple direct rendering - * clients. - * - * A fairly complete client/server non-blocking communication - * mechanism. Probably overkill given that none of our messages - * currently exceed 1 byte in length and take place over the - * relatively benign channel provided by a Unix domain socket. - */ - -/* - * Mesa 3-D graphics library - * Version: 5.0 - * - * Copyright (C) 1999-2003 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 - * BRIAN PAUL 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 <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/stat.h> - -#include <linux/kd.h> -#include <linux/vt.h> - -#include "xf86drm.h" -#include "miniglxP.h" - - -#define MINIGLX_FIFO_NAME "/tmp/miniglx.fifo" - -/** - * \brief Allocate an XEvent structure on the event queue. - * - * \param dpy the display handle. - * - * \return Pointer to the queued event structure or NULL on failure. - * - * \internal - * If there is space on the XEvent queue, return a pointer - * to the next free event and increment the eventqueue tail value. - * Otherwise return null. - */ -static XEvent *queue_event( Display *dpy ) -{ - int incr = (dpy->eventqueue.tail + 1) & MINIGLX_EVENT_QUEUE_MASK; - if (incr == dpy->eventqueue.head) { - return 0; - } - else { - XEvent *ev = &dpy->eventqueue.queue[dpy->eventqueue.tail]; - dpy->eventqueue.tail = incr; - return ev; - } -} - -/** - * \brief Dequeue an XEvent and copy it into provided storage. - * - * \param dpy the display handle. - * \param event_return pointer to copy the queued event to. - * - * \return True or False depending on success. - * - * \internal - * If there is a queued XEvent on the queue, copy it to the provided - * pointer and increment the eventqueue head value. Otherwise return - * null. - */ -static int dequeue_event( Display *dpy, XEvent *event_return ) -{ - if (dpy->eventqueue.tail == dpy->eventqueue.head) { - return False; - } - else { - *event_return = dpy->eventqueue.queue[dpy->eventqueue.head]; - dpy->eventqueue.head += 1; - dpy->eventqueue.head &= MINIGLX_EVENT_QUEUE_MASK; - return True; - } -} - -/** - * \brief Shutdown a socket connection. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * - * \internal - * Shutdown and close the file descriptor. If this is the special - * connection in fd[0], issue an error message and exit - there's been - * some sort of failure somewhere. Otherwise, let the application - * know about whats happened by issuing a DestroyNotify event. - */ -static void shut_fd( Display *dpy, int i ) -{ - if (dpy->fd[i].fd < 0) - return; - - shutdown (dpy->fd[i].fd, SHUT_RDWR); - close (dpy->fd[i].fd); - dpy->fd[i].fd = -1; - dpy->fd[i].readbuf_count = 0; - dpy->fd[i].writebuf_count = 0; - - if (i == 0) { - fprintf(stderr, "server connection lost\n"); - exit(1); - } - else { - /* Pass this to the application as a DestroyNotify event. - */ - XEvent *er = queue_event(dpy); - if (!er) return; - er->xdestroywindow.type = DestroyNotify; - er->xdestroywindow.serial = 0; - er->xdestroywindow.send_event = 0; - er->xdestroywindow.display = dpy; - er->xdestroywindow.window = (Window)i; - - drmGetLock(dpy->driverContext.drmFD, 1, 0); - drmUnlock(dpy->driverContext.drmFD, 1); - } -} - -/** - * \brief Send a message to a socket connection. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * \param msg the message to send. - * \param sz the size of the message - * - * \internal - * Copy the message to the write buffer for the nominated connection. - * This will be actually sent to that file descriptor from - * __miniglx_Select(). - */ -int send_msg( Display *dpy, int i, - const void *msg, size_t sz ) -{ - int cnt = dpy->fd[i].writebuf_count; - if (MINIGLX_BUF_SIZE - cnt < sz) { - fprintf(stderr, "client %d: writebuf overflow\n", i); - return False; - } - - memcpy( dpy->fd[i].writebuf + cnt, msg, sz ); cnt += sz; - dpy->fd[i].writebuf_count = cnt; - return True; -} - -/** - * \brief Send a message to a socket connection. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * \param msg the message to send. - * - * \internal - * Use send_msg() to send a one-byte message to a socket. - */ -int send_char_msg( Display *dpy, int i, char msg ) -{ - return send_msg( dpy, i, &msg, sizeof(char)); -} - - -/** - * \brief Block and receive a message from a socket connection. - * - * \param dpy the display handle. - * \param connection the index in dpy->fd of the socket connection. - * \param msg storage for the received message. - * \param msg_size the number of bytes to read. - * - * \internal - * Block and read from the connection's file descriptor - * until msg_size bytes have been received. - * - * Only called from welcome_message_part(). - */ -int blocking_read( Display *dpy, int connection, - char *msg, size_t msg_size ) -{ - int i, r; - - for (i = 0 ; i < msg_size ; i += r) { - r = read(dpy->fd[connection].fd, msg + i, msg_size - i); - if (r < 1) { - fprintf(stderr, "blocking_read: %d %s\n", r, strerror(errno)); - shut_fd(dpy,connection); - return False; - } - } - - return True; -} - -/** - * \brief Send/receive a part of the welcome message. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * \param msg storage for the sent/received message. - * \param sz the number of bytes to write/read. - * - * \return True on success, or False on failure. - * - * This function is called by welcome_message_part(), to either send or receive - * (via blocking_read()) part of the welcome message, according to whether - * Display::IsClient is set. - * - * Each part of the welcome message on the wire consists of a count and then the - * actual message data with that number of bytes. - */ -static int welcome_message_part( Display *dpy, int i, void **msg, int sz ) -{ - if (dpy->IsClient) { - int sz; - if (!blocking_read( dpy, i, (char *)&sz, sizeof(sz))) return False; - if (!*msg) *msg = malloc(sz); - if (!*msg) return False; - if (!blocking_read( dpy, i, *msg, sz )) return False; - return sz; - } - else { - if (!send_msg( dpy, i, &sz, sizeof(sz))) return False; - if (!send_msg( dpy, i, *msg, sz )) return False; - } - - return True; -} - -/** - * \brief Send/receive the welcome message. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * - * \return True on success, or False on failure. - * - * Using welcome_message_part(), sends/receives the client ID, the client - * configuration details in DRIDriverContext::shared, and the driver private - * message in DRIDriverContext::driverClientMsg. - */ -static int welcome_message( Display *dpy, int i ) -{ - void *tmp = &dpy->driverContext.shared; - int *clientid = dpy->IsClient ? &dpy->clientID : &i; - int size; - - if (!welcome_message_part( dpy, i, (void **)&clientid, sizeof(*clientid))) - return False; - - if (!welcome_message_part( dpy, i, &tmp, sizeof(dpy->driverContext.shared))) - return False; - - size=welcome_message_part( dpy, i, - (void **)&dpy->driverContext.driverClientMsg, - dpy->driverContext.driverClientMsgSize ); - - if (!size) - return False; - - if (dpy->IsClient) { - dpy->driverContext.driverClientMsgSize = size; - } - return True; -} - - -/** - * \brief Handle a new client connection. - * - * \param dpy the display handle. - * - * \return True on success or False on failure. - * - * Accepts the connection, sets it in non-blocking operation, and finds a free - * slot in Display::fd for it. - */ -static int handle_new_client( Display *dpy ) -{ - struct sockaddr_un client_address; - unsigned int l = sizeof(client_address); - int r, i; - - r = accept(dpy->fd[0].fd, (struct sockaddr *) &client_address, &l); - if (r < 0) { - perror ("accept()"); - shut_fd(dpy,0); - return False; - } - - if (fcntl(r, F_SETFL, O_NONBLOCK) != 0) { - perror("fcntl"); - close(r); - return False; - } - - - /* Some rough & ready adaption of the XEvent semantics. - */ - for (i = 1 ; i < dpy->nrFds ; i++) { - if (dpy->fd[i].fd < 0) { - XEvent *er = queue_event(dpy); - if (!er) { - close(r); - return False; - } - - dpy->fd[i].fd = r; - er->xcreatewindow.type = CreateNotify; - er->xcreatewindow.serial = 0; - er->xcreatewindow.send_event = 0; - er->xcreatewindow.display = dpy; - er->xcreatewindow.window = (Window)i; /* fd slot == window, now? */ - - /* Send the driver client message - this is expected as the - * first message on a new connection. The recpient already - * knows the size of the message. - */ - welcome_message( dpy, i ); - return True; - } - } - - - fprintf(stderr, "[miniglx] %s: Max nr clients exceeded\n", __FUNCTION__); - close(r); - return False; -} - -/** - * This routine "puffs out" the very basic communications between - * client and server to full-sized X Events that can be handled by the - * application. - * - * \param dpy the display handle. - * \param i the index in dpy->fd of the socket connection. - * - * \return True on success or False on failure. - * - * \internal - * Interprets the message (see msg) into a XEvent and advances the file FIFO - * buffer. - */ -static int -handle_fifo_read( Display *dpy, int i ) -{ - drm_magic_t magic; - int err; - - while (dpy->fd[i].readbuf_count) { - char id = dpy->fd[i].readbuf[0]; - XEvent *er; - int count = 1; - - if (dpy->IsClient) { - switch (id) { - /* The server has called XMapWindow on a client window */ - case _YouveGotFocus: - er = queue_event(dpy); - if (!er) return False; - er->xmap.type = MapNotify; - er->xmap.serial = 0; - er->xmap.send_event = False; - er->xmap.display = dpy; - er->xmap.event = dpy->TheWindow; - er->xmap.window = dpy->TheWindow; - er->xmap.override_redirect = False; - if (dpy->driver->notifyFocus) - dpy->driver->notifyFocus( 1 ); - break; - - /* The server has called XMapWindow on a client window */ - case _RepaintPlease: - er = queue_event(dpy); - if (!er) return False; - er->xexpose.type = Expose; - er->xexpose.serial = 0; - er->xexpose.send_event = False; - er->xexpose.display = dpy; - er->xexpose.window = dpy->TheWindow; - if (dpy->rotateMode) { - er->xexpose.x = dpy->TheWindow->y; - er->xexpose.y = dpy->TheWindow->x; - er->xexpose.width = dpy->TheWindow->h; - er->xexpose.height = dpy->TheWindow->w; - } - else { - er->xexpose.x = dpy->TheWindow->x; - er->xexpose.y = dpy->TheWindow->y; - er->xexpose.width = dpy->TheWindow->w; - er->xexpose.height = dpy->TheWindow->h; - } - er->xexpose.count = 0; - break; - - /* The server has called 'XUnmapWindow' on a client - * window. - */ - case _YouveLostFocus: - er = queue_event(dpy); - if (!er) return False; - er->xunmap.type = UnmapNotify; - er->xunmap.serial = 0; - er->xunmap.send_event = False; - er->xunmap.display = dpy; - er->xunmap.event = dpy->TheWindow; - er->xunmap.window = dpy->TheWindow; - er->xunmap.from_configure = False; - if (dpy->driver->notifyFocus) - dpy->driver->notifyFocus( 0 ); - break; - - case _Authorize: - dpy->authorized = True; - break; - - default: - fprintf(stderr, "Client received unhandled message type %d\n", id); - shut_fd(dpy, i); /* Actually shuts down the client */ - return False; - } - } - else { - switch (id) { - /* Lets the server know that the client is ready to render - * (having called 'XMapWindow' locally). - */ - case _CanIHaveFocus: - er = queue_event(dpy); - if (!er) return False; - er->xmaprequest.type = MapRequest; - er->xmaprequest.serial = 0; - er->xmaprequest.send_event = False; - er->xmaprequest.display = dpy; - er->xmaprequest.parent = 0; - er->xmaprequest.window = (Window)i; - break; - - /* Both _YouveLostFocus and _IDontWantFocus generate unmap - * events. The idea is that _YouveLostFocus lets the client - * know that it has had focus revoked by the server, whereas - * _IDontWantFocus lets the server know that the client has - * unmapped its own window. - */ - case _IDontWantFocus: - er = queue_event(dpy); - if (!er) return False; - er->xunmap.type = UnmapNotify; - er->xunmap.serial = 0; - er->xunmap.send_event = False; - er->xunmap.display = dpy; - er->xunmap.event = (Window)i; - er->xunmap.window = (Window)i; - er->xunmap.from_configure = False; - break; - - case _Authorize: - /* is full message here yet? */ - if (dpy->fd[i].readbuf_count < count + sizeof(magic)) { - count = 0; - break; - } - memcpy(&magic, dpy->fd[i].readbuf + count, sizeof(magic)); - fprintf(stderr, "Authorize - magic %d\n", magic); - - err = drmAuthMagic(dpy->driverContext.drmFD, magic); - count += sizeof(magic); - - send_char_msg( dpy, i, _Authorize ); - break; - - default: - fprintf(stderr, "Server received unhandled message type %d\n", id); - shut_fd(dpy, i); /* Generates DestroyNotify event */ - return False; - } - } - - dpy->fd[i].readbuf_count -= count; - - if (dpy->fd[i].readbuf_count) { - memmove(dpy->fd[i].readbuf, - dpy->fd[i].readbuf + count, - dpy->fd[i].readbuf_count); - } - } - - return True; -} - -/** - * Handle a VT signal - * - * \param dpy display handle. - * - * The VT switches is detected by comparing Display::haveVT and - * Display::hwActive. When loosing the VT the hardware lock is acquired, the - * hardware is shutdown via a call to DRIDriverRec::shutdownHardware(), and the - * VT released. When acquiring the VT back the hardware state is restored via a - * call to DRIDriverRec::restoreHardware() and the hardware lock released. - */ -static void __driHandleVtSignals( Display *dpy ) -{ - dpy->vtSignalFlag = 0; - - fprintf(stderr, "%s: haveVT %d hwActive %d\n", __FUNCTION__, - dpy->haveVT, dpy->hwActive); - - if (!dpy->haveVT && dpy->hwActive) { - /* Need to get lock and shutdown hardware */ - DRM_LIGHT_LOCK( dpy->driverContext.drmFD, - dpy->driverContext.pSAREA, - dpy->driverContext.serverContext ); - dpy->driver->shutdownHardware( &dpy->driverContext ); - - /* Can now give up control of the VT */ - ioctl( dpy->ConsoleFD, VT_RELDISP, 1 ); - dpy->hwActive = 0; - } - else if (dpy->haveVT && !dpy->hwActive) { - /* Get VT (wait??) */ - ioctl( dpy->ConsoleFD, VT_RELDISP, VT_ACTIVATE ); - - /* restore HW state, release lock */ - dpy->driver->restoreHardware( &dpy->driverContext ); - DRM_UNLOCK( dpy->driverContext.drmFD, - dpy->driverContext.pSAREA, - dpy->driverContext.serverContext ); - dpy->hwActive = 1; - } -} - - -#undef max -#define max(x,y) ((x) > (y) ? (x) : (y)) - -/** - * Logic for the select() call. - * - * \param dpy display handle. - * \param n highest fd in any set plus one. - * \param rfds fd set to be watched for reading, or NULL to create one. - * \param wfds fd set to be watched for writing, or NULL to create one. - * \param xfds fd set to be watched for exceptions or error, or NULL to create one. - * \param tv timeout value, or NULL for no timeout. - * - * \return number of file descriptors contained in the sets, or a negative number on failure. - * - * \note - * This all looks pretty complex, but is necessary especially on the - * server side to prevent a poorly-behaved client from causing the - * server to block in a read or write and hence not service the other - * clients. - * - * \sa - * See select_tut in the Linux manual pages for more discussion. - * - * \internal - * Creates and initializes the file descriptor sets by inspecting Display::fd - * if these aren't passed in the function call. Calls select() and fulfill the - * demands by trying to fill MiniGLXConnection::readbuf and draining - * MiniGLXConnection::writebuf. - * The server fd[0] is handled specially for new connections, by calling - * handle_new_client(). - * - */ -int -__miniglx_Select( Display *dpy, int n, fd_set *rfds, fd_set *wfds, fd_set *xfds, - struct timeval *tv ) -{ - int i; - int retval; - fd_set my_rfds, my_wfds; - struct timeval my_tv; - - if (!rfds) { - rfds = &my_rfds; - FD_ZERO(rfds); - } - - if (!wfds) { - wfds = &my_wfds; - FD_ZERO(wfds); - } - - /* Don't block if there are events queued. Review this if the - * flush in XMapWindow is changed to blocking. (Test case: - * miniglxtest). - */ - if (dpy->eventqueue.head != dpy->eventqueue.tail) { - my_tv.tv_sec = my_tv.tv_usec = 0; - tv = &my_tv; - } - - for (i = 0 ; i < dpy->nrFds; i++) { - if (dpy->fd[i].fd < 0) - continue; - - if (dpy->fd[i].writebuf_count) - FD_SET(dpy->fd[i].fd, wfds); - - if (dpy->fd[i].readbuf_count < MINIGLX_BUF_SIZE) - FD_SET(dpy->fd[i].fd, rfds); - - n = max(n, dpy->fd[i].fd + 1); - } - - if (dpy->vtSignalFlag) - __driHandleVtSignals( dpy ); - - retval = select( n, rfds, wfds, xfds, tv ); - - if (dpy->vtSignalFlag) { - int tmp = errno; - __driHandleVtSignals( dpy ); - errno = tmp; - } - - if (retval < 0) { - FD_ZERO(rfds); - FD_ZERO(wfds); - return retval; - } - - /* Handle server fd[0] specially on the server - accept new client - * connections. - */ - if (!dpy->IsClient) { - if (FD_ISSET(dpy->fd[0].fd, rfds)) { - FD_CLR(dpy->fd[0].fd, rfds); - handle_new_client( dpy ); - } - } - - /* Otherwise, try and fill readbuffer and drain writebuffer: - */ - for (i = 0 ; i < dpy->nrFds ; i++) { - if (dpy->fd[i].fd < 0) - continue; - - /* If there aren't any event slots left, don't examine - * any more file events. This will prevent lost events. - */ - if (dpy->eventqueue.head == - ((dpy->eventqueue.tail + 1) & MINIGLX_EVENT_QUEUE_MASK)) { - fprintf(stderr, "leaving event loop as event queue is full\n"); - return retval; - } - - if (FD_ISSET(dpy->fd[i].fd, wfds)) { - int r = write(dpy->fd[i].fd, - dpy->fd[i].writebuf, - dpy->fd[i].writebuf_count); - - if (r < 1) - shut_fd(dpy,i); - else { - dpy->fd[i].writebuf_count -= r; - if (dpy->fd[i].writebuf_count) { - memmove(dpy->fd[i].writebuf, - dpy->fd[i].writebuf + r, - dpy->fd[i].writebuf_count); - } - } - } - - if (FD_ISSET(dpy->fd[i].fd, rfds)) { - int r = read(dpy->fd[i].fd, - dpy->fd[i].readbuf + dpy->fd[i].readbuf_count, - MINIGLX_BUF_SIZE - dpy->fd[i].readbuf_count); - - if (r < 1) - shut_fd(dpy,i); - else { - dpy->fd[i].readbuf_count += r; - - handle_fifo_read( dpy, i ); - } - } - } - - return retval; -} - -/** - * \brief Handle socket events. - * - * \param dpy the display handle. - * \param nonblock whether to return immediately or wait for an event. - * - * \return True on success, False on failure. Aborts on critical error. - * - * \internal - * This function is the select() main loop. - */ -int handle_fd_events( Display *dpy, int nonblock ) -{ - while (1) { - struct timeval tv = {0, 0}; - int r = __miniglx_Select( dpy, 0, 0, 0, 0, nonblock ? &tv : 0 ); - if (r >= 0) - return True; - if (errno == EINTR || errno == EAGAIN) - continue; - perror ("select()"); - exit (1); - } -} - -/** - * Initializes the connections. - * - * \param dpy the display handle. - * - * \return True on success or False on failure. - * - * Allocates and initializes the Display::fd array and create a Unix socket on - * the first entry. For a server binds the socket to a filename and listen for - * connections. For a client connects to the server and waits for a welcome - * message. Sets the socket in nonblocking mode. - */ -int __miniglx_open_connections( Display *dpy ) -{ - struct sockaddr_un sa; - int i; - - dpy->nrFds = dpy->IsClient ? 1 : MINIGLX_MAX_SERVER_FDS; - dpy->fd = calloc(1, dpy->nrFds * sizeof(struct MiniGLXConnection)); - if (!dpy->fd) - return False; - - for (i = 0 ; i < dpy->nrFds ; i++) - dpy->fd[i].fd = -1; - - if (!dpy->IsClient) { - if (unlink(MINIGLX_FIFO_NAME) != 0 && errno != ENOENT) { - perror("unlink " MINIGLX_FIFO_NAME); - return False; - } - - } - - /* Create a Unix socket -- Note this is *not* a network connection! - */ - dpy->fd[0].fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (dpy->fd[0].fd < 0) { - perror("socket " MINIGLX_FIFO_NAME); - return False; - } - - memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, MINIGLX_FIFO_NAME); - - if (dpy->IsClient) { - /* Connect to server - */ - if (connect(dpy->fd[0].fd, (struct sockaddr *)&sa, sizeof(sa)) != 0) { - perror("connect"); - shut_fd(dpy,0); - return False; - } - - /* Wait for configuration messages from the server. - */ - welcome_message( dpy, 0 ); - } - else { - mode_t tmp = umask( 0000 ); /* open to everybody ? */ - - /* Bind socket to our filename - */ - if (bind(dpy->fd[0].fd, (struct sockaddr *)&sa, sizeof(sa)) != 0) { - perror("bind"); - shut_fd(dpy,0); - return False; - } - - umask( tmp ); - - /* Listen for connections - */ - if (listen(dpy->fd[0].fd, 5) != 0) { - perror("listen"); - shut_fd(dpy,0); - return False; - } - } - - if (fcntl(dpy->fd[0].fd, F_SETFL, O_NONBLOCK) != 0) { - perror("fcntl"); - shut_fd(dpy,0); - return False; - } - - - return True; -} - - -/** - * Frees the connections initialized by __miniglx_open_connections(). - * - * \param dpy the display handle. - */ -void __miniglx_close_connections( Display *dpy ) -{ - int i; - - for (i = 0 ; i < dpy->nrFds ; i++) { - if (dpy->fd[i].fd >= 0) { - shutdown (dpy->fd[i].fd, SHUT_RDWR); - close (dpy->fd[i].fd); - } - } - - dpy->nrFds = 0; - free(dpy->fd); -} - - -/** - * Set a drawable flag. - * - * \param dpy the display handle. - * \param w drawable (window). - * \param flag flag. - * - * Sets the specified drawable flag in the SAREA and increment its stamp while - * holding the light hardware lock. - */ -static void set_drawable_flag( Display *dpy, int w, int flag ) -{ - if (dpy->driverContext.pSAREA) { - if (dpy->hwActive) - DRM_LIGHT_LOCK( dpy->driverContext.drmFD, - dpy->driverContext.pSAREA, - dpy->driverContext.serverContext ); - - dpy->driverContext.pSAREA->drawableTable[w].stamp++; - dpy->driverContext.pSAREA->drawableTable[w].flags = flag; - - if (dpy->hwActive) - DRM_UNLOCK( dpy->driverContext.drmFD, - dpy->driverContext.pSAREA, - dpy->driverContext.serverContext ); - } -} - - - -/** - * \brief Map Window. - * - * \param dpy the display handle as returned by XOpenDisplay(). - * \param w the window handle. - * - * If called by a client, sends a request for focus to the server. If - * called by the server, will generate a MapNotify and Expose event at - * the client. - * - */ -void -XMapWindow( Display *dpy, Window w ) -{ - if (dpy->IsClient) - send_char_msg( dpy, 0, _CanIHaveFocus ); - else { - set_drawable_flag( dpy, (int)w, 1 ); - send_char_msg( dpy, (int)w, _YouveGotFocus ); - send_char_msg( dpy, (int)w, _RepaintPlease ); - dpy->TheWindow = w; - } - handle_fd_events( dpy, 0 ); /* flush write queue */ -} - -/** - * \brief Unmap Window. - * - * \param dpy the display handle as returned by XOpenDisplay(). - * \param w the window handle. - * - * Called from the client: Lets the server know that the window won't - * be updated anymore. - * - * Called from the server: Tells the specified client that it no longer - * holds the focus. - */ -void -XUnmapWindow( Display *dpy, Window w ) -{ - if (dpy->IsClient) { - send_char_msg( dpy, 0, _IDontWantFocus ); - } - else { - dpy->TheWindow = 0; - set_drawable_flag( dpy, (int)w, 0 ); - send_char_msg( dpy, (int)w, _YouveLostFocus ); - } - handle_fd_events( dpy, 0 ); /* flush write queue */ -} - - -/** - * \brief Block and wait for next X event. - * - * \param dpy the display handle as returned by XOpenDisplay(). - * \param event_return a pointer to an XEvent structure for the returned data. - * - * Wait until there is a new XEvent pending. - */ -int XNextEvent(Display *dpy, XEvent *event_return) -{ - for (;;) { - if ( dpy->eventqueue.head != dpy->eventqueue.tail ) - return dequeue_event( dpy, event_return ); - - handle_fd_events( dpy, 0 ); - } -} - -/** - * \brief Non-blocking check for next X event. - * - * \param dpy the display handle as returned by XOpenDisplay(). - * \param event_mask ignored. - * \param event_return a pointer to an XEvent structure for the returned data. - * - * Check if there is a new XEvent pending. Note that event_mask is - * ignored and any pending event will be returned. - */ -Bool XCheckMaskEvent(Display *dpy, long event_mask, XEvent *event_return) -{ - if ( dpy->eventqueue.head != dpy->eventqueue.tail ) - return dequeue_event( dpy, event_return ); - - handle_fd_events( dpy, 1 ); - - return dequeue_event( dpy, event_return ); -} diff --git a/src/glx/x11/packrender.h b/src/glx/packrender.h index 30f6d44bbd..30f6d44bbd 100644 --- a/src/glx/x11/packrender.h +++ b/src/glx/packrender.h diff --git a/src/glx/x11/packsingle.h b/src/glx/packsingle.h index f33a873f3a..f33a873f3a 100644 --- a/src/glx/x11/packsingle.h +++ b/src/glx/packsingle.h diff --git a/src/glx/x11/pixel.c b/src/glx/pixel.c index d36ca31e7d..d36ca31e7d 100644 --- a/src/glx/x11/pixel.c +++ b/src/glx/pixel.c diff --git a/src/glx/x11/pixelstore.c b/src/glx/pixelstore.c index 8b51b5d8b7..8b51b5d8b7 100644 --- a/src/glx/x11/pixelstore.c +++ b/src/glx/pixelstore.c diff --git a/src/glx/x11/render2.c b/src/glx/render2.c index 762950f4ac..762950f4ac 100644 --- a/src/glx/x11/render2.c +++ b/src/glx/render2.c diff --git a/src/glx/x11/renderpix.c b/src/glx/renderpix.c index 9919bbcde3..9919bbcde3 100644 --- a/src/glx/x11/renderpix.c +++ b/src/glx/renderpix.c diff --git a/src/glx/x11/single2.c b/src/glx/single2.c index d128ba2053..9ecf589fff 100644 --- a/src/glx/x11/single2.c +++ b/src/glx/single2.c @@ -35,7 +35,8 @@ #include "glxextensions.h" #include "indirect.h" #include "indirect_vertex_array.h" -#include "dispatch.h" +#include "glapitable.h" +#include "glapidispatch.h" #include "glapi.h" #ifdef USE_XCB #include <xcb/xcb.h> diff --git a/src/glx/x11/singlepix.c b/src/glx/singlepix.c index fa12ac3bbc..f5ebf4dfdb 100644 --- a/src/glx/x11/singlepix.c +++ b/src/glx/singlepix.c @@ -30,7 +30,8 @@ #include "packsingle.h" #include "indirect.h" -#include "dispatch.h" +#include "glapitable.h" +#include "glapidispatch.h" #include "glapi.h" #include "glthread.h" #include "glapioffsets.h" diff --git a/src/glx/x11/vertarr.c b/src/glx/vertarr.c index 398cfb1e79..398cfb1e79 100644 --- a/src/glx/x11/vertarr.c +++ b/src/glx/vertarr.c diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile deleted file mode 100644 index 86d84d4b9f..0000000000 --- a/src/glx/x11/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -TOP = ../../.. -include $(TOP)/configs/current - -EXTRA_DEFINES = -DXF86VIDMODE -D_REENTRANT -UIN_DRI_DRIVER \ - -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" - -SOURCES = \ - glcontextmodes.c \ - clientattrib.c \ - compsize.c \ - eval.c \ - glxcmds.c \ - glxcurrent.c \ - glxext.c \ - glxextensions.c \ - indirect.c \ - indirect_init.c \ - indirect_size.c \ - indirect_window_pos.c \ - indirect_texture_compression.c \ - indirect_transpose_matrix.c \ - indirect_vertex_array.c \ - indirect_vertex_program.c \ - pixel.c \ - pixelstore.c \ - render2.c \ - renderpix.c \ - single2.c \ - singlepix.c \ - vertarr.c \ - xfont.c \ - glx_pbuffer.c \ - glx_query.c \ - drisw_glx.c \ - dri_common.c \ - dri_glx.c \ - XF86dri.c \ - glxhash.c \ - dri2_glx.c \ - dri2.c - -include $(TOP)/src/mesa/sources.mak - -MESA_GLAPI_ASM_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_ASM_SOURCES)) -MESA_GLAPI_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_SOURCES)) -MESA_GLAPI_OBJECTS = $(addprefix $(TOP)/src/mesa/, $(GLAPI_OBJECTS)) - -OBJECTS = $(SOURCES:.c=.o) $(MESA_GLAPI_OBJECTS) - -INCLUDES = -I. \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/glapi \ - $(LIBDRM_CFLAGS) \ - $(DRI2PROTO_CFLAGS) \ - $(X11_INCLUDES) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ - -##### TARGETS ##### - -default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) - -# Make libGL -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile - $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major 1 -minor 2 $(MKLIB_OPTIONS) \ - -install $(TOP)/$(LIB_DIR) -id $(INSTALL_LIB_DIR)/lib$(GL_LIB).1.dylib \ - $(GL_LIB_DEPS) $(OBJECTS) - - -depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \ - $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find $(TOP)/include` - -install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) - $(MAKE) -C $(TOP)/src/mesa install-libgl - -# Remove .o and backup files -clean: - -rm -f $(TOP)/$(LIB_DIR)/libGL.so* - -rm -f *.o *~ - -rm -f depend depend.bak - --include depend diff --git a/src/glx/x11/xf86dri.h b/src/glx/xf86dri.h index ba266003f7..ba266003f7 100644 --- a/src/glx/x11/xf86dri.h +++ b/src/glx/xf86dri.h diff --git a/src/glx/x11/xf86dristr.h b/src/glx/xf86dristr.h index c8fbe9d4c7..c8fbe9d4c7 100644 --- a/src/glx/x11/xf86dristr.h +++ b/src/glx/xf86dristr.h diff --git a/src/glx/x11/xfont.c b/src/glx/xfont.c index 797fd7a490..797fd7a490 100644 --- a/src/glx/x11/xfont.c +++ b/src/glx/xfont.c diff --git a/src/mesa/SConscript b/src/mesa/SConscript index bdcfffed4b..ea5bad2825 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -251,6 +251,7 @@ if env['platform'] != 'winddk': 'main/dispatch.c', 'glapi/glapi.c', 'glapi/glapi_getproc.c', + 'glapi/glapi_nop.c', 'glapi/glthread.c', ] diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 62a3269d17..85a6f03672 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -813,7 +813,7 @@ directfbgl_create_context( GLcontext *context, { struct dd_function_table functions; - _mesa_initialize_framebuffer( framebuffer, visual ); + _mesa_initialize_window_framebuffer( framebuffer, visual ); _mesa_init_driver_functions( &functions ); functions.GetString = dfbGetString; diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 0e01d74265..3649c29666 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -454,6 +454,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; + pdp->validBuffers = GL_FALSE; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 35d8b8ff93..95df702f1a 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -376,6 +376,8 @@ struct __DRIdrawableRec { * GLX_MESA_swap_control. */ unsigned int swap_interval; + + GLboolean validBuffers; }; /** diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 447f3d15b9..c152226902 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -400,7 +400,7 @@ # define READ_RGBA( rgba, _x, _y ) \ do { \ GLuint p = GET_VALUE(_x, _y); \ - *((uint32_t *) rgba) = (t << 8) | 0xff; \ + *((uint32_t *) rgba) = (p << 8) | 0xff; \ } while (0) # else # define READ_RGBA( rgba, _x, _y ) \ diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index b272eb74ea..81d026a697 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -34,7 +34,6 @@ #include "main/mtypes.h" #include "main/cpuinfo.h" #include "main/extensions.h" -#include "glapi/dispatch.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/fb/Makefile b/src/mesa/drivers/dri/fb/Makefile index cf9b3a8556..848e2041e2 100644 --- a/src/mesa/drivers/dri/fb/Makefile +++ b/src/mesa/drivers/dri/fb/Makefile @@ -5,9 +5,6 @@ include $(TOP)/configs/current LIBNAME = fb_dri.so -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif DRIVER_SOURCES = \ fb_dri.c \ diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c deleted file mode 100644 index 02e44bb8ee..0000000000 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Test egl driver for fb_dri.so - */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <linux/fb.h> - -#include "utils.h" -#include "buffers.h" -#include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/renderbuffer.h" -#include "vbo/vbo.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "tnl/tcontext.h" -#include "tnl/t_pipeline.h" -#include "drivers/common/driverfuncs.h" -#include "drirenderbuffer.h" - -#include "eglconfig.h" -#include "eglmain/context.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" - -extern void -fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis); - -/** - * fb driver-specific driver class derived from _EGLDriver - */ -typedef struct fb_driver -{ - _EGLDriver Base; /* base class/object */ - GLuint fbStuff; -} fbDriver; - -/** - * fb display-specific driver class derived from _EGLDisplay - */ -typedef struct fb_display -{ - _EGLDisplay Base; /* base class/object */ - void *pFB; -} fbDisplay; - -/** - * fb driver-specific screen class derived from _EGLScreen - */ -typedef struct fb_screen -{ - _EGLScreen Base; - char fb[NAME_MAX]; -} fbScreen; - - -/** - * fb driver-specific surface class derived from _EGLSurface - */ -typedef struct fb_surface -{ - _EGLSurface Base; /* base class/object */ - struct gl_framebuffer *mesa_framebuffer; -} fbSurface; - - -/** - * fb driver-specific context class derived from _EGLContext - */ -typedef struct fb_context -{ - _EGLContext Base; /* base class/object */ - GLcontext *glCtx; - struct { - __DRIcontext *context; - __DRIscreen *screen; - __DRIdrawable *drawable; /* drawable bound to this ctx */ - } dri; -} fbContext, *fbContextPtr; - -#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx)) - - -static EGLBoolean -fbFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) { - _EGLConfig *configs; - _EGLConfig *c; - unsigned int i, num_configs; - unsigned int depth_buffer_factor; - unsigned int back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy - * enough to add support. Basically, if a context is created with an - * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping - * will never be used. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ - }; - - uint8_t depth_bits_array[2]; - uint8_t stencil_bits_array[2]; - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; - back_buffer_factor = (have_back_buffer) ? 2 : 1; - - num_configs = depth_buffer_factor * back_buffer_factor * 2; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_RGBA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = calloc(sizeof(*configs), num_configs); - c = configs; - if (!_eglFillInConfigs(c, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return EGL_FALSE; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (i = 0, c = configs; i < num_configs; i++, c++) { - int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); - if ((stencil != 0) && (stencil != stencil_bits)) { - SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); - } - } - - for (i = 0, c = configs; i < num_configs; i++, c++) - _eglAddConfig(disp, c); - - free(configs); - - return EGL_TRUE; -} - -static EGLBoolean -fbSetupFramebuffer(fbDisplay *disp, char *fbdev) -{ - int fd; - char dev[20]; - struct fb_var_screeninfo varInfo; - struct fb_fix_screeninfo fixedInfo; - - snprintf(dev, sizeof(dev), "/dev/%s", fbdev); - - /* open the framebuffer device */ - fd = open(dev, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Error opening %s: %s\n", fbdev, strerror(errno)); - return EGL_FALSE; - } - - /* get the original variable screen info */ - if (ioctl(fd, FBIOGET_VSCREENINFO, &varInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - /* Turn off hw accels (otherwise mmap of mmio region will be - * refused) - */ - if (varInfo.accel_flags) { - varInfo.accel_flags = 0; - if (ioctl(fd, FBIOPUT_VSCREENINFO, &varInfo)) { - fprintf(stderr, "error: ioctl(FBIOPUT_VSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - } - - /* Get the fixed screen info */ - if (ioctl(fd, FBIOGET_FSCREENINFO, &fixedInfo)) { - fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - if (fixedInfo.visual == FB_VISUAL_DIRECTCOLOR) { - struct fb_cmap cmap; - unsigned short red[256], green[256], blue[256]; - int rcols = 1 << varInfo.red.length; - int gcols = 1 << varInfo.green.length; - int bcols = 1 << varInfo.blue.length; - int i; - - cmap.start = 0; - cmap.len = gcols; - cmap.red = red; - cmap.green = green; - cmap.blue = blue; - cmap.transp = NULL; - - for (i = 0; i < rcols ; i++) - red[i] = (65536/(rcols-1)) * i; - - for (i = 0; i < gcols ; i++) - green[i] = (65536/(gcols-1)) * i; - - for (i = 0; i < bcols ; i++) - blue[i] = (65536/(bcols-1)) * i; - - if (ioctl(fd, FBIOPUTCMAP, (void *) &cmap) < 0) { - fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i); - exit(1); - } - } - - /* mmap the framebuffer into our address space */ - if (!disp->pFB) - disp->pFB = (caddr_t)mmap(0, /* start */ - fixedInfo.smem_len, /* bytes */ - PROT_READ | PROT_WRITE, /* prot */ - MAP_SHARED, /* flags */ - fd, /* fd */ - 0); /* offset */ - if (disp->pFB == (caddr_t)-1) { - fprintf(stderr, "error: unable to mmap framebuffer: %s\n", - strerror(errno)); - return EGL_FALSE; - } - - return EGL_TRUE; -} - -const char *sysfs = "/sys/class/graphics"; - -static EGLBoolean -fbInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - fbDisplay *display; - fbScreen *s; - _EGLScreen *scrn; - char c; - unsigned int x, y, r; - DIR *dir; - FILE *file; - struct dirent *dirent; - char path[NAME_MAX]; - - /* Switch display structure to one with our private fields */ - display = calloc(1, sizeof(*display)); - display->Base = *disp; - _eglHashInsert(_eglGlobal.Displays, disp->Handle, display); - free(disp); - - *major = 1; - *minor = 0; - - dir = opendir(sysfs); - if (!dir) { - printf("EGL - %s framebuffer device not found.", sysfs); - return EGL_FALSE; - } - - while ((dirent = readdir(dir))) { /* assignment! */ - - if (dirent->d_name[0] != 'f') - continue; - if (dirent->d_name[1] != 'b') - continue; - - if (fbSetupFramebuffer(display, dirent->d_name) == EGL_FALSE) - continue; - - /* Create a screen */ - s = (fbScreen *) calloc(1, sizeof(fbScreen)); - if (!s) - return EGL_FALSE; - - strncpy(s->fb, dirent->d_name, NAME_MAX); - scrn = &s->Base; - _eglInitScreen(scrn); - _eglAddScreen(&display->Base, scrn); - - snprintf(path, sizeof(path), "%s/%s/modes", sysfs, s->fb); - file = fopen(path, "r"); - while (fgets(path, sizeof(path), file)) { - sscanf(path, "%c:%ux%u-%u", &c, &x, &y, &r); - _eglAddMode(scrn, x, y, r * 1000, path); - } - fclose(file); - - fbFillInConfigs(&display->Base, 32, 24, 8, 1); - - } - closedir(dir); - - drv->Initialized = EGL_TRUE; - return EGL_TRUE; -} - - -static fbDisplay * -Lookup_fbDisplay(EGLDisplay dpy) -{ - _EGLDisplay *d = _eglLookupDisplay(dpy); - return (fbDisplay *) d; -} - - -static fbScreen * -Lookup_fbScreen(EGLDisplay dpy, EGLScreenMESA screen) -{ - _EGLScreen *s = _eglLookupScreen(dpy, screen); - return (fbScreen *) s; -} - - -static fbContext * -Lookup_fbContext(EGLContext ctx) -{ - _EGLContext *c = _eglLookupContext(ctx); - return (fbContext *) c; -} - - -static fbSurface * -Lookup_fbSurface(EGLSurface surf) -{ - _EGLSurface *s = _eglLookupSurface(surf); - return (fbSurface *) s; -} - - -static EGLBoolean -fbTerminate(_EGLDriver *drv, EGLDisplay dpy) -{ - fbDisplay *display = Lookup_fbDisplay(dpy); - _eglCleanupDisplay(&display->Base); - free(display); - free(drv); - return EGL_TRUE; -} - - -static const GLubyte * -get_string(GLcontext *ctx, GLenum pname) -{ - (void) ctx; - switch (pname) { - case GL_RENDERER: - return (const GLubyte *) "Mesa dumb framebuffer"; - default: - return NULL; - } -} - - -static void -update_state( GLcontext *ctx, GLuint new_state ) -{ - /* not much to do here - pass it on */ - _swrast_InvalidateState( ctx, new_state ); - _swsetup_InvalidateState( ctx, new_state ); - _vbo_InvalidateState( ctx, new_state ); - _tnl_InvalidateState( ctx, new_state ); -} - - -/** - * Called by ctx->Driver.GetBufferSize from in core Mesa to query the - * current framebuffer size. - */ -static void -get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) -{ - *width = buffer->Width; - *height = buffer->Height; -} - - -static void -updateFramebufferSize(GLcontext *ctx) -{ - fbContextPtr fbmesa = FB_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->WinSysDrawBuffer; - if (fbmesa->dri.drawable->w != fb->Width || - fbmesa->dri.drawable->h != fb->Height) { - driUpdateFramebufferSize(ctx, fbmesa->dri.drawable); - } -} - -static void -viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - /* XXX this should be called after we acquire the DRI lock, not here */ - updateFramebufferSize(ctx); -} - - -static void -init_core_functions( struct dd_function_table *functions ) -{ - functions->GetString = get_string; - functions->UpdateState = update_state; - functions->GetBufferSize = get_buffer_size; - functions->Viewport = viewport; - - functions->Clear = _swrast_Clear; /* could accelerate with blits */ -} - - -static EGLContext -fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - GLcontext *ctx; - _EGLConfig *conf; - fbContext *c; - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct dd_function_table functions; - GLvisual vis; - int i; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - c = (fbContext *) calloc(1, sizeof(fbContext)); - if (!c) - return EGL_NO_CONTEXT; - - _eglInitContext(&c->Base); - c->Base.Display = disp; - c->Base.Config = conf; - c->Base.DrawSurface = EGL_NO_SURFACE; - c->Base.ReadSurface = EGL_NO_SURFACE; - - /* link to display */ - _eglLinkContext(&c->Base, disp); - assert(c->Base.Handle); - - /* Init default driver functions then plug in our FBdev-specific functions - */ - _mesa_init_driver_functions(&functions); - init_core_functions(&functions); - - _eglConfigToContextModesRec(conf, &vis); - - ctx = c->glCtx = _mesa_create_context(&vis, NULL, &functions, (void *)c); - if (!c->glCtx) { - _mesa_free(c); - return GL_FALSE; - } - - /* Create module contexts */ - _swrast_CreateContext( ctx ); - _vbo_CreateContext( ctx ); - _tnl_CreateContext( ctx ); - _swsetup_CreateContext( ctx ); - _swsetup_Wakeup( ctx ); - - - /* use default TCL pipeline */ - { - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->Driver.RunPipeline = _tnl_run_pipeline; - } - - _mesa_enable_sw_extensions(ctx); - - return c->Base.Handle; -} - - -static EGLSurface -fbCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) -{ - int i; - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface"); - return EGL_NO_SURFACE; - } - } - printf("eglCreateWindowSurface()\n"); - /* XXX unfinished */ - - return EGL_NO_SURFACE; -} - - -static EGLSurface -fbCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) -{ - _EGLConfig *conf; - EGLint i; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs at this time */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - } - - if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) { - _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); - return EGL_NO_SURFACE; - } - - printf("eglCreatePixmapSurface()\n"); - return EGL_NO_SURFACE; -} - - -static EGLSurface -fbCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) -{ - fbSurface *surf; - - surf = (fbSurface *) calloc(1, sizeof(fbSurface)); - if (!surf) { - return EGL_NO_SURFACE; - } - - if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list) == EGL_NO_SURFACE) { - free(surf); - return EGL_NO_SURFACE; - } - - /* create software-based pbuffer */ - { - GLcontext *ctx = NULL; /* this _should_ be OK */ - GLvisual vis; - _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); - assert(conf); /* bad config should be caught earlier */ - _eglConfigToContextModesRec(conf, &vis); - - surf->mesa_framebuffer = _mesa_create_framebuffer(&vis); - _mesa_add_soft_renderbuffers(surf->mesa_framebuffer, - GL_TRUE, /* color bufs */ - vis.haveDepthBuffer, - vis.haveStencilBuffer, - vis.haveAccumBuffer, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */ ); - - /* set pbuffer/framebuffer size */ - _mesa_resize_framebuffer(ctx, surf->mesa_framebuffer, - surf->Base.Width, surf->Base.Height); - } - - return surf->Base.Handle; -} - - -static EGLBoolean -fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) -{ - fbSurface *fs = Lookup_fbSurface(surface); - _eglUnlinkSurface(&fs->Base); - if (!_eglIsSurfaceBound(&fs->Base)) - free(fs); - return EGL_TRUE; -} - - -static EGLBoolean -fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) -{ - fbContext *fc = Lookup_fbContext(context); - _eglUnlinkContext(&fc->Base); - if (!_eglIsContextBound(&fc->Base)) - free(fc); - return EGL_TRUE; -} - - -static EGLBoolean -fbMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) -{ - fbSurface *readSurf = Lookup_fbSurface(read); - fbSurface *drawSurf = Lookup_fbSurface(draw); - fbContext *ctx = Lookup_fbContext(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - _mesa_make_current( ctx->glCtx, - drawSurf->mesa_framebuffer, - readSurf->mesa_framebuffer); - } else - _mesa_make_current( NULL, NULL, NULL ); - - return EGL_TRUE; -} - - -/** - * Create a drawing surface which can be directly displayed on a screen. - */ -static EGLSurface -fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) -{ - _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); - fbDisplay *display = Lookup_fbDisplay(dpy); - fbSurface *surface; - EGLSurface surf; - GLvisual vis; - GLcontext *ctx = NULL; /* this should be OK */ - int origin, bytesPerPixel; - int width, height, stride; - - surface = (fbSurface *) malloc(sizeof(*surface)); - if (!surface) { - return EGL_NO_SURFACE; - } - - /* init base class, error check, etc. */ - surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list); - if (surf == EGL_NO_SURFACE) { - free(surface); - return EGL_NO_SURFACE; - } - - /* convert EGLConfig to GLvisual */ - _eglConfigToContextModesRec(config, &vis); - - /* create Mesa framebuffer */ - surface->mesa_framebuffer = _mesa_create_framebuffer(&vis); - if (!surface->mesa_framebuffer) { - free(surface); - _eglUnlinkSurface(&surface->Base); - return EGL_NO_SURFACE; - } - - width = surface->Base.Width; - height = surface->Base.Height; - bytesPerPixel = vis.rgbBits / 8; - stride = width * bytesPerPixel; - origin = 0; - - /* front color renderbuffer */ - { - driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888, display->pFB, - bytesPerPixel, - origin, stride, NULL); - fbSetSpanFunctions(drb, &vis); - _mesa_add_renderbuffer(surface->mesa_framebuffer, - BUFFER_FRONT_LEFT, &drb->Base); - } - - /* back color renderbuffer */ - if (vis.doubleBufferMode) { - GLubyte *backBuf = _mesa_malloc(stride * height); - driRenderbuffer *drb = driNewRenderbuffer(MESA_FORMAT_ARGB8888, backBuf, - bytesPerPixel, - origin, stride, NULL); - fbSetSpanFunctions(drb, &vis); - _mesa_add_renderbuffer(surface->mesa_framebuffer, - BUFFER_BACK_LEFT, &drb->Base); - } - - /* other renderbuffers- software based */ - _mesa_add_soft_renderbuffers(surface->mesa_framebuffer, - GL_FALSE, /* color */ - vis.haveDepthBuffer, - vis.haveStencilBuffer, - vis.haveAccumBuffer, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */); - - _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height); - - return surf; -} - - -/** - * Show the given surface on the named screen. - * If surface is EGL_NO_SURFACE, disable the screen's output. - */ -static EGLBoolean -fbShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - fbDisplay *display = Lookup_fbDisplay(dpy); - fbScreen *scrn = Lookup_fbScreen(dpy, screen); - fbSurface *surf = Lookup_fbSurface(surface); - FILE *file; - char buffer[NAME_MAX]; - _EGLMode *mode = _eglLookupMode(dpy, m); - int bits; - - if (!_eglShowSurfaceMESA(drv, dpy, screen, surface, m)) - return EGL_FALSE; - - snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) { -err: - printf("chown all fb sysfs attrib to allow write - %s\n", buffer); - return EGL_FALSE; - } - snprintf(buffer, sizeof(buffer), "%d", (m == EGL_NO_MODE_MESA ? VESA_POWERDOWN : VESA_VSYNC_SUSPEND)); - fputs(buffer, file); - fclose(file); - - if (m == EGL_NO_MODE_MESA) - return EGL_TRUE; - - snprintf(buffer, sizeof(buffer), "%s/%s/mode", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - fputs(mode->Name, file); - fclose(file); - - snprintf(buffer, sizeof(buffer), "%s/%s/bits_per_pixel", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - bits = GET_CONFIG_ATTRIB(surf->Base.Config, EGL_BUFFER_SIZE); - snprintf(buffer, sizeof(buffer), "%d", bits); - fputs(buffer, file); - fclose(file); - - fbSetupFramebuffer(display, scrn->fb); - - snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); - - file = fopen(buffer, "r+"); - if (!file) - goto err; - - snprintf(buffer, sizeof(buffer), "%d", VESA_NO_BLANKING); - fputs(buffer, file); - fclose(file); - - return EGL_TRUE; -} - - -/* If the backbuffer is on a videocard, this is extraordinarily slow! - */ -static EGLBoolean -fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) -{ - fbContext *context = (fbContext *)_eglGetCurrentContext(); - fbSurface *fs = Lookup_fbSurface(draw); - struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - void *frontBuffer = front_renderbuffer->Data; - int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; - void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; - - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; - - if (context) { - GLcontext *ctx = context->glCtx; - - if (ctx->Visual.doubleBufferMode) { - int i; - int offset = 0; - char *tmp = _mesa_malloc(currentPitch); - - _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - - ASSERT(frontBuffer); - ASSERT(backBuffer); - - for (i = 0; i < fs->Base.Height; i++) { - _mesa_memcpy(tmp, (char *) backBuffer + offset, - currentPitch); - _mesa_memcpy((char *) frontBuffer + offset, tmp, - currentPitch); - offset += currentPitch; - } - - _mesa_free(tmp); - } - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); - return EGL_FALSE; - } - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new fbDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy) -{ - fbDriver *fb; - - fb = (fbDriver *) calloc(1, sizeof(fbDriver)); - if (!fb) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&fb->Base); - - /* then plug in our fb-specific functions */ - fb->Base.Initialize = fbInitialize; - fb->Base.Terminate = fbTerminate; - fb->Base.CreateContext = fbCreateContext; - fb->Base.MakeCurrent = fbMakeCurrent; - fb->Base.CreateWindowSurface = fbCreateWindowSurface; - fb->Base.CreatePixmapSurface = fbCreatePixmapSurface; - fb->Base.CreatePbufferSurface = fbCreatePbufferSurface; - fb->Base.DestroySurface = fbDestroySurface; - fb->Base.DestroyContext = fbDestroyContext; - fb->Base.CreateScreenSurfaceMESA = fbCreateScreenSurfaceMESA; - fb->Base.ShowSurfaceMESA = fbShowSurfaceMESA; - fb->Base.SwapBuffers = fbSwapBuffers; - - /* enable supported extensions */ - fb->Base.MESA_screen_surface = EGL_TRUE; - fb->Base.MESA_copy_context = EGL_TRUE; - - return &fb->Base; -} diff --git a/src/mesa/drivers/dri/ffb/ffb_bitmap.c b/src/mesa/drivers/dri/ffb/ffb_bitmap.c index 611afddfaf..b71a552c9d 100644 --- a/src/mesa/drivers/dri/ffb/ffb_bitmap.c +++ b/src/mesa/drivers/dri/ffb/ffb_bitmap.c @@ -30,7 +30,6 @@ #include "ffb_lock.h" #include "ffb_bitmap.h" #include "swrast/swrast.h" -#include "main/image.h" #include "main/macros.h" /* Compute ceiling of integer quotient of A divided by B: */ diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c index dfe60f36f2..aa3fa0a86c 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.c +++ b/src/mesa/drivers/dri/ffb/ffb_clear.c @@ -26,15 +26,12 @@ */ #include "main/mtypes.h" -#include "main/extensions.h" #include "main/mm.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" #include "ffb_vb.h" -#include "ffb_tris.h" #include "ffb_clear.h" #include "ffb_lock.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_dd.c b/src/mesa/drivers/dri/ffb/ffb_dd.c index cf83b91f0d..91b6d3153a 100644 --- a/src/mesa/drivers/dri/ffb/ffb_dd.c +++ b/src/mesa/drivers/dri/ffb/ffb_dd.c @@ -27,13 +27,9 @@ #include "main/mtypes.h" #include "main/mm.h" -#include "main/extensions.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" -#include "ffb_vb.h" -#include "ffb_tris.h" #include "ffb_clear.h" #include "ffb_lock.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_depth.c b/src/mesa/drivers/dri/ffb/ffb_depth.c index 5d509ff696..d19385b776 100644 --- a/src/mesa/drivers/dri/ffb/ffb_depth.c +++ b/src/mesa/drivers/dri/ffb/ffb_depth.c @@ -26,7 +26,6 @@ */ #include "main/mtypes.h" -#include "swrast/swrast.h" #include "ffb_dd.h" #include "ffb_span.h" #include "ffb_context.h" diff --git a/src/mesa/drivers/dri/ffb/ffb_lines.c b/src/mesa/drivers/dri/ffb/ffb_lines.c index 19dff50935..6dca4edd29 100644 --- a/src/mesa/drivers/dri/ffb/ffb_lines.c +++ b/src/mesa/drivers/dri/ffb/ffb_lines.c @@ -27,15 +27,11 @@ #include "main/mtypes.h" #include "main/mm.h" -#include "main/extensions.h" #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" #include "ffb_vb.h" #include "ffb_lines.h" -#include "ffb_tris.h" -#include "ffb_lock.h" #undef FFB_LINE_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_points.c b/src/mesa/drivers/dri/ffb/ffb_points.c index 9c37a47aeb..5bf4f8f070 100644 --- a/src/mesa/drivers/dri/ffb/ffb_points.c +++ b/src/mesa/drivers/dri/ffb/ffb_points.c @@ -30,8 +30,6 @@ #include "ffb_context.h" #include "ffb_vb.h" #include "ffb_points.h" -#include "ffb_tris.h" -#include "ffb_lock.h" #undef FFB_POINT_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_span.c b/src/mesa/drivers/dri/ffb/ffb_span.c index 8ec33a11bc..61901cccad 100644 --- a/src/mesa/drivers/dri/ffb/ffb_span.c +++ b/src/mesa/drivers/dri/ffb/ffb_span.c @@ -31,8 +31,6 @@ #include "ffb_context.h" #include "ffb_lock.h" -#include "swrast/swrast.h" - #define DBG 0 #define HW_LOCK() \ diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index 6f8a46d1fc..c09d2fef83 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -27,8 +27,6 @@ #include "main/mtypes.h" #include "main/colormac.h" -#include "main/mm.h" -#include "main/extensions.h" #include "main/enums.h" #include "vbo/vbo.h" @@ -39,12 +37,9 @@ #include "ffb_dd.h" #include "ffb_span.h" -#include "ffb_depth.h" #include "ffb_context.h" -#include "ffb_vb.h" #include "ffb_tris.h" #include "ffb_state.h" -#include "ffb_lock.h" #undef STATE_TRACE diff --git a/src/mesa/drivers/dri/ffb/ffb_stencil.c b/src/mesa/drivers/dri/ffb/ffb_stencil.c index ce8ef43c91..10cdfbc616 100644 --- a/src/mesa/drivers/dri/ffb/ffb_stencil.c +++ b/src/mesa/drivers/dri/ffb/ffb_stencil.c @@ -32,8 +32,6 @@ #include "ffb_stencil.h" #include "ffb_lock.h" -#include "swrast/swrast.h" - #undef STENCIL_TRACE static void FFBWriteStencilSpan( GLcontext *ctx, diff --git a/src/mesa/drivers/dri/ffb/ffb_vb.c b/src/mesa/drivers/dri/ffb/ffb_vb.c index f9c6fd1f31..ca8ffb2721 100644 --- a/src/mesa/drivers/dri/ffb/ffb_vb.c +++ b/src/mesa/drivers/dri/ffb/ffb_vb.c @@ -30,8 +30,6 @@ #include "ffb_vb.h" #include "main/imports.h" #include "tnl/t_context.h" -#include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #undef VB_DEBUG diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 88285f454e..6a84651479 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -28,7 +28,6 @@ #include "ffb_xmesa.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/matrix.h" #include "main/renderbuffer.h" #include "main/simple_list.h" #include "main/imports.h" @@ -52,7 +51,6 @@ #include "ffb_lines.h" #include "ffb_points.h" #include "ffb_state.h" -#include "ffb_tex.h" #include "ffb_lock.h" #include "ffb_vtxfmt.h" #include "ffb_bitmap.h" diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index bd9cfe5c0f..34e34606b4 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -34,10 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "main/context.h" -#include "main/matrix.h" #include "main/simple_list.h" -#include "main/extensions.h" -#include "main/framebuffer.h" #include "main/imports.h" #include "main/points.h" diff --git a/src/mesa/drivers/dri/i810/i810render.c b/src/mesa/drivers/dri/i810/i810render.c index 1d98e00688..b543d4f012 100644 --- a/src/mesa/drivers/dri/i810/i810render.c +++ b/src/mesa/drivers/dri/i810/i810render.c @@ -44,7 +44,6 @@ #include "i810context.h" #include "i810tris.h" -#include "i810state.h" #include "i810vb.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index 2a30782afd..476c801358 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -36,8 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/fbobject.h" -#include "main/matrix.h" #include "main/renderbuffer.h" #include "main/simple_list.h" #include "utils.h" @@ -48,8 +46,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i810state.h" #include "i810tex.h" #include "i810span.h" -#include "i810tris.h" -#include "i810ioctl.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 642245c61c..0c68e120b0 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -20,8 +20,6 @@ #include "i810context.h" #include "i810state.h" #include "i810tex.h" -#include "i810vb.h" -#include "i810tris.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810tex.c b/src/mesa/drivers/dri/i810/i810tex.c index e764644a6c..2ccb9562e9 100644 --- a/src/mesa/drivers/dri/i810/i810tex.c +++ b/src/mesa/drivers/dri/i810/i810tex.c @@ -33,7 +33,6 @@ #include "main/colormac.h" #include "main/texobj.h" #include "main/mm.h" -#include "swrast/swrast.h" #include "texmem.h" @@ -42,7 +41,6 @@ #include "i810context.h" #include "i810tex.h" -#include "i810state.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810texmem.c b/src/mesa/drivers/dri/i810/i810texmem.c index d93afbf9ef..bb426a4112 100644 --- a/src/mesa/drivers/dri/i810/i810texmem.c +++ b/src/mesa/drivers/dri/i810/i810texmem.c @@ -35,7 +35,6 @@ #include "i810_dri.h" #include "i810context.h" #include "i810tex.h" -#include "i810state.h" #include "i810ioctl.h" diff --git a/src/mesa/drivers/dri/i810/i810vb.c b/src/mesa/drivers/dri/i810/i810vb.c index 30890dc9b7..09a772258c 100644 --- a/src/mesa/drivers/dri/i810/i810vb.c +++ b/src/mesa/drivers/dri/i810/i810vb.c @@ -38,7 +38,6 @@ #include "i810context.h" #include "i810vb.h" #include "i810ioctl.h" -#include "i810tris.h" #include "i810state.h" diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index cf32476f40..dc15ae425c 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -8,7 +8,6 @@ MINIGLX_SOURCES = server/intel_dri.c DRIVER_SOURCES = \ i830_context.c \ - i830_metaops.c \ i830_state.c \ i830_texblend.c \ i830_texstate.c \ @@ -40,7 +39,6 @@ DRIVER_SOURCES = \ i915_debug.c \ i915_debug_fp.c \ i915_fragprog.c \ - i915_metaops.c \ i915_program.c \ i915_state.c \ i915_vtbl.c \ diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 4cb6305988..ebe8b15ca7 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -28,14 +28,11 @@ #include "i830_context.h" #include "main/imports.h" #include "texmem.h" -#include "intel_tex.h" #include "tnl/tnl.h" #include "tnl/t_vertex.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "utils.h" #include "intel_span.h" -#include "intel_pixel.h" #include "intel_tris.h" /*************************************** @@ -108,7 +105,6 @@ i830CreateContext(const __GLcontextModes * mesaVis, intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; i830InitState(i830); - i830InitMetaFuncs(i830); _tnl_allow_vertex_fog(ctx, 1); _tnl_allow_pixel_fog(ctx, 0); diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h index 592ae53976..b755d48678 100644 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -144,7 +144,7 @@ struct i830_context GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; DECLARE_RENDERINPUTS(last_index_bitset); - struct i830_hw_state meta, initial, state, *current; + struct i830_hw_state state; }; @@ -206,10 +206,6 @@ extern void i830EmitState(struct i830_context *i830); extern void i830InitState(struct i830_context *i830); extern void i830_update_provoking_vertex(GLcontext *ctx); -/* i830_metaops.c - */ -extern void i830InitMetaFuncs(struct i830_context *i830); - /*====================================================================== * Inline conversion functions. These are better-typed than the * macros used previously: diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c deleted file mode 100644 index 2cce661c86..0000000000 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ /dev/null @@ -1,456 +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/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_regions.h" - -#include "i830_context.h" -#include "i830_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I830_UPLOAD_INVARIENT | \ - I830_UPLOAD_CTX | \ - I830_UPLOAD_BUFFERS | \ - I830_UPLOAD_STIPPLE | \ - I830_UPLOAD_TEXBLEND(0) | \ - I830_UPLOAD_TEX(0)) - - -#define SET_STATE( i830, STATE ) \ -do { \ - i830->current->emitted &= ~ACTIVE; \ - i830->current = &i830->STATE; \ - i830->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -set_no_stencil_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -static void -set_no_depth_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Set depth unit to replace. - */ -static void -set_depth_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC - (COMPAREFUNC_ALWAYS)); - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -set_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK((s_mask & - 0xff))); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE((s_clear & 0xff)) | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); - - - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -set_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | - (1 << WRITEMASK_GREEN_SHIFT) | - (1 << WRITEMASK_BLUE_SHIFT) | - (1 << WRITEMASK_ALPHA_SHIFT)); - - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; - - if (state) { - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= - (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); - } - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Installs a one-stage passthrough texture blend pipeline. Is there - * more that can be done to turn off texturing? - */ -static void -set_no_texture(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_NONE, GL_NONE, - {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, - {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, - 0, 0, 0, 0 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); -} - -/* Set up a single element blend stage for 'replace' texturing with no - * funny ops. - */ -static void -set_texture_blend_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_REPLACE, GL_REPLACE, - {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, - GL_TEXTURE,}, - {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, - GL_SRC_ALPHA}, - 0, 0, 1, 1 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); - -/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ -/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ -} - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -set_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint *setup = i830->meta.Tex[0]; - GLint numLevels = 1; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - i830->meta.tex_buffer[0] = buffer; - i830->meta.tex_offset[0] = offset; - - setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((pitch - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - setup[I830_TEXREG_TM0S2] = - (((((pitch * cpp) / 4) - - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); - - setup[I830_TEXREG_TM0S3] = - ((((numLevels - - 1) * - 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << - TM0S3_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << - TM0S3_MAG_FILTER_SHIFT)); - - setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); - - setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_IN_TEXELUNITS | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - i830->meta.emitted &= ~I830_UPLOAD_TEX(0); - return GL_TRUE; -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | - VFT0_TEX_COUNT(1) | - VFT0_DIFFUSE | VFT0_XYZ); - i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | - VFT1_TEX0_FMT(TEXCOORDFMT_2D) | - VFT1_TEX1_FMT(TEXCOORDFMT_2D) | - VFT1_TEX2_FMT(TEXCOORDFMT_2D) | - VFT1_TEX3_FMT(TEXCOORDFMT_2D)); - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; - i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; - i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; - i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; - i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; - i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; - i830->meta.Ctx[I830_CTXREG_STENCILTST] = - i830->state.Ctx[I830_CTXREG_STENCILTST]; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] = - i830->state.Ctx[I830_CTXREG_ENABLES_1]; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] = - i830->state.Ctx[I830_CTXREG_ENABLES_2]; - i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; - i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = - i830->state.Ctx[I830_CTXREG_FOGCOLOR]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; - i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; - i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; - - - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - i830->meta.emitted &= ~I830_UPLOAD_CTX; - - - i830->meta.Buffer[I830_DESTREG_SENABLE] = - i830->state.Buffer[I830_DESTREG_SENABLE]; - i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; - i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - - - -/* Select between front and back draw buffers. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830_state_draw_region(intel, &i830->meta, color_region, depth_region); -} - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); - - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; - - SET_STATE(i830, meta); - set_vertex_format(intel); - set_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); -/* intel_region_release(intel, &i830->meta.tex_region[0]); */ - SET_STATE(i830, state); -} - - - -void -i830InitMetaFuncs(struct i830_context *i830) -{ - i830->intel.vtbl.install_meta_state = install_meta_state; - i830->intel.vtbl.leave_meta_state = leave_meta_state; - i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; - i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; - i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; - i830->intel.vtbl.meta_depth_replace = set_depth_replace; - i830->intel.vtbl.meta_color_mask = set_color_mask; - i830->intel.vtbl.meta_no_texture = set_no_texture; - i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; - i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; - i830->intel.vtbl.meta_draw_region = meta_draw_region; - i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index acda7e70de..3b9b3ae329 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -1127,9 +1127,6 @@ i830InitState(struct i830_context *i830) _mesa_init_driver_state(ctx); - memcpy(&i830->initial, &i830->state, sizeof(i830->state)); - - i830->current = &i830->state; i830->state.emitted = 0; i830->state.active = (I830_UPLOAD_INVARIENT | I830_UPLOAD_RASTER_RULES | diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 4471ca2bbb..a8df77c600 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -25,8 +25,6 @@ * **************************************************************************/ -#include "glapi/glapi.h" - #include "i830_context.h" #include "i830_reg.h" #include "intel_batchbuffer.h" @@ -237,8 +235,8 @@ static GLboolean i830_check_vertex_size(struct intel_context *intel, GLuint expected) { struct i830_context *i830 = i830_context(&intel->ctx); - int vft0 = i830->current->Ctx[I830_CTXREG_VF]; - int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; + int vft0 = i830->state.Ctx[I830_CTXREG_VF]; + int vft1 = i830->state.Ctx[I830_CTXREG_VF2]; int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; int i, sz = 0; @@ -414,7 +412,7 @@ static void i830_emit_state(struct intel_context *intel) { struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; + struct i830_hw_state *state = &i830->state; int i, count; GLuint dirty; dri_bo *aper_array[3 + I830_TEX_UNITS]; @@ -543,10 +541,6 @@ i830_emit_state(struct intel_context *intel) I915_GEM_DOMAIN_SAMPLER, 0, state->tex_offset[i]); } - else if (state == &i830->meta) { - assert(i == 0); - OUT_BATCH(0); - } else { OUT_BATCH(state->tex_offset[i]); } @@ -581,10 +575,6 @@ i830_destroy_context(struct intel_context *intel) intel_region_release(&i830->state.draw_region); intel_region_release(&i830->state.depth_region); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); - intel_region_release(&i830->initial.draw_region); - intel_region_release(&i830->initial.depth_region); for (i = 0; i < I830_TEX_UNITS; i++) { if (i830->state.tex_buffer[i] != NULL) { @@ -596,24 +586,22 @@ i830_destroy_context(struct intel_context *intel) _tnl_free_vertices(&intel->ctx); } - -void -i830_state_draw_region(struct intel_context *intel, - struct i830_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) +static void +i830_set_draw_region(struct intel_context *intel, + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i830_context *i830 = i830_context(&intel->ctx); GLcontext *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); GLuint value; + struct i830_hw_state *state = &i830->state; - ASSERT(state == &i830->state || state == &i830->meta); - - if (state->draw_region != color_region) { + if (state->draw_region != color_regions[0]) { intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); + intel_region_reference(&state->draw_region, color_regions[0]); } if (state->depth_region != depth_region) { intel_region_release(&state->depth_region); @@ -624,7 +612,7 @@ i830_state_draw_region(struct intel_context *intel, * Set stride/cpp values */ i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_CBUFADDR0], - color_region, BUF_3D_ID_COLOR_BACK); + color_regions[0], BUF_3D_ID_COLOR_BACK); i915_set_buf_info_for_region(&state->Buffer[I830_DESTREG_DBUFADDR0], depth_region, BUF_3D_ID_DEPTH); @@ -674,19 +662,6 @@ i830_state_draw_region(struct intel_context *intel, state->Buffer[I830_DESTREG_DRAWRECT5] = 0; I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - - -} - - -static void -i830_set_draw_region(struct intel_context *intel, - struct intel_region *color_regions[], - struct intel_region *depth_region, - GLuint num_regions) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830_state_draw_region(intel, &i830->state, color_regions[0], depth_region); } /* This isn't really handled at the moment. @@ -702,8 +677,7 @@ static void i830_assert_not_dirty( struct intel_context *intel ) { struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; - assert(!get_dirty(state)); + assert(!get_dirty(&i830->state)); } static void diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 7c7711da09..ed9a44ff24 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -28,7 +28,6 @@ #include "i915_context.h" #include "main/imports.h" #include "main/macros.h" -#include "intel_tex.h" #include "intel_tris.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -38,15 +37,11 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "utils.h" #include "i915_reg.h" #include "i915_program.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" #include "intel_tris.h" #include "intel_span.h" -#include "intel_pixel.h" /*************************************** * Mesa's Driver Functions @@ -116,7 +111,6 @@ i915CreateContext(const __GLcontextModes * mesaVis, _mesa_printf("\ntexmem-0-3 branch\n\n"); i915InitVtbl(i915); - i915InitMetaFuncs(i915); i915InitDriverFunctions(&functions); diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index f55b551139..60b357ec28 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -259,7 +259,7 @@ struct i915_context struct i915_fragment_program *current_program; - struct i915_hw_state meta, initial, state, *current; + struct i915_hw_state state; }; @@ -346,12 +346,6 @@ extern void i915UpdateTextureState(struct intel_context *intel); extern void i915InitTextureFuncs(struct dd_function_table *functions); /*====================================================================== - * i915_metaops.c - */ -void i915InitMetaFuncs(struct i915_context *i915); - - -/*====================================================================== * i915_fragprog.c */ extern void i915ValidateFragmentProgram(struct i915_context *i915); diff --git a/src/mesa/drivers/dri/i915/i915_debug_fp.c b/src/mesa/drivers/dri/i915/i915_debug_fp.c index 84347a01ef..bf500e54fa 100644 --- a/src/mesa/drivers/dri/i915/i915_debug_fp.c +++ b/src/mesa/drivers/dri/i915/i915_debug_fp.c @@ -30,9 +30,6 @@ #include "i915_reg.h" #include "i915_debug.h" #include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_print.h" #define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index a273bd28ea..15e3b87097 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -1205,7 +1205,7 @@ i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) return GL_TRUE; } -static void +static GLboolean i915ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { @@ -1223,7 +1223,10 @@ i915ProgramStringNotify(GLcontext * ctx, } } - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } void diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c deleted file mode 100644 index 90a78c6082..0000000000 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ /dev/null @@ -1,507 +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/enums.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_regions.h" - -#include "i915_context.h" -#include "i915_reg.h" - -/* We touch almost everything: - */ -#define ACTIVE (I915_UPLOAD_INVARIENT | \ - I915_UPLOAD_CTX | \ - I915_UPLOAD_BUFFERS | \ - I915_UPLOAD_STIPPLE | \ - I915_UPLOAD_PROGRAM | \ - I915_UPLOAD_FOG | \ - I915_UPLOAD_TEX(0)) - -#define SET_STATE( i915, STATE ) \ -do { \ - i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ - i915->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -meta_no_stencil_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_no_depth_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_depth_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->meta.Ctx[I915_CTXREG_LIS6] |= - COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -meta_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint op = STENCILOP_REPLACE; - GLuint func = COMPAREFUNC_ALWAYS; - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(s_mask)); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); - - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | - (func << S5_STENCIL_TEST_FUNC_SHIFT)); - - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -static void -meta_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - const GLuint mask = (S5_WRITEDISABLE_RED | - S5_WRITEDISABLE_GREEN | - S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); - - /* Copy colormask state from "regular" hw context. - */ - if (state) { - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; - i915->meta.Ctx[I915_CTXREG_LIS5] |= - (i915->state.Ctx[I915_CTXREG_LIS5] & mask); - } - else - i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); - - i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; - i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; - i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; - i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; - i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; - - i915->meta.Buffer[I915_DESTREG_SENABLE] = - i915->state.Buffer[I915_DESTREG_SENABLE]; - i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; - i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; - - i915->meta.emitted &= ~I915_UPLOAD_FOG; - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - - -#define REG( type, nr ) (((type)<<5)|(nr)) - -#define REG_R(x) REG(REG_TYPE_R, x) -#define REG_T(x) REG(REG_TYPE_T, x) -#define REG_CONST(x) REG(REG_TYPE_CONST, x) -#define REG_S(x) REG(REG_TYPE_S, x) -#define REG_OC REG(REG_TYPE_OC, 0) -#define REG_OD REG(REG_TYPE_OD, 0) -#define REG_U(x) REG(REG_TYPE_U, x) - -#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) -#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) -#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) -#define REG_T_TEX(x) REG(REG_TYPE_T, x) - - -#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) -#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) -#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) -#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) -#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) -#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) -#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) - -#define T0_SAMPLER( unit ) ((unit)<<T0_SAMPLER_NR_SHIFT) - -#define T1_ADDRESS_REG( type, nr ) (((type)<<T1_ADDRESS_REG_TYPE_SHIFT)| \ - ((nr)<<T1_ADDRESS_REG_NR_SHIFT)) - - -#define A1_SRC0_XYZW ((SRC_X << A1_SRC0_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC0_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A1_SRC0_CHANNEL_Z_SHIFT) | \ - (SRC_W << A1_SRC0_CHANNEL_W_SHIFT)) - -#define A1_SRC1_XY ((SRC_X << A1_SRC1_CHANNEL_X_SHIFT) | \ - (SRC_Y << A1_SRC1_CHANNEL_Y_SHIFT)) - -#define A2_SRC1_ZW ((SRC_Z << A2_SRC1_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC1_CHANNEL_W_SHIFT)) - -#define A2_SRC2_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) - - - - - -static void -meta_no_texture(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare incoming diffuse color: - */ - (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = mov(t_diffuse) - */ - (A0_MOV | - A0_DEST_REG(REG_OC) | - A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), - (A1_SRC0_XYZW), - 0, - }; - - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - -static void -meta_texture_blend_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare the sampler: - */ - (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), - D1_MBZ, - D2_MBZ, - - /* Declare the interpolated texture coordinate: - */ - (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = texld(sample0, texcoord0) - */ - (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), - T1_ADDRESS_REG(REG_TYPE_T, 0), - T2_MBZ - }; - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -meta_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint unit = 0; - GLint numLevels = 1; - GLuint *state = i915->meta.Tex[0]; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - - if ((pitch * cpp) & 3) { - _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); - return GL_FALSE; - } - -/* intel_region_release(&i915->meta.tex_region[0]); */ -/* intel_region_reference(&i915->meta.tex_region[0], region); */ - i915->meta.tex_buffer[0] = buffer; - i915->meta.tex_offset[0] = offset; - - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((pitch - 1) << MS3_WIDTH_SHIFT) | - textureFormat | MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); - - state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); - - state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); - - state[I915_TEXREG_SS4] = 0; - - i915->meta.emitted &= ~I915_UPLOAD_TEX(0); - return GL_TRUE; -} - - -/** - * Set the color and depth drawing region for meta ops. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->meta, color_region, depth_region); -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915->meta.Ctx[I915_CTXREG_LIS2] = - (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | - S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); - - i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; - - i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; - - SET_STATE(i915, meta); - set_vertex_format(intel); - meta_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); -/* intel_region_release(&i915->meta.tex_region[0]); */ - SET_STATE(i915, state); -} - - - -void -i915InitMetaFuncs(struct i915_context *i915) -{ - i915->intel.vtbl.install_meta_state = install_meta_state; - i915->intel.vtbl.leave_meta_state = leave_meta_state; - i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; - i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; - i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; - i915->intel.vtbl.meta_depth_replace = meta_depth_replace; - i915->intel.vtbl.meta_color_mask = meta_color_mask; - i915->intel.vtbl.meta_no_texture = meta_no_texture; - i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; - i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; - i915->intel.vtbl.meta_draw_region = meta_draw_region; - i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 9d7a9e1dfe..7275617a6f 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -1157,7 +1157,4 @@ i915InitState(struct i915_context *i915) i915_init_packets(i915); _mesa_init_driver_state(ctx); - - memcpy(&i915->initial, &i915->state, sizeof(i915->state)); - i915->current = &i915->state; } diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 266e6848c3..392126b7dc 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -37,17 +37,13 @@ #include "tnl/t_vertex.h" #include "intel_batchbuffer.h" -#include "intel_tex.h" #include "intel_regions.h" #include "intel_tris.h" #include "intel_fbo.h" -#include "intel_chipset.h" #include "i915_reg.h" #include "i915_context.h" -#include "glapi/glapi.h" - static void i915_render_prevalidate(struct intel_context *intel) { @@ -100,8 +96,8 @@ static GLboolean i915_check_vertex_size(struct intel_context *intel, GLuint expected) { struct i915_context *i915 = i915_context(&intel->ctx); - int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; - int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int lis2 = i915->state.Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4]; int i, sz = 0; switch (lis4 & S4_VFMT_XYZW_MASK) { @@ -287,7 +283,7 @@ static void i915_emit_state(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; + struct i915_hw_state *state = &i915->state; int i, count, aper_count; GLuint dirty; dri_bo *aper_array[3 + I915_TEX_UNITS]; @@ -443,10 +439,6 @@ i915_emit_state(struct intel_context *intel) I915_GEM_DOMAIN_SAMPLER, 0, state->tex_offset[i]); } - else if (state == &i915->meta) { - assert(i == 0); - OUT_BATCH(0); - } else { OUT_BATCH(state->tex_offset[i]); } @@ -500,10 +492,6 @@ i915_destroy_context(struct intel_context *intel) intel_region_release(&i915->state.draw_region); intel_region_release(&i915->state.depth_region); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); - intel_region_release(&i915->initial.draw_region); - intel_region_release(&i915->initial.depth_region); for (i = 0; i < I915_TEX_UNITS; i++) { if (i915->state.tex_buffer[i] != NULL) { @@ -533,29 +521,22 @@ i915_set_buf_info_for_region(uint32_t *state, struct intel_region *region, } } -/** - * Set the drawing regions for the color and depth/stencil buffers. - * This involves setting the pitch, cpp and buffer ID/location. - * Also set pixel format for color and Z rendering - * Used for setting both regular and meta state. - */ -void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) +static void +i915_set_draw_region(struct intel_context *intel, + struct intel_region *color_regions[], + struct intel_region *depth_region, + GLuint num_regions) { struct i915_context *i915 = i915_context(&intel->ctx); GLcontext *ctx = &intel->ctx; struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; struct intel_renderbuffer *irb = intel_renderbuffer(rb); GLuint value; + struct i915_hw_state *state = &i915->state; - ASSERT(state == &i915->state || state == &i915->meta); - - if (state->draw_region != color_region) { + if (state->draw_region != color_regions[0]) { intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); + intel_region_reference(&state->draw_region, color_regions[0]); } if (state->depth_region != depth_region) { intel_region_release(&state->depth_region); @@ -566,7 +547,7 @@ i915_state_draw_region(struct intel_context *intel, * Set stride/cpp values */ i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_CBUFADDR0], - color_region, BUF_3D_ID_COLOR_BACK); + color_regions[0], BUF_3D_ID_COLOR_BACK); i915_set_buf_info_for_region(&state->Buffer[I915_DESTREG_DBUFADDR0], depth_region, BUF_3D_ID_DEPTH); @@ -627,17 +608,6 @@ i915_state_draw_region(struct intel_context *intel, } -static void -i915_set_draw_region(struct intel_context *intel, - struct intel_region *color_regions[], - struct intel_region *depth_region, - GLuint num_regions) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->state, color_regions[0], depth_region); -} - - static void i915_new_batch(struct intel_context *intel) @@ -655,8 +625,7 @@ static void i915_assert_not_dirty( struct intel_context *intel ) { struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; - GLuint dirty = get_dirty(state); + GLuint dirty = get_dirty(&i915->state); assert(!dirty); } diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index e99baf8e0e..6d498c5654 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -52,8 +52,6 @@ #include "intel_buffers.h" #include "intel_reg.h" #include "intel_span.h" -#include "intel_tex.h" -#include "intel_chipset.h" #include "i830_context.h" #include "i830_reg.h" diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c index bac1c3a49c..fa2d394b22 100644 --- a/src/mesa/drivers/dri/i965/brw_cc.c +++ b/src/mesa/drivers/dri/i965/brw_cc.c @@ -34,9 +34,7 @@ #include "brw_state.h" #include "brw_defines.h" #include "brw_util.h" -#include "intel_fbo.h" #include "main/macros.h" -#include "main/enums.h" static void prepare_cc_vp( struct brw_context *brw ) { @@ -295,8 +293,7 @@ cc_unit_create_from_key(struct brw_context *brw, struct brw_cc_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_CC_UNIT, key, sizeof(*key), &brw->cc.vp_bo, 1, - &cc, sizeof(cc), - NULL, NULL); + &cc, sizeof(cc)); /* Emit CC viewport relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index af1d975de9..d3275c7a89 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -130,13 +130,14 @@ static void compile_clip_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->clip.prog_bo); - brw->clip.prog_bo = brw_upload_cache( &brw->cache, - BRW_CLIP_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->clip.prog_data ); + brw->clip.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, + BRW_CLIP_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->clip.prog_data); } /* Calculate interpolants for triangle and line rasterization. diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index afc0b11049..ceb62a3116 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c index 8458f61c5a..7f47634dca 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_point.c +++ b/src/mesa/drivers/dri/i965/brw_clip_point.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index c8f24a94e4..424c9a1f19 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -32,7 +32,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "main/macros.h" struct brw_clip_unit_key { unsigned int total_grf; @@ -143,8 +142,7 @@ clip_unit_create_from_key(struct brw_context *brw, bo = brw_upload_cache(&brw->cache, BRW_CLIP_UNIT, key, sizeof(*key), &brw->clip.prog_bo, 1, - &clip, sizeof(clip), - NULL, NULL); + &clip, sizeof(clip)); /* Emit clip program relocation */ assert(brw->clip.prog_bo); diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index cfbb8f2686..815211acc2 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" static void release_tmps( struct brw_clip_compile *c ) diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index ad1bfa435f..f36d22fdbf 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -39,7 +39,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index 86fed59fa4..14bc889b0f 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -40,7 +40,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 7bb15956b5..65f51be341 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -33,7 +33,6 @@ #include "main/imports.h" #include "main/api_noop.h" #include "main/macros.h" -#include "main/vtxfmt.h" #include "main/simple_list.h" #include "shader/shader_api.h" @@ -41,16 +40,9 @@ #include "brw_defines.h" #include "brw_draw.h" #include "brw_state.h" -#include "brw_vs.h" -#include "intel_tex.h" -#include "intel_blit.h" -#include "intel_batchbuffer.h" -#include "intel_pixel.h" #include "intel_span.h" #include "tnl/t_pipeline.h" -#include "utils.h" - /*************************************** * Mesa's Driver Functions diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 0dd3087143..21c4cd38a7 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -131,7 +131,6 @@ struct brw_context; #define BRW_NEW_WM_INPUT_DIMENSIONS 0x100 #define BRW_NEW_PSP 0x800 #define BRW_NEW_WM_SURFACES 0x1000 -#define BRW_NEW_FENCE 0x2000 #define BRW_NEW_INDICES 0x4000 #define BRW_NEW_VERTICES 0x8000 /** @@ -332,7 +331,6 @@ struct brw_cache { struct brw_cache_item **items; GLuint size, n_items; - GLuint aux_size[BRW_MAX_CACHE]; char *name[BRW_MAX_CACHE]; /* Record of the last BOs chosen for each cache_id. Used to set @@ -574,15 +572,11 @@ struct brw_context GLfloat *last_buf; GLuint last_bufsz; - /** - * Whether we should create a new bo instead of reusing the old one - * (if we just dispatch the batch pointing at the old one. - */ - GLboolean need_new_bo; } curbe; struct { struct brw_vs_prog_data *prog_data; + int8_t *constant_map; /* variable array following prog_data */ dri_bo *prog_bo; dri_bo *state_bo; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 190310afbb..6cb8edb611 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -179,6 +179,7 @@ static GLfloat fixed_plane[6][4] = { */ static void prepare_constant_buffer(struct brw_context *brw) { + struct intel_context *intel = &brw->intel; GLcontext *ctx = &brw->intel.ctx; const struct brw_vertex_program *vp = brw_vertex_program_const(brw->vertex_program); @@ -256,13 +257,24 @@ static void prepare_constant_buffer(struct brw_context *brw) */ _mesa_load_state_parameters(ctx, vp->program.Base.Parameters); - /* XXX just use a memcpy here */ - for (i = 0; i < nr; i++) { - const GLfloat *value = vp->program.Base.Parameters->ParameterValues[i]; - buf[offset + i * 4 + 0] = value[0]; - buf[offset + i * 4 + 1] = value[1]; - buf[offset + i * 4 + 2] = value[2]; - buf[offset + i * 4 + 3] = value[3]; + if (vp->use_const_buffer) { + /* Load the subset of push constants that will get used when + * we also have a pull constant buffer. + */ + for (i = 0; i < vp->program.Base.Parameters->NumParameters; i++) { + if (brw->vs.constant_map[i] != -1) { + assert(brw->vs.constant_map[i] <= nr); + memcpy(buf + offset + brw->vs.constant_map[i] * 4, + vp->program.Base.Parameters->ParameterValues[i], + 4 * sizeof(float)); + } + } + } else { + for (i = 0; i < nr; i++) { + memcpy(buf + offset + i * 4, + vp->program.Base.Parameters->ParameterValues[i], + 4 * sizeof(float)); + } } } @@ -293,9 +305,9 @@ static void prepare_constant_buffer(struct brw_context *brw) brw->curbe.last_bufsz = bufsz; if (brw->curbe.curbe_bo != NULL && - (brw->curbe.need_new_bo || - brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size)) + brw->curbe.curbe_next_offset + bufsz > brw->curbe.curbe_bo->size) { + intel_bo_unmap_gtt_preferred(intel, brw->curbe.curbe_bo); dri_bo_unreference(brw->curbe.curbe_bo); brw->curbe.curbe_bo = NULL; } @@ -307,6 +319,7 @@ static void prepare_constant_buffer(struct brw_context *brw) brw->curbe.curbe_bo = dri_bo_alloc(brw->intel.bufmgr, "CURBE", 4096, 1 << 6); brw->curbe.curbe_next_offset = 0; + intel_bo_map_gtt_preferred(intel, brw->curbe.curbe_bo, GL_TRUE); } brw->curbe.curbe_offset = brw->curbe.curbe_next_offset; @@ -315,7 +328,9 @@ static void prepare_constant_buffer(struct brw_context *brw) /* Copy data to the buffer: */ - dri_bo_subdata(brw->curbe.curbe_bo, brw->curbe.curbe_offset, bufsz, buf); + memcpy(brw->curbe.curbe_bo->virtual + brw->curbe.curbe_offset, + buf, + bufsz); } brw_add_validated_bo(brw, brw->curbe.curbe_bo); diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index df281b27d5..d510d767f9 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -39,10 +39,8 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_fallback.h" #include "intel_batchbuffer.h" -#include "intel_buffer_objects.h" #define FILE_DEBUG_FLAG DEBUG_BATCH diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index c773b71507..c46b9ba89c 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -29,19 +29,15 @@ #include "main/glheader.h" #include "main/bufferobj.h" #include "main/context.h" -#include "main/state.h" -#include "main/api_validate.h" #include "main/enums.h" #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_fallback.h" #include "intel_batchbuffer.h" #include "intel_buffer_objects.h" -#include "intel_tex.h" static GLuint double_types[5] = { 0, @@ -59,6 +55,14 @@ static GLuint float_types[5] = { BRW_SURFACEFORMAT_R32G32B32A32_FLOAT }; +static GLuint half_float_types[5] = { + 0, + BRW_SURFACEFORMAT_R16_FLOAT, + BRW_SURFACEFORMAT_R16G16_FLOAT, + 0, /* can't seem to render this one */ + BRW_SURFACEFORMAT_R16G16B16A16_FLOAT +}; + static GLuint uint_types_norm[5] = { 0, BRW_SURFACEFORMAT_R32_UNORM, @@ -172,6 +176,7 @@ static GLuint get_surface_type( GLenum type, GLuint size, switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; + case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_norm[size]; case GL_SHORT: return short_types_norm[size]; case GL_BYTE: return byte_types_norm[size]; @@ -194,6 +199,7 @@ static GLuint get_surface_type( GLenum type, GLuint size, switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; + case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_scale[size]; case GL_SHORT: return short_types_scale[size]; case GL_BYTE: return byte_types_scale[size]; @@ -211,6 +217,7 @@ static GLuint get_size( GLenum type ) switch (type) { case GL_DOUBLE: return sizeof(GLdouble); case GL_FLOAT: return sizeof(GLfloat); + case GL_HALF_FLOAT: return sizeof(GLhalfARB); case GL_INT: return sizeof(GLint); case GL_SHORT: return sizeof(GLshort); case GL_BYTE: return sizeof(GLbyte); diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index fe5c1ae279..ba401c215c 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -36,13 +36,9 @@ #include "swrast/swrast.h" #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_fallback.h" -#include "intel_chipset.h" #include "intel_fbo.h" #include "intel_regions.h" -#include "glapi/glapi.h" - #define FILE_DEBUG_FLAG DEBUG_FALLBACKS static GLboolean do_check_fallback(struct brw_context *brw) diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 1bc3eccf49..7261b316c1 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -125,12 +125,13 @@ static void compile_gs_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->gs.prog_bo); - brw->gs.prog_bo = brw_upload_cache( &brw->cache, BRW_GS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->gs.prog_data ); + brw->gs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_GS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->gs.prog_data); } static const GLenum gs_prim[GL_POLYGON+1] = { diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index a81b972ef4..dd7b057d62 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -40,7 +40,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_gs.h" static void brw_gs_alloc_regs( struct brw_gs_compile *c, diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c index 1af5790a67..d8ad5cecf3 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_state.c @@ -34,7 +34,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "main/macros.h" struct brw_gs_unit_key { unsigned int total_grf; @@ -108,8 +107,7 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_GS_UNIT, key, sizeof(*key), &brw->gs.prog_bo, 1, - &gs, sizeof(gs), - NULL, NULL); + &gs, sizeof(gs)); if (key->prog_active) { /* Emit GS program relocation */ diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 7b70f787b7..f708ee0063 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -327,7 +327,7 @@ const struct brw_tracked_state brw_polygon_stipple = { static void upload_polygon_stipple_offset(struct brw_context *brw) { - __DRIdrawable *dPriv = brw->intel.driDrawable; + GLcontext *ctx = &brw->intel.ctx; struct brw_polygon_stipple_offset bpso; memset(&bpso, 0, sizeof(bpso)); @@ -343,8 +343,8 @@ static void upload_polygon_stipple_offset(struct brw_context *brw) * worry about. */ if (brw->intel.ctx.DrawBuffer->Name == 0) { - bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31; - bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31; + bpso.bits0.x_offset = 0; + bpso.bits0.y_offset = (32 - (ctx->DrawBuffer->Height & 31)) & 31; } else { bpso.bits0.y_offset = 0; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index bac69187c1..c78f7b38ae 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -37,7 +37,6 @@ #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" static void brwBindProgram( GLcontext *ctx, @@ -112,9 +111,10 @@ static GLboolean brwIsProgramNative( GLcontext *ctx, return GL_TRUE; } -static void brwProgramStringNotify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) + +static GLboolean brwProgramStringNotify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); @@ -151,6 +151,9 @@ static void brwProgramStringNotify( GLcontext *ctx, */ _tnl_program_string(ctx, target, prog); } + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } void brwInitFragProgFuncs( struct dd_function_table *functions ) diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 968890f7fb..8e6839b812 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -117,12 +117,13 @@ static void compile_sf_prog( struct brw_context *brw, /* Upload */ dri_bo_unreference(brw->sf.prog_bo); - brw->sf.prog_bo = brw_upload_cache( &brw->cache, BRW_SF_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->sf.prog_data ); + brw->sf.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_SF_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + sizeof(c.prog_data), + &brw->sf.prog_data); } /* Calculate interpolants for triangle and line rasterization. diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 09223b7cfb..847c886279 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -35,7 +35,6 @@ #include "brw_state.h" #include "brw_defines.h" #include "main/macros.h" -#include "intel_fbo.h" static void upload_sf_vp(struct brw_context *brw) { @@ -70,9 +69,9 @@ static void upload_sf_vp(struct brw_context *brw) * for DrawBuffer->_[XY]{min,max} */ - /* The scissor only needs to handle the intersection of drawable and - * scissor rect. Clipping to the boundaries of static shared buffers - * for front/back/depth is covered by looping over cliprects in brw_draw.c. + /* The scissor only needs to handle the intersection of drawable + * and scissor rect, since there are no longer cliprects for shared + * buffers with DRI2. * * Note that the hardware's coordinates are inclusive, while Mesa's min is * inclusive but max is exclusive. @@ -309,8 +308,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key, bo = brw_upload_cache(&brw->cache, BRW_SF_UNIT, key, sizeof(*key), reloc_bufs, 2, - &sf, sizeof(sf), - NULL, NULL); + &sf, sizeof(sf)); /* STATE_PREFETCH command description describes this state as being * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain. diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 9c9d145c4b..536fe8b249 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -124,16 +124,26 @@ dri_bo *brw_cache_data(struct brw_cache *cache, dri_bo **reloc_bufs, GLuint nr_reloc_bufs); -dri_bo *brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_sz, - dri_bo **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_sz, - const void *aux, - void *aux_return ); +drm_intel_bo *brw_upload_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz); + +drm_intel_bo *brw_upload_cache_with_auxdata(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_sz, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_sz, + const void *aux, + GLuint aux_sz, + void *aux_return); dri_bo *brw_search_cache( struct brw_cache *cache, enum brw_cache_id cache_id, diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index e4c9ba7d87..5fc47b0420 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -71,25 +71,23 @@ static GLuint -hash_key(const void *key, GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs) +hash_key(struct brw_cache_item *item) { - GLuint *ikey = (GLuint *)key; - GLuint hash = 0, i; + GLuint *ikey = (GLuint *)item->key; + GLuint hash = item->cache_id, i; - assert(key_size % 4 == 0); + assert(item->key_size % 4 == 0); /* I'm sure this can be improved on: */ - for (i = 0; i < key_size/4; i++) { + for (i = 0; i < item->key_size/4; i++) { hash ^= ikey[i]; hash = (hash << 5) | (hash >> 27); } /* Include the BO pointers as key data as well */ - ikey = (GLuint *)reloc_bufs; - key_size = nr_reloc_bufs * sizeof(dri_bo *); - for (i = 0; i < key_size/4; i++) { + ikey = (GLuint *)item->reloc_bufs; + for (i = 0; i < item->nr_reloc_bufs * sizeof(drm_intel_bo *) / 4; i++) { hash ^= ikey[i]; hash = (hash << 5) | (hash >> 27); } @@ -114,11 +112,22 @@ update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id, cache->brw->state.dirty.cache |= 1 << cache_id; } +static int +brw_cache_item_equals(const struct brw_cache_item *a, + const struct brw_cache_item *b) +{ + return a->cache_id == b->cache_id && + a->hash == b->hash && + a->key_size == b->key_size && + (memcmp(a->key, b->key, a->key_size) == 0) && + a->nr_reloc_bufs == b->nr_reloc_bufs && + (memcmp(a->reloc_bufs, b->reloc_bufs, + a->nr_reloc_bufs * sizeof(dri_bo *)) == 0); +} static struct brw_cache_item * -search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, - GLuint hash, const void *key, GLuint key_size, - dri_bo **reloc_bufs, GLuint nr_reloc_bufs) +search_cache(struct brw_cache *cache, GLuint hash, + struct brw_cache_item *lookup) { struct brw_cache_item *c; @@ -133,13 +142,7 @@ search_cache(struct brw_cache *cache, enum brw_cache_id cache_id, #endif for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->cache_id == cache_id && - c->hash == hash && - c->key_size == key_size && - memcmp(c->key, key, key_size) == 0 && - c->nr_reloc_bufs == nr_reloc_bufs && - memcmp(c->reloc_bufs, reloc_bufs, - nr_reloc_bufs * sizeof(dri_bo *)) == 0) + if (brw_cache_item_equals(lookup, c)) return c; } @@ -182,10 +185,18 @@ brw_search_cache(struct brw_cache *cache, void *aux_return) { struct brw_cache_item *item; - GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); + struct brw_cache_item lookup; + GLuint hash; - item = search_cache(cache, cache_id, hash, key, key_size, - reloc_bufs, nr_reloc_bufs); + lookup.cache_id = cache_id; + lookup.key = key; + lookup.key_size = key_size; + lookup.reloc_bufs = reloc_bufs; + lookup.nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(&lookup); + lookup.hash = hash; + + item = search_cache(cache, hash, &lookup); if (item == NULL) return NULL; @@ -200,26 +211,34 @@ brw_search_cache(struct brw_cache *cache, } -dri_bo * -brw_upload_cache( struct brw_cache *cache, - enum brw_cache_id cache_id, - const void *key, - GLuint key_size, - dri_bo **reloc_bufs, - GLuint nr_reloc_bufs, - const void *data, - GLuint data_size, - const void *aux, - void *aux_return ) +drm_intel_bo * +brw_upload_cache_with_auxdata(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_size, + const void *aux, + GLuint aux_size, + void *aux_return) { struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); - GLuint hash = hash_key(key, key_size, reloc_bufs, nr_reloc_bufs); + GLuint hash; GLuint relocs_size = nr_reloc_bufs * sizeof(dri_bo *); - GLuint aux_size = cache->aux_size[cache_id]; void *tmp; dri_bo *bo; int i; + item->cache_id = cache_id; + item->key = key; + item->key_size = key_size; + item->reloc_bufs = reloc_bufs; + item->nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(item); + item->hash = hash; + /* Create the buffer object to contain the data */ bo = dri_bo_alloc(cache->brw->intel.bufmgr, cache->name[cache_id], data_size, 1 << 6); @@ -229,19 +248,15 @@ brw_upload_cache( struct brw_cache *cache, tmp = _mesa_malloc(key_size + aux_size + relocs_size); memcpy(tmp, key, key_size); - memcpy(tmp + key_size, aux, cache->aux_size[cache_id]); + memcpy(tmp + key_size, aux, aux_size); memcpy(tmp + key_size + aux_size, reloc_bufs, relocs_size); for (i = 0; i < nr_reloc_bufs; i++) { if (reloc_bufs[i] != NULL) dri_bo_reference(reloc_bufs[i]); } - item->cache_id = cache_id; item->key = tmp; - item->hash = hash; - item->key_size = key_size; item->reloc_bufs = tmp + key_size + aux_size; - item->nr_reloc_bufs = nr_reloc_bufs; item->bo = bo; dri_bo_reference(bo); @@ -255,7 +270,6 @@ brw_upload_cache( struct brw_cache *cache, cache->n_items++; if (aux_return) { - assert(cache->aux_size[cache_id]); *(void **)aux_return = (void *)((char *)item->key + item->key_size); } @@ -272,6 +286,23 @@ brw_upload_cache( struct brw_cache *cache, return bo; } +drm_intel_bo * +brw_upload_cache(struct brw_cache *cache, + enum brw_cache_id cache_id, + const void *key, + GLuint key_size, + dri_bo **reloc_bufs, + GLuint nr_reloc_bufs, + const void *data, + GLuint data_size) +{ + return brw_upload_cache_with_auxdata(cache, cache_id, + key, key_size, + reloc_bufs, nr_reloc_bufs, + data, data_size, + NULL, 0, + NULL); +} /** * Wrapper around brw_cache_data_sz using the cache_id's canonical key size. @@ -292,11 +323,18 @@ brw_cache_data(struct brw_cache *cache, GLuint nr_reloc_bufs) { dri_bo *bo; - struct brw_cache_item *item; - GLuint hash = hash_key(data, data_size, reloc_bufs, nr_reloc_bufs); - - item = search_cache(cache, cache_id, hash, data, data_size, - reloc_bufs, nr_reloc_bufs); + struct brw_cache_item *item, lookup; + GLuint hash; + + lookup.cache_id = cache_id; + lookup.key = data; + lookup.key_size = data_size; + lookup.reloc_bufs = reloc_bufs; + lookup.nr_reloc_bufs = nr_reloc_bufs; + hash = hash_key(&lookup); + lookup.hash = hash; + + item = search_cache(cache, hash, &lookup); if (item) { update_cache_last(cache, cache_id, item->bo); dri_bo_reference(item->bo); @@ -306,8 +344,7 @@ brw_cache_data(struct brw_cache *cache, bo = brw_upload_cache(cache, cache_id, data, data_size, reloc_bufs, nr_reloc_bufs, - data, data_size, - NULL, NULL); + data, data_size); return bo; } @@ -321,11 +358,9 @@ enum pool_type { static void brw_init_cache_id(struct brw_cache *cache, const char *name, - enum brw_cache_id id, - GLuint aux_size) + enum brw_cache_id id) { cache->name[id] = strdup(name); - cache->aux_size[id] = aux_size; } @@ -341,80 +376,28 @@ brw_init_non_surface_cache(struct brw_context *brw) cache->items = (struct brw_cache_item **) _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(cache, - "CC_VP", - BRW_CC_VP, - 0); - - brw_init_cache_id(cache, - "CC_UNIT", - BRW_CC_UNIT, - 0); - - brw_init_cache_id(cache, - "WM_PROG", - BRW_WM_PROG, - sizeof(struct brw_wm_prog_data)); - - brw_init_cache_id(cache, - "SAMPLER_DEFAULT_COLOR", - BRW_SAMPLER_DEFAULT_COLOR, - 0); - - brw_init_cache_id(cache, - "SAMPLER", - BRW_SAMPLER, - 0); - - brw_init_cache_id(cache, - "WM_UNIT", - BRW_WM_UNIT, - 0); - - brw_init_cache_id(cache, - "SF_PROG", - BRW_SF_PROG, - sizeof(struct brw_sf_prog_data)); - - brw_init_cache_id(cache, - "SF_VP", - BRW_SF_VP, - 0); - - brw_init_cache_id(cache, - "SF_UNIT", - BRW_SF_UNIT, - 0); - - brw_init_cache_id(cache, - "VS_UNIT", - BRW_VS_UNIT, - 0); - - brw_init_cache_id(cache, - "VS_PROG", - BRW_VS_PROG, - sizeof(struct brw_vs_prog_data)); - - brw_init_cache_id(cache, - "CLIP_UNIT", - BRW_CLIP_UNIT, - 0); - - brw_init_cache_id(cache, - "CLIP_PROG", - BRW_CLIP_PROG, - sizeof(struct brw_clip_prog_data)); - - brw_init_cache_id(cache, - "GS_UNIT", - BRW_GS_UNIT, - 0); - - brw_init_cache_id(cache, - "GS_PROG", - BRW_GS_PROG, - sizeof(struct brw_gs_prog_data)); + brw_init_cache_id(cache, "CC_VP", BRW_CC_VP); + brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT); + brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG); + brw_init_cache_id(cache, "SAMPLER_DEFAULT_COLOR", BRW_SAMPLER_DEFAULT_COLOR); + brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER); + brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT); + brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG); + brw_init_cache_id(cache, "SF_VP", BRW_SF_VP); + + brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT); + + brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT); + + brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG); + + brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT); + + brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG); + + brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT); + + brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG); } @@ -430,15 +413,8 @@ brw_init_surface_cache(struct brw_context *brw) cache->items = (struct brw_cache_item **) _mesa_calloc(cache->size * sizeof(struct brw_cache_item)); - brw_init_cache_id(cache, - "SS_SURFACE", - BRW_SS_SURFACE, - 0); - - brw_init_cache_id(cache, - "SS_SURF_BIND", - BRW_SS_SURF_BIND, - 0); + brw_init_cache_id(cache, "SS_SURFACE", BRW_SS_SURFACE); + brw_init_cache_id(cache, "SS_SURF_BIND", BRW_SS_SURF_BIND); } diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c index e94fa7d2b4..020ac523b6 100644 --- a/src/mesa/drivers/dri/i965/brw_state_dump.c +++ b/src/mesa/drivers/dri/i965/brw_state_dump.c @@ -28,7 +28,6 @@ #include "main/mtypes.h" #include "brw_context.h" -#include "brw_state.h" #include "brw_defines.h" /** diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index af8dfb4c15..0ecbef1ef9 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -36,13 +36,7 @@ #include "intel_batchbuffer.h" #include "intel_buffers.h" -/* This is used to initialize brw->state.atoms[]. We could use this - * list directly except for a single atom, brw_constant_buffer, which - * has a .dirty value which changes according to the parameters of the - * current fragment and vertex programs, and so cannot be a static - * value. - */ -const struct brw_tracked_state *atoms[] = +static const struct brw_tracked_state *atoms[] = { &brw_check_fallback, @@ -208,7 +202,6 @@ static struct dirty_bit_map brw_bits[] = { DEFINE_BIT(BRW_NEW_CONTEXT), DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS), DEFINE_BIT(BRW_NEW_PSP), - DEFINE_BIT(BRW_NEW_FENCE), DEFINE_BIT(BRW_NEW_INDICES), DEFINE_BIT(BRW_NEW_INDEX_BUFFER), DEFINE_BIT(BRW_NEW_VERTICES), diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 64a9535282..09edfd81fd 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -36,7 +36,6 @@ #include "intel_tex_layout.h" #include "intel_context.h" #include "main/macros.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_MIPTREE diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index fd055e225e..44b085e214 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -35,6 +35,7 @@ #include "brw_util.h" #include "brw_state.h" #include "shader/prog_print.h" +#include "shader/prog_parameter.h" @@ -42,9 +43,11 @@ static void do_vs_prog( struct brw_context *brw, struct brw_vertex_program *vp, struct brw_vs_prog_key *key ) { + GLcontext *ctx = &brw->intel.ctx; GLuint program_size; const GLuint *program; struct brw_vs_compile c; + int aux_size; memset(&c, 0, sizeof(c)); memcpy(&c.key, key, sizeof(*key)); @@ -73,13 +76,27 @@ static void do_vs_prog( struct brw_context *brw, */ program = brw_get_program(&c.func, &program_size); + /* We upload from &c.prog_data including the constant_map assuming + * they're packed together. It would be nice to have a + * compile-time assert macro here. + */ + assert(c.constant_map == (int8_t *)&c.prog_data + + sizeof(c.prog_data)); + assert(ctx->Const.VertexProgram.MaxNativeParameters == + ARRAY_SIZE(c.constant_map)); + + aux_size = sizeof(c.prog_data); + if (c.vp->use_const_buffer) + aux_size += c.vp->program.Base.Parameters->NumParameters; + dri_bo_unreference(brw->vs.prog_bo); - brw->vs.prog_bo = brw_upload_cache( &brw->cache, BRW_VS_PROG, - &c.key, sizeof(c.key), - NULL, 0, - program, program_size, - &c.prog_data, - &brw->vs.prog_data ); + brw->vs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_VS_PROG, + &c.key, sizeof(c.key), + NULL, 0, + program, program_size, + &c.prog_data, + aux_size, + &brw->vs.prog_data); } @@ -109,6 +126,8 @@ static void brw_upload_vs_prog(struct brw_context *brw) &brw->vs.prog_data); if (brw->vs.prog_bo == NULL) do_vs_prog(brw, vp, &key); + brw->vs.constant_map = ((int8_t *)brw->vs.prog_data + + sizeof(*brw->vs.prog_data)); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index 4a591365c9..95e0501b1e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -51,6 +51,7 @@ struct brw_vs_compile { struct brw_compile func; struct brw_vs_prog_key key; struct brw_vs_prog_data prog_data; + int8_t constant_map[1024]; struct brw_vertex_program *vp; @@ -81,6 +82,8 @@ struct brw_vs_compile { GLint index; struct brw_reg reg; } current_const[3]; + + GLboolean needs_stack; }; void brw_vs_emit( struct brw_vs_compile *c ); diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 1b84dd505f..4f4eef85e8 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -104,9 +104,47 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) /* Vertex program parameters from curbe: */ if (c->vp->use_const_buffer) { - /* get constants from a real constant buffer */ - c->prog_data.curb_read_length = 0; - c->prog_data.nr_params = 4; /* XXX 0 causes a bug elsewhere... */ + int max_constant = BRW_MAX_GRF - 20 - c->vp->program.Base.NumTemporaries; + int constant = 0; + + /* We've got more constants than we can load with the push + * mechanism. This is often correlated with reladdr loads where + * we should probably be using a pull mechanism anyway to avoid + * excessive reading. However, the pull mechanism is slow in + * general. So, we try to allocate as many non-reladdr-loaded + * constants through the push buffer as we can before giving up. + */ + memset(c->constant_map, -1, c->vp->program.Base.Parameters->NumParameters); + for (i = 0; + i < c->vp->program.Base.NumInstructions && constant < max_constant; + i++) { + struct prog_instruction *inst = &c->vp->program.Base.Instructions[i]; + int arg; + + for (arg = 0; arg < 3 && constant < max_constant; arg++) { + if ((inst->SrcReg[arg].File != PROGRAM_STATE_VAR && + inst->SrcReg[arg].File != PROGRAM_CONSTANT && + inst->SrcReg[arg].File != PROGRAM_UNIFORM && + inst->SrcReg[arg].File != PROGRAM_ENV_PARAM && + inst->SrcReg[arg].File != PROGRAM_LOCAL_PARAM) || + inst->SrcReg[arg].RelAddr) + continue; + + if (c->constant_map[inst->SrcReg[arg].Index] == -1) { + c->constant_map[inst->SrcReg[arg].Index] = constant++; + } + } + } + + for (i = 0; i < constant; i++) { + c->regs[PROGRAM_STATE_VAR][i] = stride( brw_vec4_grf(reg+i/2, + (i%2) * 4), + 0, 4, 1); + } + reg += (constant + 1) / 2; + c->prog_data.curb_read_length = reg - 1; + /* XXX 0 causes a bug elsewhere... */ + c->prog_data.nr_params = MAX2(constant * 4, 4); } else { /* use a section of the GRF for constants */ @@ -214,8 +252,10 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c ) } } - c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); - reg += 2; + if (c->needs_stack) { + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); + reg += 2; + } /* Some opcodes need an internal temporary: */ @@ -762,15 +802,14 @@ get_constant(struct brw_vs_compile *c, { const struct prog_src_register *src = &inst->SrcReg[argIndex]; struct brw_compile *p = &c->func; - struct brw_reg const_reg; - struct brw_reg const2_reg; - const GLboolean relAddr = src->RelAddr; + struct brw_reg const_reg = c->current_const[argIndex].reg; assert(argIndex < 3); - if (c->current_const[argIndex].index != src->Index || relAddr) { + if (c->current_const[argIndex].index != src->Index) { struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; + /* Keep track of the last constant loaded in this slot, for reuse. */ c->current_const[argIndex].index = src->Index; #if 0 @@ -779,48 +818,74 @@ get_constant(struct brw_vs_compile *c, #endif /* need to fetch the constant now */ brw_dp_READ_4_vs(p, - c->current_const[argIndex].reg,/* writeback dest */ + const_reg, /* writeback dest */ 0, /* oword */ - relAddr, /* relative indexing? */ + 0, /* relative indexing? */ addrReg, /* address register */ 16 * src->Index, /* byte offset */ SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ ); - - if (relAddr) { - /* second read */ - const2_reg = get_tmp(c); - - /* use upper half of address reg for second read */ - addrReg = stride(addrReg, 0, 4, 0); - addrReg.subnr = 16; - - brw_dp_READ_4_vs(p, - const2_reg, /* writeback dest */ - 1, /* oword */ - relAddr, /* relative indexing? */ - addrReg, /* address register */ - 16 * src->Index, /* byte offset */ - SURF_INDEX_VERT_CONST_BUFFER - ); - } } - const_reg = c->current_const[argIndex].reg; + /* replicate lower four floats into upper half (to get XYZWXYZW) */ + const_reg = stride(const_reg, 0, 4, 0); + const_reg.subnr = 0; - if (relAddr) { - /* merge the two Owords into the constant register */ - /* const_reg[7..4] = const2_reg[7..4] */ - brw_MOV(p, - suboffset(stride(const_reg, 0, 4, 1), 4), - suboffset(stride(const2_reg, 0, 4, 1), 4)); - release_tmp(c, const2_reg); - } - else { - /* replicate lower four floats into upper half (to get XYZWXYZW) */ - const_reg = stride(const_reg, 0, 4, 0); - const_reg.subnr = 0; - } + return const_reg; +} + +static struct brw_reg +get_reladdr_constant(struct brw_vs_compile *c, + const struct prog_instruction *inst, + GLuint argIndex) +{ + const struct prog_src_register *src = &inst->SrcReg[argIndex]; + struct brw_compile *p = &c->func; + struct brw_reg const_reg = c->current_const[argIndex].reg; + struct brw_reg const2_reg; + struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0]; + + assert(argIndex < 3); + + /* Can't reuse a reladdr constant load. */ + c->current_const[argIndex].index = -1; + + #if 0 + printf(" fetch const[a0.x+%d] for arg %d into reg %d\n", + src->Index, argIndex, c->current_const[argIndex].reg.nr); +#endif + + /* fetch the first vec4 */ + brw_dp_READ_4_vs(p, + const_reg, /* writeback dest */ + 0, /* oword */ + 1, /* relative indexing? */ + addrReg, /* address register */ + 16 * src->Index, /* byte offset */ + SURF_INDEX_VERT_CONST_BUFFER /* binding table index */ + ); + /* second vec4 */ + const2_reg = get_tmp(c); + + /* use upper half of address reg for second read */ + addrReg = stride(addrReg, 0, 4, 0); + addrReg.subnr = 16; + + brw_dp_READ_4_vs(p, + const2_reg, /* writeback dest */ + 1, /* oword */ + 1, /* relative indexing? */ + addrReg, /* address register */ + 16 * src->Index, /* byte offset */ + SURF_INDEX_VERT_CONST_BUFFER + ); + + /* merge the two Owords into the constant register */ + /* const_reg[7..4] = const2_reg[7..4] */ + brw_MOV(p, + suboffset(stride(const_reg, 0, 4, 1), 4), + suboffset(stride(const2_reg, 0, 4, 1), 4)); + release_tmp(c, const2_reg); return const_reg; } @@ -928,7 +993,13 @@ get_src_reg( struct brw_vs_compile *c, case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: if (c->vp->use_const_buffer) { - return get_constant(c, inst, argIndex); + if (!relAddr && c->constant_map[index] != -1) { + assert(c->regs[PROGRAM_STATE_VAR][c->constant_map[index]].nr != 0); + return c->regs[PROGRAM_STATE_VAR][c->constant_map[index]]; + } else if (relAddr) + return get_reladdr_constant(c, inst, argIndex); + else + return get_constant(c, inst, argIndex); } else if (relAddr) { return deref(c, c->regs[PROGRAM_STATE_VAR][0], index); @@ -1367,7 +1438,7 @@ void brw_vs_emit(struct brw_vs_compile *c ) GLuint insn, if_depth = 0, loop_depth = 0; GLuint end_offset = 0; struct brw_instruction *end_inst, *last_inst; - struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH]; + struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH] = { 0 }; const struct brw_indirect stack_index = brw_indirect(0, 0); GLuint index; GLuint file; @@ -1380,12 +1451,14 @@ void brw_vs_emit(struct brw_vs_compile *c ) brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_access_mode(p, BRW_ALIGN_16); - - /* Message registers can't be read, so copy the output into GRF register - if they are used in source registers */ + for (insn = 0; insn < nr_insns; insn++) { GLuint i; struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn]; + + /* Message registers can't be read, so copy the output into GRF + * register if they are used in source registers + */ for (i = 0; i < 3; i++) { struct prog_src_register *src = &inst->SrcReg[i]; GLuint index = src->Index; @@ -1393,12 +1466,23 @@ void brw_vs_emit(struct brw_vs_compile *c ) if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS) c->output_regs[index].used_in_src = GL_TRUE; } + + switch (inst->Opcode) { + case OPCODE_CAL: + case OPCODE_RET: + c->needs_stack = GL_TRUE; + break; + default: + break; + } } /* Static register allocation */ brw_vs_alloc_regs(c); - brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); + + if (c->needs_stack) + brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); for (insn = 0; insn < nr_insns; insn++) { diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c index 345ffa7ee1..fd9f2fee42 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_state.c @@ -164,8 +164,7 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key) bo = brw_upload_cache(&brw->cache, BRW_VS_UNIT, key, sizeof(*key), &brw->vs.prog_bo, 1, - &vs, sizeof(vs), - NULL, NULL); + &vs, sizeof(vs)); /* Emit VS program relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c index 3bc9840a97..ead623fc0e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -35,7 +35,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" /* Creates a new VS constant buffer reflecting the current VS program's * constants, if needed by the VS program. @@ -156,7 +155,7 @@ brw_vs_get_binding_table(struct brw_context *brw) if (bind_bo == NULL) { GLuint data_size = BRW_VS_MAX_SURF * sizeof(GLuint); - uint32_t *data = malloc(data_size); + uint32_t data[BRW_VS_MAX_SURF]; int i; for (i = 0; i < BRW_VS_MAX_SURF; i++) @@ -168,8 +167,7 @@ brw_vs_get_binding_table(struct brw_context *brw) bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->vs.surf_bo, BRW_VS_MAX_SURF, - data, data_size, - NULL, NULL); + data, data_size); /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_VS_MAX_SURF; i++) { @@ -182,8 +180,6 @@ brw_vs_get_binding_table(struct brw_context *brw) I915_GEM_DOMAIN_INSTRUCTION, 0); } } - - free(data); } return bind_bo; diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 72749b3859..681319dedf 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -44,7 +44,6 @@ #include "brw_state.h" #include "brw_draw.h" #include "brw_state.h" -#include "brw_fallback.h" #include "brw_vs.h" #include "brw_wm.h" @@ -140,6 +139,12 @@ static void brw_finish_batch(struct intel_context *intel) { struct brw_context *brw = brw_context(&intel->ctx); brw_emit_query_end(brw); + + if (brw->curbe.curbe_bo) { + intel_bo_unmap_gtt_preferred(intel, brw->curbe.curbe_bo); + drm_intel_bo_unreference(brw->curbe.curbe_bo); + brw->curbe.curbe_bo = NULL; + } } @@ -150,8 +155,6 @@ static void brw_new_batch( struct intel_context *intel ) { struct brw_context *brw = brw_context(&intel->ctx); - brw->curbe.need_new_bo = GL_TRUE; - /* Mark all context state as needing to be re-emitted. * This is probably not as severe as on 915, since almost all of our state * is just in referenced buffers. @@ -172,12 +175,6 @@ static void brw_new_batch( struct intel_context *intel ) } } - -static void brw_note_fence( struct intel_context *intel, GLuint fence ) -{ - brw_context(&intel->ctx)->state.dirty.brw |= BRW_NEW_FENCE; -} - static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) { /* nothing */ @@ -193,7 +190,6 @@ void brwInitVtbl( struct brw_context *brw ) brw->intel.vtbl.update_texture_state = 0; brw->intel.vtbl.invalidate_state = brw_invalidate_state; - brw->intel.vtbl.note_fence = brw_note_fence; brw->intel.vtbl.new_batch = brw_new_batch; brw->intel.vtbl.finish_batch = brw_finish_batch; brw->intel.vtbl.destroy = brw_destroy_context; diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 6895f64410..9191c81755 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -30,7 +30,6 @@ */ #include "brw_context.h" -#include "brw_util.h" #include "brw_wm.h" #include "brw_state.h" @@ -199,12 +198,13 @@ static void do_wm_prog( struct brw_context *brw, program = brw_get_program(&c->func, &program_size); dri_bo_unreference(brw->wm.prog_bo); - brw->wm.prog_bo = brw_upload_cache( &brw->cache, BRW_WM_PROG, - &c->key, sizeof(c->key), - NULL, 0, - program, program_size, - &c->prog_data, - &brw->wm.prog_data ); + brw->wm.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_WM_PROG, + &c->key, sizeof(c->key), + NULL, 0, + program, program_size, + &c->prog_data, + sizeof(c->prog_data), + &brw->wm.prog_data); } @@ -336,11 +336,7 @@ static void brw_wm_populate_key( struct brw_context *brw, * drawable height in order to invert the Y axis. */ if (fp->program.Base.InputsRead & FRAG_BIT_WPOS) { - if (brw->intel.driDrawable != NULL) { - key->origin_x = brw->intel.driDrawable->x; - key->origin_y = brw->intel.driDrawable->y; - key->drawable_height = brw->intel.driDrawable->h; - } + key->drawable_height = ctx->DrawBuffer->Height; } key->nr_color_regions = brw->state.nr_color_regions; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index b9b987ea70..88d84ee82f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -76,7 +76,6 @@ struct brw_wm_prog_key { GLushort tex_swizzles[BRW_MAX_TEX_UNIT]; - GLushort origin_x, origin_y; GLushort drawable_height; GLbitfield64 vp_outputs_written; GLuint program_string_id:32; diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index f316e0cda4..fa0898c586 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -138,19 +138,43 @@ void emit_wpos_xy(struct brw_wm_compile *c, * X and Y channels. */ if (mask & WRITEMASK_X) { - /* X' = X - origin */ - brw_ADD(p, - dst[0], - retype(arg0[0], BRW_REGISTER_TYPE_W), - brw_imm_d(0 - c->key.origin_x)); + if (c->fp->program.PixelCenterInteger) { + /* X' = X */ + brw_MOV(p, + dst[0], + retype(arg0[0], BRW_REGISTER_TYPE_W)); + } else { + /* X' = X + 0.5 */ + brw_ADD(p, + dst[0], + retype(arg0[0], BRW_REGISTER_TYPE_W), + brw_imm_f(0.5)); + } } if (mask & WRITEMASK_Y) { - /* Y' = height - (Y - origin_y) = height + origin_y - Y */ - brw_ADD(p, - dst[1], - negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), - brw_imm_d(c->key.origin_y + c->key.drawable_height - 1)); + if (c->fp->program.OriginUpperLeft) { + if (c->fp->program.PixelCenterInteger) { + /* Y' = Y */ + brw_MOV(p, + dst[1], + retype(arg0[1], BRW_REGISTER_TYPE_W)); + } else { + /* Y' = Y + 0.5 */ + brw_ADD(p, + dst[1], + retype(arg0[1], BRW_REGISTER_TYPE_W), + brw_imm_f(0.5)); + } + } else { + float center_offset = c->fp->program.PixelCenterInteger ? 0.0 : 0.5; + + /* Y' = (height - 1) - Y + center */ + brw_ADD(p, + dst[1], + negate(retype(arg0[1], BRW_REGISTER_TYPE_W)), + brw_imm_f(c->key.drawable_height - 1 + center_offset)); + } } } diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index ad267a4e6a..87387b1e2d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -326,8 +326,7 @@ static void upload_wm_samplers( struct brw_context *brw ) brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER, &key, sizeof(key), brw->wm.sdc_bo, key.sampler_count, - &sampler, sizeof(sampler), - NULL, NULL); + &sampler, sizeof(sampler)); /* Emit SDC relocations */ for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index d3373ea79e..a7f80db554 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -210,8 +210,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key, bo = brw_upload_cache(&brw->cache, BRW_WM_UNIT, key, sizeof(*key), reloc_bufs, 3, - &wm, sizeof(wm), - NULL, NULL); + &wm, sizeof(wm)); /* Emit WM program relocation */ dri_bo_emit_reloc(bo, diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index f26cfabb7d..1db438ae7b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -256,8 +256,7 @@ brw_create_texture_surface( struct brw_context *brw, bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (key->bo) { /* Emit relocation to surface contents */ @@ -351,8 +350,7 @@ brw_create_constant_surface( struct brw_context *brw, bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE, key, sizeof(*key), &key->bo, key->bo ? 1 : 0, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (key->bo) { /* Emit relocation to surface contents. Section 5.1.1 of the gen4 @@ -579,7 +577,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.draw_y = 0; } /* _NEW_COLOR */ - memcpy(key.color_mask, ctx->Color.ColorMask[0], + memcpy(key.color_mask, ctx->Color.ColorMask[unit], sizeof(key.color_mask)); /* As mentioned above, disable writes to the alpha component when the @@ -589,7 +587,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, key.color_mask[3] = GL_FALSE; key.color_blend = (!ctx->Color._LogicOpEnabled && - ctx->Color.BlendEnabled); + (ctx->Color.BlendEnabled & (1 << unit))); dri_bo_unreference(brw->wm.surf_bo[unit]); brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache, @@ -653,8 +651,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw, BRW_SS_SURFACE, &key, sizeof(key), ®ion_bo, 1, - &surf, sizeof(surf), - NULL, NULL); + &surf, sizeof(surf)); if (region_bo != NULL) { /* We might sample from it, and we might render to it, so flag * them both. We might be able to figure out from other state @@ -701,8 +698,7 @@ brw_wm_get_binding_table(struct brw_context *brw) bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND, NULL, 0, brw->wm.surf_bo, brw->wm.nr_surfaces, - data, data_size, - NULL, NULL); + data, data_size); /* Emit binding table relocations to surface state */ for (i = 0; i < BRW_WM_MAX_SURF; i++) { diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 3a4b21a844..ae0f8a16f9 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -32,44 +32,6 @@ #include "intel_bufmgr.h" #include "intel_buffers.h" -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { @@ -167,7 +129,8 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; - if (intel->first_post_swapbuffers_batch == NULL) { + if (!intel->using_dri2_swapbuffers && + intel->first_post_swapbuffers_batch == NULL) { intel->first_post_swapbuffers_batch = intel->batch->buf; drm_intel_bo_reference(intel->first_post_swapbuffers_batch); } diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c index 55bee0084c..1fd07e8b82 100644 --- a/src/mesa/drivers/dri/intel/intel_blit.c +++ b/src/mesa/drivers/dri/intel/intel_blit.c @@ -38,7 +38,6 @@ #include "intel_reg.h" #include "intel_regions.h" #include "intel_batchbuffer.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_BLIT @@ -103,7 +102,7 @@ intelEmitCopyBlit(struct intel_context *intel, return GL_FALSE; } - /* do space/cliprects check before going any further */ + /* do space check before going any further */ do { aper_array[0] = intel->batch->buf; aper_array[1] = dst_buffer; @@ -213,10 +212,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) struct intel_context *intel = intel_context(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint clear_depth; - GLbitfield skipBuffers = 0; - unsigned int num_cliprects; - struct drm_clip_rect *cliprects; - int x_off, y_off; + GLboolean all; + GLint cx, cy, cw, ch; BATCH_LOCALS; /* @@ -230,183 +227,144 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask) clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } - /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in - * the loop below. - */ - if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { - skipBuffers = BUFFER_BIT_STENCIL; - } - - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects) { - GLint cx, cy, cw, ch; - drm_clip_rect_t clear; - int i; - - /* Get clear bounds after locking */ - cx = fb->_Xmin; + cx = fb->_Xmin; + if (fb->Name == 0) + cy = ctx->DrawBuffer->Height - fb->_Ymax; + else cy = fb->_Ymin; - cw = fb->_Xmax - cx; - ch = fb->_Ymax - cy; + cw = fb->_Xmax - fb->_Xmin; + ch = fb->_Ymax - fb->_Ymin; + + if (cw == 0 || ch == 0) + return; + + GLuint buf; + all = (cw == fb->Width && ch == fb->Height); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLbitfield bufBit = 1 << buf; + struct intel_renderbuffer *irb; + drm_intel_bo *write_buffer; + int x1, y1, x2, y2; + uint32_t clear_val; + uint32_t BR13, CMD; + int pitch, cpp; + drm_intel_bo *aper_array[2]; + + if (!(mask & bufBit)) + continue; + + /* OK, clear this renderbuffer */ + irb = intel_get_renderbuffer(fb, buf); + write_buffer = intel_region_buffer(intel, irb->region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + x1 = cx + irb->region->draw_x; + y1 = cy + irb->region->draw_y; + x2 = cx + cw + irb->region->draw_x; + y2 = cy + ch + irb->region->draw_y; + + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb->region->buffer, (pitch * cpp), + x1, y1, x2 - x1, y2 - y1); + + BR13 = 0xf0 << 16; + CMD = XY_COLOR_BLT_CMD; + + /* Setup the blit command */ + if (cpp == 4) { + BR13 |= BR13_8888; + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + if (mask & BUFFER_BIT_DEPTH) + CMD |= XY_BLT_WRITE_RGB; + if (mask & BUFFER_BIT_STENCIL) + CMD |= XY_BLT_WRITE_ALPHA; + } else { + /* clearing RGBA */ + CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + } + } else { + ASSERT(cpp == 2); + BR13 |= BR13_565; + } - if (fb->Name == 0) { - /* clearing a window */ + assert(irb->region->tiling != I915_TILING_Y); - /* flip top to bottom */ - clear.x1 = cx + x_off; - clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; +#ifndef I915 + if (irb->region->tiling != I915_TILING_NONE) { + CMD |= XY_DST_TILED; + pitch /= 4; } - else { - /* clearing FBO */ - assert(num_cliprects == 1); - assert(cliprects == &intel->fboRect); - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - /* no change to mask */ +#endif + BR13 |= (pitch * cpp); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clear_val = clear_depth; + } else { + uint8_t clear[4]; + GLclampf *color = ctx->Color.ClearColor; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + switch (irb->Base.Format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + clear_val = PACK_COLOR_8888(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_RGB565: + clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB4444: + clear_val = PACK_COLOR_4444(clear[3], clear[0], + clear[1], clear[2]); + break; + case MESA_FORMAT_ARGB1555: + clear_val = PACK_COLOR_1555(clear[3], clear[0], + clear[1], clear[2]); + break; + default: + _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", + irb->Base.Format); + clear_val = 0; + } } - for (i = 0; i < num_cliprects; i++) { - const drm_clip_rect_t *box = &cliprects[i]; - drm_clip_rect_t b; - GLuint buf; - GLuint clearMask = mask; /* use copy, since we modify it below */ - GLboolean all = (cw == fb->Width && ch == fb->Height); - - if (!all) { - intel_intersect_cliprects(&b, &clear, box); - } - else { - b = *box; - } - - if (b.x1 >= b.x2 || b.y1 >= b.y2) - continue; - - if (0) - _mesa_printf("clear %d,%d..%d,%d, mask %x\n", - b.x1, b.y1, b.x2, b.y2, mask); - - /* Loop over all renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { - const GLbitfield bufBit = 1 << buf; - if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { - /* OK, clear this renderbuffer */ - struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, buf); - dri_bo *write_buffer = - intel_region_buffer(intel, irb->region, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - int x1 = b.x1 + irb->region->draw_x; - int y1 = b.y1 + irb->region->draw_y; - int x2 = b.x2 + irb->region->draw_x; - int y2 = b.y2 + irb->region->draw_y; - - GLuint clearVal; - GLint pitch, cpp; - GLuint BR13, CMD; - - pitch = irb->region->pitch; - cpp = irb->region->cpp; - - DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n", - __FUNCTION__, - irb->region->buffer, (pitch * cpp), - x1, y1, x2 - x1, y2 - y1); - - BR13 = 0xf0 << 16; - CMD = XY_COLOR_BLT_CMD; - - /* Setup the blit command */ - if (cpp == 4) { - BR13 |= BR13_8888; - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - if (clearMask & BUFFER_BIT_DEPTH) - CMD |= XY_BLT_WRITE_RGB; - if (clearMask & BUFFER_BIT_STENCIL) - CMD |= XY_BLT_WRITE_ALPHA; - } - else { - /* clearing RGBA */ - CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; - } - } - else { - ASSERT(cpp == 2); - BR13 |= BR13_565; - } - - assert(irb->region->tiling != I915_TILING_Y); + assert(x1 < x2); + assert(y1 < y2); -#ifndef I915 - if (irb->region->tiling != I915_TILING_NONE) { - CMD |= XY_DST_TILED; - pitch /= 4; - } -#endif - BR13 |= (pitch * cpp); - - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - clearVal = clear_depth; - } - else { - uint8_t clear[4]; - GLclampf *color = ctx->Color.ClearColor; - - CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); - - switch (irb->Base.Format) { - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_XRGB8888: - clearVal = PACK_COLOR_8888(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_RGB565: - clearVal = PACK_COLOR_565(clear[0], clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB4444: - clearVal = PACK_COLOR_4444(clear[3], clear[0], - clear[1], clear[2]); - break; - case MESA_FORMAT_ARGB1555: - clearVal = PACK_COLOR_1555(clear[3], clear[0], - clear[1], clear[2]); - break; - default: - _mesa_problem(ctx, "Unexpected renderbuffer format: %d\n", - irb->Base.Format); - clearVal = 0; - } - } - - /* - _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", - buf, irb->Base.Name); - */ - - assert(x1 < x2); - assert(y1 < y2); - - BEGIN_BATCH(6); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((y1 << 16) | x1); - OUT_BATCH((y2 << 16) | x2); - OUT_RELOC(write_buffer, - I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, - 0); - OUT_BATCH(clearVal); - ADVANCE_BATCH(); - clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ - } - } + /* do space check before going any further */ + aper_array[0] = intel->batch->buf; + aper_array[1] = write_buffer; + + if (drm_intel_bufmgr_check_aperture_space(aper_array, + ARRAY_SIZE(aper_array)) != 0) { + intel_batchbuffer_flush(intel->batch); } + + BEGIN_BATCH(6); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y1 << 16) | x1); + OUT_BATCH((y2 << 16) | x2); + OUT_RELOC(write_buffer, + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, + 0); + OUT_BATCH(clear_val); + ADVANCE_BATCH(); + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) + mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + else + mask &= ~bufBit; /* turn off bit, for faster loop exit */ } } diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 7c4b79f743..2f03e45005 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -28,45 +28,7 @@ #include "intel_context.h" #include "intel_buffers.h" #include "intel_fbo.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" #include "main/framebuffer.h" -#include "drirenderbuffer.h" - - -/** - * XXX move this into a new dri/common/cliprects.c file. - */ -GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dst, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b) -{ - GLint bx = b->x1; - GLint by = b->y1; - GLint bw = b->x2 - bx; - GLint bh = b->y2 - by; - - if (bx < a->x1) - bw -= a->x1 - bx, bx = a->x1; - if (by < a->y1) - bh -= a->y1 - by, by = a->y1; - if (bx + bw > a->x2) - bw = a->x2 - bx; - if (by + bh > a->y2) - bh = a->y2 - by; - if (bw <= 0) - return GL_FALSE; - if (bh <= 0) - return GL_FALSE; - - dst->x1 = bx; - dst->y1 = by; - dst->x2 = bx + bw; - dst->y2 = by + bh; - - return GL_TRUE; -} /** * Return pointer to current color drawing region, or NULL. @@ -96,24 +58,6 @@ intel_readbuf_region(struct intel_context *intel) return NULL; } -void -intel_get_cliprects(struct intel_context *intel, - struct drm_clip_rect **cliprects, - unsigned int *num_cliprects, - int *x_off, int *y_off) -{ - intel->fboRect.x1 = 0; - intel->fboRect.y1 = 0; - intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; - intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; - - *cliprects = &intel->fboRect; - *num_cliprects = 1; - *x_off = 0; - *y_off = 0; -} - - /** * Check if we're about to draw into the front color buffer. * If so, set the intel->front_buffer_dirty field to true. diff --git a/src/mesa/drivers/dri/intel/intel_buffers.h b/src/mesa/drivers/dri/intel/intel_buffers.h index d7800f2ca2..abb86aade6 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.h +++ b/src/mesa/drivers/dri/intel/intel_buffers.h @@ -35,12 +35,6 @@ struct intel_context; struct intel_framebuffer; - -extern GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dest, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b); - extern struct intel_region *intel_readbuf_region(struct intel_context *intel); extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index 956f2339ff..ca78681538 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -33,12 +33,9 @@ #include "intel_context.h" #include "intel_blit.h" -#include "intel_chipset.h" #include "intel_clear.h" #include "intel_fbo.h" -#include "intel_pixel.h" #include "intel_regions.h" -#include "intel_batchbuffer.h" #define FILE_DEBUG_FLAG DEBUG_BLIT diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 13a28f0419..0adee6131e 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/context.h" -#include "main/arrayobj.h" #include "main/extensions.h" #include "main/framebuffer.h" #include "main/imports.h" @@ -52,13 +51,11 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" -#include "intel_decode.h" #include "intel_bufmgr.h" #include "intel_screen.h" #include "drirenderbuffer.h" #include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ #ifndef INTEL_DEBUG @@ -70,8 +67,6 @@ int INTEL_DEBUG = (0); #define DRIVER_DATE_GEM "GEM " DRIVER_DATE -static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); - static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -378,6 +373,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } } + drawable->validBuffers = GL_TRUE; driUpdateFramebufferSize(&intel->ctx, drawable); } @@ -461,7 +457,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) intel->vtbl.invalidate_state( intel, new_state ); } -static void +void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) { struct intel_context *intel = intel_context(ctx); @@ -523,7 +519,8 @@ intel_glFlush(GLcontext *ctx) * 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 (intel->first_post_swapbuffers_batch != NULL) { + if (!intel->using_dri2_swapbuffers && + intel->first_post_swapbuffers_batch != NULL) { drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); intel->first_post_swapbuffers_batch = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h index c7b7235836..36abef470a 100644 --- a/src/mesa/drivers/dri/intel/intel_context.h +++ b/src/mesa/drivers/dri/intel/intel_context.h @@ -107,7 +107,6 @@ struct intel_context void (*finish_batch) (struct intel_context * intel); void (*new_batch) (struct intel_context * intel); void (*emit_invarient_state) (struct intel_context * intel); - void (*note_fence) (struct intel_context *intel, GLuint fence); void (*update_texture_state) (struct intel_context * intel); void (*render_start) (struct intel_context * intel); @@ -125,40 +124,6 @@ struct intel_context void (*invalidate_state) (struct intel_context *intel, GLuint new_state); - - /* Metaops: - */ - void (*install_meta_state) (struct intel_context * intel); - void (*leave_meta_state) (struct intel_context * intel); - - void (*meta_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); - - void (*meta_color_mask) (struct intel_context * intel, GLboolean); - - void (*meta_stencil_replace) (struct intel_context * intel, - GLuint mask, GLuint clear); - - void (*meta_depth_replace) (struct intel_context * intel); - - void (*meta_texture_blend_replace) (struct intel_context * intel); - - void (*meta_no_stencil_write) (struct intel_context * intel); - void (*meta_no_depth_write) (struct intel_context * intel); - void (*meta_no_texture) (struct intel_context * intel); - - void (*meta_import_pixel_state) (struct intel_context * intel); - void (*meta_frame_buffer_texture) (struct intel_context *intel, - GLint xoff, GLint yoff); - - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - dri_bo * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); - void (*assert_not_dirty) (struct intel_context *intel); void (*debug_batch)(struct intel_context *intel); @@ -187,6 +152,7 @@ struct intel_context struct intel_batchbuffer *batch; drm_intel_bo *first_post_swapbuffers_batch; GLboolean no_batch_wrap; + GLboolean using_dri2_swapbuffers; struct { @@ -273,10 +239,6 @@ struct intel_context GLboolean use_texture_tiling; GLboolean use_early_z; - drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ - - drm_clip_rect_t draw_rect; - drm_clip_rect_t scissor_rect; int driFd; @@ -412,6 +374,7 @@ extern GLboolean intelInitContext(struct intel_context *intel, extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); +extern void intel_flush(GLcontext * ctx, GLboolean needs_mi_flush); extern void intelInitDriverFunctions(struct dd_function_table *functions); diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c index 5ac5ce10af..84c8d013e3 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.c +++ b/src/mesa/drivers/dri/intel/intel_extensions.c @@ -48,6 +48,7 @@ #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex +#define need_GL_EXT_draw_buffers2 #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_framebuffer_blit @@ -154,12 +155,14 @@ static const struct dri_extension brw_extensions[] = { { "GL_ARB_fragment_program_shadow", NULL }, { "GL_ARB_fragment_shader", NULL }, { "GL_ARB_framebuffer_object", GL_ARB_framebuffer_object_functions}, + { "GL_ARB_half_float_vertex", NULL }, { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, { "GL_ARB_point_sprite", NULL }, { "GL_ARB_seamless_cube_map", NULL }, { "GL_ARB_shadow", NULL }, { "GL_MESA_texture_signed_rgba", NULL }, { "GL_ARB_texture_non_power_of_two", NULL }, + { "GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions }, { "GL_EXT_shadow_funcs", NULL }, { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, { "GL_EXT_texture_sRGB", NULL }, diff --git a/src/mesa/drivers/dri/intel/intel_extensions.h b/src/mesa/drivers/dri/intel/intel_extensions.h index 1d1c97a4a9..e78e07356e 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.h +++ b/src/mesa/drivers/dri/intel/intel_extensions.h @@ -32,5 +32,8 @@ extern void intelInitExtensions(GLcontext *ctx); +extern void +intelFlushDrawable(__DRIdrawable *drawable); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 82e4150c6a..cb5a341050 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -29,7 +29,6 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "intel_tex_layout.h" -#include "intel_chipset.h" #ifndef I915 #include "brw_state.h" #endif diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index 5142f3dcd9..cb088e4032 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -29,14 +29,7 @@ #include "main/state.h" #include "main/bufferobj.h" #include "main/context.h" -#include "main/enable.h" -#include "main/matrix.h" -#include "main/texstate.h" -#include "main/varray.h" -#include "main/viewport.h" #include "swrast/swrast.h" -#include "shader/arbprogram.h" -#include "shader/program.h" #include "intel_context.h" #include "intel_pixel.h" diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 85e5ad2cdd..1e517650b7 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -37,7 +37,6 @@ #include "main/polygon.h" #include "main/state.h" #include "main/teximage.h" -#include "main/texenv.h" #include "main/texobj.h" #include "main/texstate.h" #include "main/texparam.h" @@ -46,7 +45,6 @@ #include "main/enable.h" #include "main/viewport.h" #include "shader/arbprogram.h" -#include "glapi/dispatch.h" #include "swrast/swrast.h" #include "intel_screen.h" @@ -54,7 +52,6 @@ #include "intel_batchbuffer.h" #include "intel_blit.h" #include "intel_regions.h" -#include "intel_buffer_objects.h" #include "intel_buffers.h" #include "intel_pixel.h" #include "intel_reg.h" @@ -106,7 +103,7 @@ static void set_bit( GLubyte *dest, GLuint bit ) } /* Extract a rectangle's worth of data from the bitmap. Called - * per-cliprect. + * per chunk of HW-sized bitmap. */ static GLuint get_bitmap_rect(GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, @@ -191,11 +188,12 @@ do_blit_bitmap( GLcontext *ctx, GLfloat tmpColor[4]; GLubyte ubcolor[4]; GLuint color; - unsigned int num_cliprects; - drm_clip_rect_t *cliprects; - int x_off, y_off; GLsizei bitmap_width = width; GLsizei bitmap_height = height; + GLint px, py; + GLuint stipple[32]; + GLint orig_dstx = dstx; + GLint orig_dsty = dsty; /* Update draw buffer bounds */ _mesa_update_state(ctx); @@ -236,90 +234,60 @@ do_blit_bitmap( GLcontext *ctx, if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F)) return GL_FALSE; - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects != 0) { - GLuint i; - GLint orig_dstx = dstx; - GLint orig_dsty = dsty; - - /* Clip to buffer bounds and scissor. */ - if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, - fb->_Xmax, fb->_Ymax, - &dstx, &dsty, &width, &height)) - goto out; - - dstx = x_off + dstx; - dsty = y_off + y_flip(fb, dsty, height); - - for (i = 0; i < num_cliprects; i++) { - int box_x, box_y, box_w, box_h; - GLint px, py; - GLuint stipple[32]; - - box_x = dstx; - box_y = dsty; - box_w = width; - box_h = height; - - /* Clip to drawable cliprect */ - if (!_mesa_clip_to_region(cliprects[i].x1, - cliprects[i].y1, - cliprects[i].x2, - cliprects[i].y2, - &box_x, &box_y, &box_w, &box_h)) - continue; + /* Clip to buffer bounds and scissor. */ + if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, + fb->_Xmax, fb->_Ymax, + &dstx, &dsty, &width, &height)) + goto out; + + dsty = y_flip(fb, dsty, height); #define DY 32 #define DX 32 - /* Then, finally, chop it all into chunks that can be - * digested by hardware: + /* Chop it all into chunks that can be digested by hardware: */ + for (py = 0; py < height; py += DY) { + for (px = 0; px < width; px += DX) { + int h = MIN2(DY, height - py); + int w = MIN2(DX, width - px); + GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; + GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + * + * Have to translate destination coordinates back into source + * coordinates. */ - for (py = 0; py < box_h; py += DY) { - for (px = 0; px < box_w; px += DX) { - int h = MIN2(DY, box_h - py); - int w = MIN2(DX, box_w - px); - GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8; - GLenum logic_op = ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY; - - assert(sz <= sizeof(stipple)); - memset(stipple, 0, sz); - - /* May need to adjust this when padding has been introduced in - * sz above: - * - * Have to translate destination coordinates back into source - * coordinates. - */ - if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, - bitmap, - -orig_dstx + (box_x + px - x_off), - -orig_dsty + y_flip(fb, - box_y + py - y_off, h), - w, h, - (GLubyte *)stipple, - 8, - fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) - continue; - - if (!intelEmitImmediateColorExpandBlit(intel, - dst->cpp, - (GLubyte *)stipple, - sz, - color, - dst->pitch, - dst->buffer, - 0, - dst->tiling, - box_x + px, - box_y + py, - w, h, - logic_op)) { - return GL_FALSE; - } - } - } + if (get_bitmap_rect(bitmap_width, bitmap_height, unpack, + bitmap, + -orig_dstx + (dstx + px), + -orig_dsty + y_flip(fb, dsty + py, h), + w, h, + (GLubyte *)stipple, + 8, + fb->Name == 0 ? GL_TRUE : GL_FALSE) == 0) + continue; + + if (!intelEmitImmediateColorExpandBlit(intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color, + dst->pitch, + dst->buffer, + 0, + dst->tiling, + dstx + px, + dsty + py, + w, h, + logic_op)) { + return GL_FALSE; + } } } out: diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index e002516cdd..87c293d8b0 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -112,9 +112,10 @@ do_blit_copypixels(GLcontext * ctx, struct intel_region *src = copypix_src_region(intel, type); struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_framebuffer *read_fb = ctx->ReadBuffer; - unsigned int num_cliprects; - drm_clip_rect_t *cliprects; - int x_off, y_off; + GLint orig_dstx; + GLint orig_dsty; + GLint orig_srcx; + GLint orig_srcy; if (type == GL_DEPTH || type == GL_STENCIL) { if (INTEL_DEBUG & DEBUG_FALLBACKS) @@ -135,94 +136,56 @@ do_blit_copypixels(GLcontext * ctx, if (!src || !dst) return GL_FALSE; - - intelFlush(&intel->ctx); - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - if (num_cliprects != 0) { - GLint delta_x; - GLint delta_y; - GLint orig_dstx; - GLint orig_dsty; - GLint orig_srcx; - GLint orig_srcy; - GLuint i; - - /* XXX: We fail to handle different inversion between read and draw framebuffer. */ - - /* Clip to destination buffer. */ - orig_dstx = dstx; - orig_dsty = dsty; - if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, - fb->_Xmax, fb->_Ymax, - &dstx, &dsty, &width, &height)) - goto out; - /* Adjust src coords for our post-clipped destination origin */ - srcx += dstx - orig_dstx; - srcy += dsty - orig_dsty; - - /* Clip to source buffer. */ - orig_srcx = srcx; - orig_srcy = srcy; - if (!_mesa_clip_to_region(0, 0, - read_fb->Width, read_fb->Height, - &srcx, &srcy, &width, &height)) - goto out; - /* Adjust dst coords for our post-clipped source origin */ - dstx += srcx - orig_srcx; - dsty += srcy - orig_srcy; - - /* Convert from GL to hardware coordinates: - */ - if (fb->Name == 0) { - /* copypixels to a system framebuffer */ - dstx = x_off + dstx; - dsty = y_off + (fb->Height - dsty - height); - } else { - /* copypixels to a user framebuffer object */ - dstx = x_off + dstx; - dsty = y_off + dsty; - } - - /* Flip source Y if it's a system framebuffer. */ - if (read_fb->Name == 0) { - srcx = intel->driReadDrawable->x + srcx; - srcy = intel->driReadDrawable->y + (fb->Height - srcy - height); - } - - delta_x = srcx - dstx; - delta_y = srcy - dsty; - /* Could do slightly more clipping: Eg, take the intersection of - * the destination cliprects and the read drawable cliprects - * - * This code will not overwrite other windows, but will - * introduce garbage when copying from obscured window regions. - */ - for (i = 0; i < num_cliprects; i++) { - GLint clip_x = dstx; - GLint clip_y = dsty; - GLint clip_w = width; - GLint clip_h = height; - - if (!_mesa_clip_to_region(cliprects[i].x1, cliprects[i].y1, - cliprects[i].x2, cliprects[i].y2, - &clip_x, &clip_y, &clip_w, &clip_h)) - continue; - - if (!intel_region_copy(intel, - dst, 0, clip_x, clip_y, - src, 0, clip_x + delta_x, clip_y + delta_y, - clip_w, clip_h, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY)) { - DBG("%s: blit failure\n", __FUNCTION__); - return GL_FALSE; - } - } + /* XXX: We fail to handle different inversion between read and draw framebuffer. */ + + /* Clip to destination buffer. */ + orig_dstx = dstx; + orig_dsty = dsty; + if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, + fb->_Xmax, fb->_Ymax, + &dstx, &dsty, &width, &height)) + goto out; + /* Adjust src coords for our post-clipped destination origin */ + srcx += dstx - orig_dstx; + srcy += dsty - orig_dsty; + + /* Clip to source buffer. */ + orig_srcx = srcx; + orig_srcy = srcy; + if (!_mesa_clip_to_region(0, 0, + read_fb->Width, read_fb->Height, + &srcx, &srcy, &width, &height)) + goto out; + /* Adjust dst coords for our post-clipped source origin */ + dstx += srcx - orig_srcx; + dsty += srcy - orig_srcy; + + /* Convert from GL to hardware coordinates: */ + if (fb->Name == 0) { + /* copypixels to a system framebuffer */ + dsty = fb->Height - dsty - height; + } else { + /* copypixels to a user framebuffer object */ + dsty = dsty; } -out: + /* Flip source Y if it's a system framebuffer. */ + if (read_fb->Name == 0) + srcy = fb->Height - srcy - height; + + if (!intel_region_copy(intel, + dst, 0, dstx, dsty, + src, 0, srcx, srcy, + width, height, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY)) { + DBG("%s: blit failure\n", __FUNCTION__); + return GL_FALSE; + } + +out: intel_check_front_buffer_rendering(intel); DBG("%s: success\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index b870e9315e..10177228bd 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -46,10 +46,6 @@ #include "drivers/common/meta.h" #include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" #include "intel_pixel.h" #include "intel_fbo.h" diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c index 9c0fdc6067..a98e8e16c2 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_read.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c @@ -36,7 +36,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_blit.h" #include "intel_buffers.h" #include "intel_regions.h" @@ -65,99 +64,6 @@ * any case. */ - -static GLboolean -do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - struct intel_region *dest_region) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawable *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); - return GL_FALSE; - } - - if (intel->driDrawable->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); - - - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); - - intel->vtbl.leave_meta_state(intel); - } - - intel_region_wait_fence(ctx, dest_region); /* required by GL */ - return GL_TRUE; -#endif - - return GL_FALSE; -} - - - - static GLboolean do_blit_readpixels(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height, @@ -169,6 +75,9 @@ do_blit_readpixels(GLcontext * ctx, struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; + drm_intel_bo *dst_buffer; + GLboolean all; + GLint dst_x, dst_y; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -209,56 +118,42 @@ do_blit_readpixels(GLcontext * ctx, return GL_FALSE; } else { - rowLength = -rowLength; + if (ctx->ReadBuffer->Name == 0) + rowLength = -rowLength; } dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height, format, type, 0, 0, 0); + if (!_mesa_clip_copytexsubimage(ctx, + &dst_x, &dst_y, + &x, &y, + &width, &height)) { + return GL_TRUE; + } - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects are correct. - */ - intelFlush(&intel->ctx); - - if (intel->driReadDrawable->numClipRects) { - GLboolean all = (width * height * src->cpp == dst->Base.Size && - x == 0 && dst_offset == 0); - - dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - __DRIdrawable *dPriv = intel->driReadDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = dPriv->x + x; - src_rect.y1 = dPriv->y + dPriv->h - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; + all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + dst_x = 0; + dst_y = 0; + dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; + if (ctx->ReadBuffer->Name == 0) + y = ctx->ReadBuffer->Height - (y + height); - if (!intelEmitCopyBlit(intel, - src->cpp, - src->pitch, src->buffer, 0, src->tiling, - rowLength, dst_buffer, dst_offset, GL_FALSE, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, - GL_COPY)) { - return GL_FALSE; - } - } + if (!intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, src->tiling, + rowLength, dst_buffer, dst_offset, GL_FALSE, + x, y, + dst_x, dst_y, + width, height, + GL_COPY)) { + return GL_FALSE; } if (INTEL_DEBUG & DEBUG_PIXEL) @@ -282,15 +177,6 @@ intelReadPixels(GLcontext * ctx, (ctx, x, y, width, height, format, type, pack, pixels)) return; -#ifdef I915 - if (do_texture_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; -#else - (void)do_blit_readpixels; - (void)do_texture_readpixels; -#endif - if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index 61aefa01b8..301c3df17c 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -48,7 +48,6 @@ #include "intel_buffer_objects.h" #include "intel_bufmgr.h" #include "intel_batchbuffer.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_REGION @@ -443,6 +442,7 @@ intel_region_attach_pbo(struct intel_context *intel, region->pbo->region = region; dri_bo_reference(buffer); region->buffer = buffer; + region->tiling = I915_TILING_NONE; } diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 5165716e09..c9ef1647a3 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -37,15 +37,11 @@ #include "intel_buffers.h" #include "intel_bufmgr.h" #include "intel_chipset.h" -#include "intel_extensions.h" #include "intel_fbo.h" -#include "intel_regions.h" #include "intel_screen.h" -#include "intel_span.h" #include "intel_tex.h" #include "i915_drm.h" -#include "i830_dri.h" #define DRI_CONF_TEXTURE_TILING(def) \ DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \ @@ -113,10 +109,42 @@ static const __DRItexBufferExtension intelTexBufferExtension = { intelSetTexBuffer2, }; +static void +intelDRI2Flush(__DRIdrawable *drawable) +{ + struct intel_context *intel = drawable->driContextPriv->driverPrivate; + + if (intel->gen < 4) + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); +} + +static void +intelDRI2FlushInvalidate(__DRIdrawable *drawable) +{ + struct intel_context *intel = drawable->driContextPriv->driverPrivate; + + intel->using_dri2_swapbuffers = GL_TRUE; + + intelDRI2Flush(drawable); + drawable->validBuffers = GL_FALSE; + + intel_update_renderbuffers(intel->driContext, drawable); +} + +static const struct __DRI2flushExtensionRec intelFlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + intelDRI2Flush, + intelDRI2FlushInvalidate, +}; + static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelFlushExtension.base, NULL }; @@ -174,7 +202,7 @@ intelCreateBuffer(__DRIscreen * driScrnPriv, if (!fb) return GL_FALSE; - _mesa_initialize_framebuffer(fb, mesaVis); + _mesa_initialize_window_framebuffer(fb, mesaVis); if (mesaVis->redBits == 5) rgbFormat = MESA_FORMAT_RGB565; @@ -311,11 +339,10 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp) intelScreenPrivate *intelScreen; GLenum fb_format[3]; GLenum fb_type[3]; - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ + static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + GLX_NONE, GLX_SWAP_UNDEFINED_OML, + GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML }; uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; int color; diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c index 605734d8e5..d925cb9997 100644 --- a/src/mesa/drivers/dri/intel/intel_span.c +++ b/src/mesa/drivers/dri/intel/intel_span.c @@ -259,36 +259,20 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define DBG 0 #define LOCAL_VARS \ - struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ - unsigned int num_cliprects; \ - struct drm_clip_rect *cliprects; \ - int x_off, y_off; \ + int minx = 0, miny = 0; \ + int maxx = ctx->DrawBuffer->Width; \ + int maxy = ctx->DrawBuffer->Height; \ int pitch = irb->region->pitch * irb->region->cpp; \ void *buf = irb->region->buffer->virtual; \ GLuint p; \ (void) p; \ (void)buf; (void)pitch; /* unused for non-gttmap. */ \ - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); -/* XXX FBO: this is identical to the macro in spantmp2.h except we get - * the cliprect info from the context, not the driDrawable. - * Move this into spantmp2.h someday. - */ -#define HW_CLIPLOOP() \ - do { \ - int _nc = num_cliprects; \ - while ( _nc-- ) { \ - int minx = cliprects[_nc].x1 - x_off; \ - int miny = cliprects[_nc].y1 - y_off; \ - int maxx = cliprects[_nc].x2 - x_off; \ - int maxy = cliprects[_nc].y2 - y_off; - -#if 0 - }} -#endif +#define HW_CLIPLOOP() +#define HW_ENDCLIPLOOP() #define Y_FLIP(_y) ((_y) * yScale + yBias) @@ -297,9 +281,9 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #define HW_UNLOCK() /* Convenience macros to avoid typing the swizzle argument over and over */ -#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) -#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) -#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off) +#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X), (_Y)) +#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X), (_Y)) +#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X), (_Y)) /* r5g6b5 color span and pixel functions */ #define INTEL_PIXEL_FMT GL_RGB @@ -342,18 +326,15 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb, #include "intel_spantmp.h" #define LOCAL_DEPTH_VARS \ - struct intel_context *intel = intel_context(ctx); \ struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\ - unsigned int num_cliprects; \ - struct drm_clip_rect *cliprects; \ - int x_off, y_off; \ + int minx = 0, miny = 0; \ + int maxx = ctx->DrawBuffer->Width; \ + int maxy = ctx->DrawBuffer->Height; \ int pitch = irb->region->pitch * irb->region->cpp; \ void *buf = irb->region->buffer->virtual; \ (void)buf; (void)pitch; /* unused for non-gttmap. */ \ - intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off); - #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS diff --git a/src/mesa/drivers/dri/intel/intel_state.c b/src/mesa/drivers/dri/intel/intel_state.c index aefae53eb2..c5ef909dbf 100644 --- a/src/mesa/drivers/dri/intel/intel_state.c +++ b/src/mesa/drivers/dri/intel/intel_state.c @@ -35,8 +35,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_regions.h" -#include "swrast/swrast.h" int intel_translate_shadow_compare_func(GLenum func) diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index d8e71093c4..d67451cf8e 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -36,7 +36,6 @@ #include "intel_screen.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_buffers.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" @@ -114,8 +113,6 @@ do_copy_texsubimage(struct intel_context *intel, drm_intel_bo *dst_bo = intel_region_buffer(intel, intelImage->mt->region, INTEL_WRITE_PART); - const GLint orig_x = x; - const GLint orig_y = y; GLuint image_x, image_y; GLshort src_pitch; @@ -125,9 +122,6 @@ do_copy_texsubimage(struct intel_context *intel, intelImage->face, 0, &image_x, &image_y); - /* Update dst for clipped src. Need to also clip the source rect. */ - dstx += x - orig_x; - dsty += y - orig_y; /* Can't blit to tiled buffers with non-tile-aligned offset. */ if (intelImage->mt->region->tiling == I915_TILING_Y) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c index a7c6c45ffe..7be5231eae 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_format.c +++ b/src/mesa/drivers/dri/intel/intel_tex_format.c @@ -1,6 +1,5 @@ #include "intel_context.h" #include "intel_tex.h" -#include "intel_chipset.h" #include "main/enums.h" diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 307669f87e..6402141170 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -7,7 +7,6 @@ #include "main/convolve.h" #include "main/context.h" #include "main/formats.h" -#include "main/image.h" #include "main/texcompress.h" #include "main/texstore.h" #include "main/texgetimage.h" @@ -178,6 +177,7 @@ check_pbo_format(GLint internalFormat, switch (internalFormat) { case 4: case GL_RGBA: + case GL_RGBA8: return (format == GL_BGRA && (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) && @@ -187,6 +187,11 @@ check_pbo_format(GLint internalFormat, return (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && mesa_format == MESA_FORMAT_RGB565); + case 1: + case GL_LUMINANCE: + return (format == GL_LUMINANCE && + type == GL_UNSIGNED_BYTE && + mesa_format == MESA_FORMAT_L8); case GL_YCBCR_MESA: return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); default: @@ -241,7 +246,8 @@ try_pbo_upload(struct intel_context *intel, if (!intelEmitCopyBlit(intel, intelImage->mt->cpp, src_stride, src_buffer, src_offset, GL_FALSE, - dst_stride, dst_buffer, 0, GL_FALSE, + dst_stride, dst_buffer, 0, + intelImage->mt->region->tiling, 0, 0, dst_x, dst_y, width, height, GL_COPY)) { return GL_FALSE; @@ -742,7 +748,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, if (!intelObj) return; - intel_update_renderbuffers(pDRICtx, dPriv); + if (!dPriv->validBuffers) + intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); /* If the region isn't set, then intel_update_renderbuffers was unable diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c index c9a24ac398..ed5c5d896b 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_validate.c +++ b/src/mesa/drivers/dri/intel/intel_tex_validate.c @@ -2,10 +2,8 @@ #include "main/macros.h" #include "intel_context.h" -#include "intel_batchbuffer.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "intel_chipset.h" #define FILE_DEBUG_FLAG DEBUG_TEXTURE diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 3b4ef7ffd8..11bce31b12 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -33,8 +33,6 @@ #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" -#include "main/extensions.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_dd.c b/src/mesa/drivers/dri/mach64/mach64_dd.c index e400e9a918..ca713e2de5 100644 --- a/src/mesa/drivers/dri/mach64/mach64_dd.c +++ b/src/mesa/drivers/dri/mach64/mach64_dd.c @@ -31,12 +31,9 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" #include "mach64_dd.h" #include "main/context.h" -#include "main/framebuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_lock.c b/src/mesa/drivers/dri/mach64/mach64_lock.c index 8653c77da5..1a95a8f619 100644 --- a/src/mesa/drivers/dri/mach64/mach64_lock.c +++ b/src/mesa/drivers/dri/mach64/mach64_lock.c @@ -32,7 +32,6 @@ #include "mach64_context.h" #include "mach64_state.h" #include "mach64_lock.h" -#include "mach64_tex.h" #include "drirenderbuffer.h" #if DEBUG_LOCKING diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 1ed3b0b70e..5cbfb85627 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -31,8 +31,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_tris.h" -#include "mach64_vb.h" #include "mach64_span.h" #include "main/context.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_span.c b/src/mesa/drivers/dri/mach64/mach64_span.c index b4ba2a41c9..0c52c0c88c 100644 --- a/src/mesa/drivers/dri/mach64/mach64_span.c +++ b/src/mesa/drivers/dri/mach64/mach64_span.c @@ -31,7 +31,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" #include "mach64_span.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c index df7cbc8670..b9093b5a13 100644 --- a/src/mesa/drivers/dri/mach64/mach64_state.c +++ b/src/mesa/drivers/dri/mach64/mach64_state.c @@ -36,7 +36,6 @@ #include "mach64_vb.h" #include "mach64_tex.h" -#include "main/context.h" #include "main/enums.h" #include "main/colormac.h" #include "swrast/swrast.h" @@ -44,8 +43,6 @@ #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/mach64/mach64_tex.c b/src/mesa/drivers/dri/mach64/mach64_tex.c index 6627d3c38a..1bce967d58 100644 --- a/src/mesa/drivers/dri/mach64/mach64_tex.c +++ b/src/mesa/drivers/dri/mach64/mach64_tex.c @@ -31,13 +31,8 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" -#include "mach64_tris.h" #include "mach64_tex.h" -#include "main/context.h" -#include "main/macros.h" #include "main/simple_list.h" #include "main/enums.h" #include "main/texstore.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_texmem.c b/src/mesa/drivers/dri/mach64/mach64_texmem.c index b97e9eec25..46cee4320d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texmem.c +++ b/src/mesa/drivers/dri/mach64/mach64_texmem.c @@ -37,10 +37,7 @@ #include "main/imports.h" #include "mach64_context.h" -#include "mach64_state.h" #include "mach64_ioctl.h" -#include "mach64_vb.h" -#include "mach64_tris.h" #include "mach64_tex.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_texstate.c b/src/mesa/drivers/dri/mach64/mach64_texstate.c index df0a09a5c1..adf774ec19 100644 --- a/src/mesa/drivers/dri/mach64/mach64_texstate.c +++ b/src/mesa/drivers/dri/mach64/mach64_texstate.c @@ -36,8 +36,6 @@ #include "mach64_context.h" #include "mach64_ioctl.h" -#include "mach64_state.h" -#include "mach64_vb.h" #include "mach64_tris.h" #include "mach64_tex.h" diff --git a/src/mesa/drivers/dri/mach64/mach64_vb.c b/src/mesa/drivers/dri/mach64/mach64_vb.c index e58812e902..00da835376 100644 --- a/src/mesa/drivers/dri/mach64/mach64_vb.c +++ b/src/mesa/drivers/dri/mach64/mach64_vb.c @@ -42,7 +42,6 @@ #include "mach64_vb.h" #include "mach64_ioctl.h" #include "mach64_tris.h" -#include "mach64_state.h" #define MACH64_TEX1_BIT 0x1 diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index f835cb8bd6..e7813b6372 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -35,7 +35,6 @@ #include "mga_drm.h" #include "mga_xmesa.h" #include "main/context.h" -#include "main/matrix.h" #include "main/simple_list.h" #include "main/imports.h" #include "main/framebuffer.h" @@ -64,7 +63,6 @@ #include "utils.h" #include "vblank.h" -#include "main/extensions.h" #include "drirenderbuffer.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c index 3b1ea22b60..2f23c0e514 100644 --- a/src/mesa/drivers/dri/mga/mgadd.c +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -32,11 +32,6 @@ #include "mgacontext.h" #include "mgadd.h" -#include "mgastate.h" -#include "mgaspan.h" -#include "mgatex.h" -#include "mgatris.h" -#include "mgavb.h" #include "mga_xmesa.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index 8ce5d802ab..259358eaa3 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -42,10 +42,7 @@ #include "mgacontext.h" #include "mgadd.h" #include "mgastate.h" -#include "mgatex.h" -#include "mgavb.h" #include "mgaioctl.h" -#include "mgatris.h" #include "vblank.h" diff --git a/src/mesa/drivers/dri/mga/mgarender.c b/src/mesa/drivers/dri/mga/mgarender.c index 517c3b8f82..8b8fc485d3 100644 --- a/src/mesa/drivers/dri/mga/mgarender.c +++ b/src/mesa/drivers/dri/mga/mgarender.c @@ -48,7 +48,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mgacontext.h" #include "mgatris.h" -#include "mgastate.h" #include "mgaioctl.h" #include "mgavb.h" diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c index 62a9317cd4..ca3dd4b013 100644 --- a/src/mesa/drivers/dri/mga/mgatex.c +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -40,11 +40,8 @@ #include "mgacontext.h" #include "mgatex.h" #include "mgaregs.h" -#include "mgatris.h" #include "mgaioctl.h" -#include "swrast/swrast.h" - #include "xmlpool.h" /** diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c index c1bcd4b853..4c58c3bdb0 100644 --- a/src/mesa/drivers/dri/mga/mgatris.c +++ b/src/mesa/drivers/dri/mga/mgatris.c @@ -38,7 +38,6 @@ #include "mgaioctl.h" #include "mgatris.h" #include "mgavb.h" -#include "mgastate.h" static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim ); diff --git a/src/mesa/drivers/dri/mga/mgavb.c b/src/mesa/drivers/dri/mga/mgavb.c index 1c635b23a6..def5109863 100644 --- a/src/mesa/drivers/dri/mga/mgavb.c +++ b/src/mesa/drivers/dri/mga/mgavb.c @@ -39,7 +39,6 @@ #include "main/colormac.h" #include "tnl/t_context.h" -#include "swrast_setup/swrast_setup.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 0000000000..7c895a2e4b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -0,0 +1,59 @@ +# src/mesa/drivers/dri/nouveau/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +CFLAGS += $(shell pkg-config libdrm libdrm_nouveau --cflags) +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + +LIBNAME = nouveau_vieux_dri.so + +MINIGLX_SOURCES = + +DRIVER_SOURCES = \ + nouveau_screen.c \ + nouveau_context.c \ + nouveau_fbo.c \ + nouveau_driver.c \ + nouveau_state.c \ + nouveau_bufferobj.c \ + nouveau_span.c \ + nouveau_bo_state.c \ + nouveau_texture.c \ + nouveau_surface.c \ + nv04_context.c \ + nv04_screen.c \ + nv04_render.c \ + nv04_state_fb.c \ + nv04_state_raster.c \ + nv04_state_tex.c \ + nv04_state_frag.c \ + nv04_surface.c \ + nv10_context.c \ + nv10_screen.c \ + nv10_render.c \ + nv10_state_fb.c \ + nv10_state_polygon.c \ + nv10_state_raster.c \ + nv10_state_tex.c \ + nv10_state_frag.c \ + nv10_state_tnl.c \ + nv20_context.c \ + nv20_screen.c \ + nv20_render.c \ + nv20_state_fb.c \ + nv20_state_polygon.c \ + nv20_state_raster.c \ + nv20_state_tex.c \ + nv20_state_tnl.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c new file mode 100644 index 0000000000..664632f407 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" + +static GLboolean +nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, + uint32_t flags) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_pushbuf *push = chan->pushbuf; + uint32_t packet; + + if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND) + nouveau_grobj_autobind(m->gr); + + if (MARK_RING(chan, 2, 2)) + return GL_FALSE; + + push->remaining -= 2; + packet = (m->gr->subc << 13) | (1 << 18) | m->mthd; + + if (flags) { + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, + packet, 0, flags | + (m->flags & (NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | + NOUVEAU_BO_RDWR)), + 0, 0)) + goto fail; + } else { + *(push->cur++) = packet; + } + + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data, + m->data2, flags | m->flags, + m->vor, m->tor)) + goto fail; + + return GL_TRUE; + +fail: + MARK_UNDO(chan); + return GL_FALSE; +} + +static GLboolean +nouveau_bo_context_grow(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_marker *marker = bctx->marker; + int allocated = bctx->allocated + 1; + + marker = realloc(marker, allocated * sizeof(struct nouveau_bo_marker)); + if (!marker) + return GL_FALSE; + + bctx->marker = marker; + bctx->allocated = allocated; + + return GL_TRUE; +} + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + struct nouveau_bo_marker *m; + + if (bctx->count == bctx->allocated) { + if (!nouveau_bo_context_grow(bctx)) + goto fail; + } + + m = &bctx->marker[bctx->count]; + + *m = (struct nouveau_bo_marker) { + .gr = gr, + .mthd = mthd, + .data = data, + .data2 = data2, + .vor = vor, + .tor = tor, + .flags = flags, + }; + nouveau_bo_ref(bo, &m->bo); + + s->count++; + bctx->count++; + + if (!nouveau_bo_marker_emit(bctx->ctx, m, 0)) + goto fail; + + return GL_TRUE; + +fail: + nouveau_bo_context_reset(bctx); + return GL_FALSE; +} + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + int i; + + for (i = 0; i < bctx->count; i++) + nouveau_bo_ref(NULL, &bctx->marker[i].bo); + + s->count -= bctx->count; + bctx->count = 0; +} + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) { + if (!nouveau_bo_marker_emit(ctx, &bctx->marker[j], + NOUVEAU_BO_DUMMY)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +void +nouveau_bo_state_init(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) + s->context[i].ctx = ctx; +} + +void +nouveau_bo_state_destroy(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) + nouveau_bo_ref(NULL, &bctx->marker[j].bo); + + if (bctx->marker) + free(bctx->marker); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h new file mode 100644 index 0000000000..da0a3a5c6f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_BO_STATE_H__ +#define __NOUVEAU_BO_STATE_H__ + +enum { + NOUVEAU_BO_CONTEXT_FRAMEBUFFER = 0, + NOUVEAU_BO_CONTEXT_LMA_DEPTH, + NOUVEAU_BO_CONTEXT_SURFACE, + NOUVEAU_BO_CONTEXT_TEXTURE0, + NOUVEAU_BO_CONTEXT_TEXTURE1, + NOUVEAU_BO_CONTEXT_TEXTURE2, + NOUVEAU_BO_CONTEXT_TEXTURE3, + NOUVEAU_BO_CONTEXT_VERTEX, + NUM_NOUVEAU_BO_CONTEXT +}; + +struct nouveau_bo_marker { + struct nouveau_grobj *gr; + uint32_t mthd; + + struct nouveau_bo *bo; + uint32_t data; + uint32_t data2; + uint32_t vor; + uint32_t tor; + uint32_t flags; +}; + +struct nouveau_bo_context { + GLcontext *ctx; + + struct nouveau_bo_marker *marker; + int allocated; + int count; +}; + +struct nouveau_bo_state { + struct nouveau_bo_context context[NUM_NOUVEAU_BO_CONTEXT]; + int count; +}; + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags); + +#define nouveau_bo_markl(bctx, gr, mthd, bo, data, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, data, 0, 0, 0, \ + flags | NOUVEAU_BO_LOW); + +#define nouveau_bo_marko(bctx, gr, mthd, bo, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, 0, 0, \ + context_chan(ctx)->vram->handle, \ + context_chan(ctx)->gart->handle, \ + flags | NOUVEAU_BO_OR); + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx); + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx); + +void +nouveau_bo_state_init(GLcontext *ctx); + +void +nouveau_bo_state_destroy(GLcontext *ctx); + +#define __context_bctx(ctx, i) \ + ({ \ + struct nouveau_context *nctx = to_nouveau_context(ctx); \ + struct nouveau_bo_context *bctx = &nctx->bo.context[i]; \ + nouveau_bo_context_reset(bctx); \ + bctx; \ + }) +#define context_bctx(ctx, s) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s) +#define context_bctx_i(ctx, s, i) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s##0 + (i)) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c new file mode 100644 index 0000000000..1118b96de1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_bufferobj.h" +#include "nouveau_context.h" + +#include "main/bufferobj.h" + +static struct gl_buffer_object * +nouveau_bufferobj_new(GLcontext *ctx, GLuint buffer, GLenum target) +{ + struct nouveau_bufferobj *nbo; + + nbo = CALLOC_STRUCT(nouveau_bufferobj); + if (!nbo) + return NULL; + + _mesa_initialize_buffer_object(&nbo->base, buffer, target); + + return &nbo->base; +} + +static void +nouveau_bufferobj_del(GLcontext *ctx, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_ref(NULL, &nbo->bo); + FREE(nbo); +} + +static GLboolean +nouveau_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size, + const GLvoid *data, GLenum usage, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + int ret; + + obj->Size = size; + obj->Usage = usage; + + nouveau_bo_ref(NULL, &nbo->bo); + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, + size, &nbo->bo); + assert(!ret); + + if (data) { + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map, data, size); + nouveau_bo_unmap(nbo->bo); + } + + return GL_TRUE; +} + +static void +nouveau_bufferobj_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map + offset, data, size); + nouveau_bo_unmap(nbo->bo); +} + +static void +nouveau_bufferobj_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_RD); + _mesa_memcpy(data, nbo->bo->map + offset, size); + nouveau_bo_unmap(nbo->bo); +} + +static void * +nouveau_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, + struct gl_buffer_object *obj) +{ + return ctx->Driver.MapBufferRange(ctx, target, 0, obj->Size, access, + obj); +} + +static void * +nouveau_bufferobj_map_range(GLcontext *ctx, GLenum target, GLintptr offset, + GLsizeiptr length, GLenum access, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + uint32_t flags = 0; + + assert(!obj->Pointer); + + if (!nbo->bo) + return NULL; + + if (access == GL_READ_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_RD; + if (access == GL_WRITE_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_WR; + + nouveau_bo_map_range(nbo->bo, offset, length, flags); + + obj->Pointer = nbo->bo->map; + obj->Offset = offset; + obj->Length = length; + obj->AccessFlags = access; + + return obj->Pointer; +} + +static GLboolean +nouveau_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + assert(obj->Pointer); + + nouveau_bo_unmap(nbo->bo); + + obj->Pointer = NULL; + obj->Offset = 0; + obj->Length = 0; + obj->AccessFlags = 0; + + return GL_TRUE; +} + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions) +{ + functions->NewBufferObject = nouveau_bufferobj_new; + functions->DeleteBuffer = nouveau_bufferobj_del; + functions->BufferData = nouveau_bufferobj_data; + functions->BufferSubData = nouveau_bufferobj_subdata; + functions->GetBufferSubData = nouveau_bufferobj_get_subdata; + functions->MapBuffer = nouveau_bufferobj_map; + functions->MapBufferRange = nouveau_bufferobj_map_range; + functions->UnmapBuffer = nouveau_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h new file mode 100644 index 0000000000..acfc4cb9a9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_BUFFEROBJ_H__ +#define __NOUVEAU_BUFFEROBJ_H__ + +struct nouveau_bufferobj { + struct gl_buffer_object base; + struct nouveau_bo *bo; +}; +#define to_nouveau_bufferobj(x) ((struct nouveau_bufferobj *)(x)) + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c new file mode 100644 index 0000000000..b87b8dbdd0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_bufferobj.h" +#include "nouveau_fbo.h" + +#include "main/dd.h" +#include "main/framebuffer.h" +#include "main/light.h" +#include "main/state.h" +#include "drivers/common/meta.h" +#include "drivers/common/driverfuncs.h" +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_fog_coord + +#include "main/remap_helper.h" + +static const struct dri_extension nouveau_extensions[] = { + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_env_add", NULL }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { NULL, NULL } +}; + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx) +{ + __DRIscreen *dri_screen = dri_ctx->driScreenPriv; + struct nouveau_screen *screen = dri_screen->private; + struct nouveau_context *nctx; + GLcontext *ctx; + + ctx = screen->driver->context_create(screen, visual, share_ctx); + if (!ctx) + return GL_FALSE; + + nctx = to_nouveau_context(ctx); + nctx->dri_context = dri_ctx; + dri_ctx->driverPrivate = ctx; + + return GL_TRUE; +} + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct dd_function_table functions; + + nctx->screen = screen; + nctx->fallback = HWTNL; + + /* Initialize the function pointers */ + _mesa_init_driver_functions(&functions); + nouveau_driver_functions_init(&functions); + nouveau_bufferobj_functions_init(&functions); + nouveau_texture_functions_init(&functions); + nouveau_fbo_functions_init(&functions); + + /* Initialize the mesa context */ + _mesa_initialize_context(ctx, visual, share_ctx, &functions, NULL); + + nouveau_state_init(ctx); + nouveau_bo_state_init(ctx); + _mesa_meta_init(ctx); + _swrast_CreateContext(ctx); + _vbo_CreateContext(ctx); + _tnl_CreateContext(ctx); + nouveau_span_functions_init(ctx); + _mesa_allow_light_in_model(ctx, GL_FALSE); + + /* Enable any supported extensions */ + driInitExtensions(ctx, nouveau_extensions, GL_TRUE); + + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontext *dri_ctx) +{ + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context == nctx) + nctx->screen->context = NULL; + + _tnl_DestroyContext(ctx); + _vbo_DestroyContext(ctx); + _swrast_DestroyContext(ctx); + _mesa_meta_free(ctx); + nouveau_bo_state_destroy(ctx); + context_drv(ctx)->context_destroy(ctx); +} + +static void +nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + unsigned int *stamp) +{ + struct nouveau_context *nctx = context->driverPrivate; + GLcontext *ctx = &nctx->base; + __DRIscreen *screen = context->driScreenPriv; + struct gl_framebuffer *fb = drawable->driverPrivate; + unsigned int attachments[10]; + __DRIbuffer *buffers = NULL; + int i = 0, count, ret; + + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (fb->Visual.doubleBufferMode) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (fb->Visual.haveDepthBuffer && fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + else if (fb->Visual.haveDepthBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH; + else if (fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, &drawable->h, + attachments, i, &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + for (i = 0; i < count; i++) { + struct gl_renderbuffer *rb; + struct nouveau_surface *s; + uint32_t old_handle; + int index; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + case __DRI_BUFFER_FAKE_FRONT_LEFT: + index = BUFFER_FRONT_LEFT; + break; + case __DRI_BUFFER_BACK_LEFT: + index = BUFFER_BACK_LEFT; + break; + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_DEPTH_STENCIL: + index = BUFFER_DEPTH; + break; + case __DRI_BUFFER_STENCIL: + index = BUFFER_STENCIL; + break; + default: + assert(0); + } + + rb = fb->Attachment[index].Renderbuffer; + s = &to_nouveau_renderbuffer(rb)->surface; + + s->width = drawable->w; + s->height = drawable->h; + s->pitch = buffers[i].pitch; + s->cpp = buffers[i].cpp; + + /* Don't bother to reopen the bo if it happens to be + * the same. */ + if (s->bo) { + ret = nouveau_bo_handle_get(s->bo, &old_handle); + assert(!ret); + } + + if (!s->bo || old_handle != buffers[i].name) { + nouveau_bo_ref(NULL, &s->bo); + ret = nouveau_bo_handle_ref(context_dev(ctx), + buffers[i].name, &s->bo); + assert(!ret); + + context_dirty(ctx, FRAMEBUFFER); + } + } + + _mesa_resize_framebuffer(ctx, fb, drawable->w, drawable->h); +} + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw, + __DRIdrawable *dri_read) +{ + if (dri_ctx) { + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context != nctx) { + nctx->screen->context = nctx; + BITSET_ONES(nctx->dirty); + } + + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable.d_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); + + /* Pass it down to mesa. */ + _mesa_make_current(ctx, dri_draw->driverPrivate, + dri_read->driverPrivate); + _mesa_update_state(ctx); + + FIRE_RING(context_chan(ctx)); + + } else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx) +{ + return GL_TRUE; +} + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nctx->fallback = MAX2(HWTNL, mode); + + if (mode < SWRAST) + nouveau_state_emit(ctx); + else + FIRE_RING(context_chan(ctx)); +} + +void +nouveau_validate_framebuffer(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + /* Someone's planning to draw something really soon. */ + nctx->drawable.dirty = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h new file mode 100644 index 0000000000..9812963e1a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_bo_state.h" +#include "nouveau_render.h" + +#include "main/bitset.h" + +enum nouveau_fallback { + HWTNL = 0, + SWTNL, + SWRAST, +}; + +struct nouveau_drawable_state { + GLboolean dirty; + unsigned int d_stamp; + unsigned int r_stamp; +}; + +struct nouveau_context { + GLcontext base; + __DRIcontext *dri_context; + struct nouveau_screen *screen; + + BITSET_DECLARE(dirty, MAX_NOUVEAU_STATE); + enum nouveau_fallback fallback; + + struct nouveau_bo_state bo; + struct nouveau_render_state render; + struct nouveau_drawable_state drawable; +}; + +#define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx)) + +#define context_dev(ctx) \ + (to_nouveau_context(ctx)->screen->device) +#define context_chipset(ctx) \ + (context_dev(ctx)->chipset) +#define context_chan(ctx) \ + (to_nouveau_context(ctx)->screen->chan) +#define context_eng3d(ctx) \ + (to_nouveau_context(ctx)->screen->eng3d) +#define context_drv(ctx) \ + (to_nouveau_context(ctx)->screen->driver) +#define context_dirty(ctx, s) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s) +#define context_dirty_i(ctx, s, i) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s##0 + i) + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx); + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx); + +void +nouveau_context_destroy(__DRIcontext *dri_ctx); + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, + __DRIdrawable *ddraw, + __DRIdrawable *rdraw); + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx); + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode); + +void +nouveau_validate_framebuffer(GLcontext *ctx); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c new file mode 100644 index 0000000000..bf0e20ca81 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" + +#include "drivers/common/meta.h" + +static const GLubyte * +nouveau_get_string(GLcontext *ctx, GLenum name) +{ + static char buffer[128]; + char hardware_name[32]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Nouveau"; + + case GL_RENDERER: + sprintf(hardware_name, "nv%02X", context_chipset(ctx)); + driGetRendererString(buffer, hardware_name, DRIVER_DATE, 0); + + return (GLubyte *)buffer; + default: + return NULL; + } +} + +static void +nouveau_flush(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + + FIRE_RING(chan); + + if (ctx->DrawBuffer->Name == 0 && + ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + __DRIscreen *screen = nctx->screen->dri_screen; + __DRIdri2LoaderExtension *dri2 = screen->dri2.loader; + __DRIdrawable *drawable = nctx->dri_context->driDrawablePriv; + + dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); + } + + nctx->drawable.dirty = GL_FALSE; +} + +static void +nouveau_finish(GLcontext *ctx) +{ + nouveau_flush(ctx); +} + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + int x, y, w, h; + int i, buf; + + nouveau_validate_framebuffer(ctx); + get_scissors(fb, &x, &y, &w, &h); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct nouveau_surface *s; + unsigned mask, value; + + buf = buffers & (1 << i); + if (!buf) + continue; + + s = &to_nouveau_renderbuffer( + fb->Attachment[i].Renderbuffer->Wrapped)->surface; + + if (buf & BUFFER_BITS_COLOR) { + mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]); + value = pack_rgba_f(s->format, ctx->Color.ClearColor); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~buf; + + } else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { + mask = pack_zs_i(s->format, + (buffers & BUFFER_BIT_DEPTH && + ctx->Depth.Mask) ? ~0 : 0, + (buffers & BUFFER_BIT_STENCIL && + ctx->Stencil.WriteMask[0]) ? ~0 : 0); + value = pack_zs_f(s->format, + ctx->Depth.Clear, + ctx->Stencil.Clear); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + } + } + + if (buffers) + _mesa_meta_Clear(ctx, buffers); +} + +void +nouveau_driver_functions_init(struct dd_function_table *functions) +{ + functions->GetString = nouveau_get_string; + functions->Flush = nouveau_flush; + functions->Finish = nouveau_finish; + functions->Clear = nouveau_clear; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h new file mode 100644 index 0000000000..3b4d332d74 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_DRIVER_H__ +#define __NOUVEAU_DRIVER_H__ + +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/formats.h" +#include "utils.h" +#include "dri_util.h" + +#undef NDEBUG +#include <assert.h> + +#include "nouveau_device.h" +#include "nouveau_pushbuf.h" +#include "nouveau_grobj.h" +#include "nouveau_channel.h" +#include "nouveau_bo.h" +#include "nouveau_notifier.h" +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_surface.h" + +#define DRIVER_DATE "20091015" +#define DRIVER_AUTHOR "Nouveau" + +struct nouveau_driver { + void (*screen_destroy)(struct nouveau_screen *screen); + + GLcontext *(*context_create)(struct nouveau_screen *screen, + const GLvisual *visual, + GLcontext *share_ctx); + void (*context_destroy)(GLcontext *ctx); + + void (*surface_copy)(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + void (*surface_fill)(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + + nouveau_state_func *emit; + int num_emit; +}; + +#define nouveau_error(format, ...) \ + _mesa_fprintf(stderr, "%s: " format, __func__, ## __VA_ARGS__) + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers); + +void +nouveau_span_functions_init(GLcontext *ctx); + +void +nouveau_driver_functions_init(struct dd_function_table *functions); + +void +nouveau_texture_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c new file mode 100644 index 0000000000..91eade8d63 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/fbobject.h" + +static GLboolean +set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + rb->InternalFormat = internalFormat; + + switch (internalFormat) { + case GL_RGB: + case GL_RGB8: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_XRGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGBA: + case GL_RGBA8: + rb->_BaseFormat = GL_RGBA; + rb->Format = MESA_FORMAT_ARGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGB5: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_RGB565; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z16; + rb->DataType = GL_UNSIGNED_SHORT; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + case GL_STENCIL_INDEX8_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z24_S8; + rb->DataType = GL_UNSIGNED_INT; + s->cpp = 4; + break; + default: + return GL_FALSE; + } + + s->format = rb->Format; + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, + rb->Format, width, height); + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +static void +nouveau_renderbuffer_del(struct gl_renderbuffer *rb) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + nouveau_surface_ref(NULL, s); + FREE(rb); +} + +static struct gl_renderbuffer * +nouveau_renderbuffer_new(GLcontext *ctx, GLuint name) +{ + struct gl_renderbuffer *rb; + + rb = (struct gl_renderbuffer *) + CALLOC_STRUCT(nouveau_renderbuffer); + if (!rb) + return NULL; + + _mesa_init_renderbuffer(rb, name); + + rb->AllocStorage = nouveau_renderbuffer_storage; + rb->Delete = nouveau_renderbuffer_del; + + return rb; +} + +static GLboolean +nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable) +{ + struct gl_renderbuffer *rb; + + rb = nouveau_renderbuffer_new(NULL, 0); + if (!rb) + return NULL; + + rb->AllocStorage = nouveau_renderbuffer_dri_storage; + + if (!set_renderbuffer_format(rb, format)) { + nouveau_renderbuffer_del(rb); + return NULL; + } + + return rb; +} + +static struct gl_framebuffer * +nouveau_framebuffer_new(GLcontext *ctx, GLuint name) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_user_framebuffer(&nfb->base, name); + + return &nfb->base; +} + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_window_framebuffer(&nfb->base, visual); + + return &nfb->base; +} + +static void +nouveau_bind_framebuffer(GLcontext *ctx, GLenum target, + struct gl_framebuffer *dfb, + struct gl_framebuffer *rfb) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + + context_dirty(ctx, FRAMEBUFFER); +} + +static GLenum +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return GL_RGBA8; + case MESA_FORMAT_RGB565: + return GL_RGB5; + default: + assert(0); + } +} + +static void +nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_renderbuffer *rb = att->Renderbuffer; + struct gl_texture_image *ti = + att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + int ret; + + /* Allocate a renderbuffer object for the texture if we + * haven't already done so. */ + if (!rb) { + rb = nouveau_renderbuffer_new(ctx, 0); + assert(rb); + + rb->AllocStorage = NULL; + _mesa_reference_renderbuffer(&att->Renderbuffer, rb); + } + + /* Update the renderbuffer fields from the texture. */ + ret = set_renderbuffer_format(rb, get_tex_format(ti)); + assert(ret); + + rb->Width = ti->Width; + rb->Height = ti->Height; + nouveau_surface_ref(&to_nouveau_teximage(ti)->surface, + &to_nouveau_renderbuffer(rb)->surface); + + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_finish_render_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) +{ + struct nouveau_renderbuffer *nrb + = to_nouveau_renderbuffer(att->Renderbuffer); + + texture_dirty(att->Texture); + nouveau_surface_ref(NULL, &nrb->surface); +} + +void +nouveau_fbo_functions_init(struct dd_function_table *functions) +{ + functions->NewFramebuffer = nouveau_framebuffer_new; + functions->NewRenderbuffer = nouveau_renderbuffer_new; + functions->BindFramebuffer = nouveau_bind_framebuffer; + functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer; + functions->RenderTexture = nouveau_render_texture; + functions->FinishRenderTexture = nouveau_finish_render_texture; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h new file mode 100644 index 0000000000..5ae984bbff --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_FBO_H__ +#define __NOUVEAU_FBO_H__ + +struct nouveau_framebuffer { + struct gl_framebuffer base; + struct nouveau_bo *lma_bo; +}; +#define to_nouveau_framebuffer(x) ((struct nouveau_framebuffer *)(x)) + +struct nouveau_renderbuffer { + struct gl_renderbuffer base; + struct nouveau_surface surface; +}; +#define to_nouveau_renderbuffer(x) ((struct nouveau_renderbuffer *)(x)) + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual); + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable); + +void +nouveau_fbo_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h new file mode 100644 index 0000000000..00007a9a35 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_GLDEFS_H__ +#define __NOUVEAU_GLDEFS_H__ + +static inline unsigned +nvgl_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x0000; + case GL_ONE: + return 0x0001; + case GL_SRC_COLOR: + return 0x0300; + case GL_ONE_MINUS_SRC_COLOR: + return 0x0301; + case GL_SRC_ALPHA: + return 0x0302; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x0303; + case GL_DST_ALPHA: + return 0x0304; + case GL_ONE_MINUS_DST_ALPHA: + return 0x0305; + case GL_DST_COLOR: + return 0x0306; + case GL_ONE_MINUS_DST_COLOR: + return 0x0307; + case GL_SRC_ALPHA_SATURATE: + return 0x0308; + case GL_CONSTANT_COLOR: + return 0x8001; + case GL_ONE_MINUS_CONSTANT_COLOR: + return 0x8002; + case GL_CONSTANT_ALPHA: + return 0x8003; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return 0x8004; + default: + assert(0); + } +} + +static inline unsigned +nvgl_blend_eqn(unsigned eqn) +{ + switch (eqn) { + case GL_FUNC_ADD: + return 0x8006; + case GL_MIN: + return 0x8007; + case GL_MAX: + return 0x8008; + case GL_FUNC_SUBTRACT: + return 0x800a; + case GL_FUNC_REVERSE_SUBTRACT: + return 0x800b; + default: + assert(0); + } +} + +static inline unsigned +nvgl_logicop_func(unsigned func) +{ + switch (func) { + case GL_CLEAR: + return 0x1500; + case GL_NOR: + return 0x1508; + case GL_AND_INVERTED: + return 0x1504; + case GL_COPY_INVERTED: + return 0x150c; + case GL_AND_REVERSE: + return 0x1502; + case GL_INVERT: + return 0x150a; + case GL_XOR: + return 0x1506; + case GL_NAND: + return 0x150e; + case GL_AND: + return 0x1501; + case GL_EQUIV: + return 0x1509; + case GL_NOOP: + return 0x1505; + case GL_OR_INVERTED: + return 0x150d; + case GL_COPY: + return 0x1503; + case GL_OR_REVERSE: + return 0x150b; + case GL_OR: + return 0x1507; + case GL_SET: + return 0x150f; + default: + assert(0); + } +} + +static inline unsigned +nvgl_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x0200; + case GL_LESS: + return 0x0201; + case GL_EQUAL: + return 0x0202; + case GL_LEQUAL: + return 0x0203; + case GL_GREATER: + return 0x0204; + case GL_NOTEQUAL: + return 0x0205; + case GL_GEQUAL: + return 0x0206; + case GL_ALWAYS: + return 0x0207; + default: + assert(0); + } +} + +static inline unsigned +nvgl_polygon_mode(unsigned mode) +{ + switch (mode) { + case GL_POINT: + return 0x1b00; + case GL_LINE: + return 0x1b01; + case GL_FILL: + return 0x1b02; + default: + assert(0); + } +} + +static inline unsigned +nvgl_stencil_op(unsigned op) +{ + switch (op) { + case GL_ZERO: + return 0x0000; + case GL_INVERT: + return 0x150a; + case GL_KEEP: + return 0x1e00; + case GL_REPLACE: + return 0x1e01; + case GL_INCR: + return 0x1e02; + case GL_DECR: + return 0x1e03; + case GL_INCR_WRAP_EXT: + return 0x8507; + case GL_DECR_WRAP_EXT: + return 0x8508; + default: + assert(0); + } +} + +static inline unsigned +nvgl_primitive(unsigned prim) +{ + switch (prim) { + case GL_POINTS: + return 0x0001; + case GL_LINES: + return 0x0002; + case GL_LINE_LOOP: + return 0x0003; + case GL_LINE_STRIP: + return 0x0004; + case GL_TRIANGLES: + return 0x0005; + case GL_TRIANGLE_STRIP: + return 0x0006; + case GL_TRIANGLE_FAN: + return 0x0007; + case GL_QUADS: + return 0x0008; + case GL_QUAD_STRIP: + return 0x0009; + case GL_POLYGON: + return 0x000a; + default: + assert(0); + } +} + +static inline unsigned +nvgl_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + case GL_CLAMP: + return 0x5; + default: + assert(0); + } +} + +static inline unsigned +nvgl_filter_mode(unsigned filter) +{ + switch (filter) { + case GL_NEAREST: + return 0x1; + case GL_LINEAR: + return 0x2; + case GL_NEAREST_MIPMAP_NEAREST: + return 0x3; + case GL_LINEAR_MIPMAP_NEAREST: + return 0x4; + case GL_NEAREST_MIPMAP_LINEAR: + return 0x5; + case GL_LINEAR_MIPMAP_LINEAR: + return 0x6; + default: + assert(0); + } +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render.h b/src/mesa/drivers/dri/nouveau/nouveau_render.h new file mode 100644 index 0000000000..bff0ccfd76 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_RENDER_H__ +#define __NOUVEAU_RENDER_H__ + +#include "vbo/vbo_context.h" + +struct nouveau_array_state; + +typedef void (*dispatch_t)(GLcontext *, unsigned int, int, unsigned int); +typedef unsigned (*extract_u_t)(struct nouveau_array_state *a, int i, int j); +typedef float (*extract_f_t)(struct nouveau_array_state *a, int i, int j); + +struct nouveau_attr_info { + int vbo_index; + int imm_method; + int imm_fields; + + void (*emit)(GLcontext *, struct nouveau_array_state *, const void *); +}; + +struct nouveau_array_state { + int attr; + int stride, fields, type; + + struct nouveau_bo *bo; + unsigned offset; + const void *buf; + + extract_u_t extract_u; + extract_f_t extract_f; +}; + +#define RENDER_SCRATCH_COUNT 32 +#define RENDER_SCRATCH_SIZE 64*1024 + +struct nouveau_scratch_state { + struct nouveau_bo *bo[RENDER_SCRATCH_COUNT]; + + int index; + int offset; + void *buf; +}; + +struct nouveau_swtnl_state { + struct nouveau_bo *vbo; + void *buf; + unsigned vertex_count; + GLenum primitive; +}; + +struct nouveau_render_state { + enum { + VBO, + IMM + } mode; + + struct nouveau_array_state ib; + struct nouveau_array_state attrs[VERT_ATTRIB_MAX]; + + /* Maps a HW VBO index or IMM emission order to an index in + * the attrs array above (or -1 if unused). */ + int map[VERT_ATTRIB_MAX]; + + int attr_count; + int vertex_size; + + struct nouveau_scratch_state scratch; + struct nouveau_swtnl_state swtnl; +}; + +#define to_render_state(ctx) (&to_nouveau_context(ctx)->render) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render_t.c b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c new file mode 100644 index 0000000000..c0505781cf --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +/* + * Vertex submission helper definitions shared among the software and + * hardware TnL paths. + */ + +#include "nouveau_gldefs.h" + +#include "main/light.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define OUT_INDICES_L(r, i, d, n) \ + BATCH_OUT_L(i + d, n); \ + (void)r +#define OUT_INDICES_I16(r, i, d, n) \ + BATCH_OUT_I16(r->ib.extract_u(&r->ib, 0, i) + d, \ + r->ib.extract_u(&r->ib, 0, i + 1) + d) +#define OUT_INDICES_I32(r, i, d, n) \ + BATCH_OUT_I32(r->ib.extract_u(&r->ib, 0, i) + d) + +/* + * Emit <n> vertices using BATCH_OUT_<out>, MAX_OUT_<out> at a time, + * grouping them in packets of length MAX_PACKET. + * + * out: hardware index data type. + * ctx: GL context. + * start: element within the index buffer to begin with. + * delta: integer correction that will be added to each index found in + * the index buffer. + */ +#define EMIT_VBO(out, ctx, start, delta, n) do { \ + struct nouveau_render_state *render = to_render_state(ctx); \ + int npush = n; \ + \ + while (npush) { \ + int npack = MIN2(npush, MAX_PACKET * MAX_OUT_##out); \ + npush -= npack; \ + \ + BATCH_PACKET_##out((npack + MAX_OUT_##out - 1) \ + / MAX_OUT_##out); \ + while (npack) { \ + int nout = MIN2(npack, MAX_OUT_##out); \ + npack -= nout; \ + \ + OUT_INDICES_##out(render, start, delta, \ + nout); \ + start += nout; \ + } \ + } \ + } while (0) + +/* + * Emit the <n>-th element of the array <a>, using IMM_OUT. + */ +#define EMIT_IMM(ctx, a, n) do { \ + struct nouveau_attr_info *info = \ + &TAG(vertex_attrs)[(a)->attr]; \ + int m; \ + \ + if (!info->emit) { \ + IMM_PACKET(info->imm_method, info->imm_fields); \ + \ + for (m = 0; m < (a)->fields; m++) \ + IMM_OUT((a)->extract_f(a, n, m)); \ + \ + for (m = (a)->fields; m < info->imm_fields; m++) \ + IMM_OUT(((float []){0, 0, 0, 1})[m]); \ + \ + } else { \ + info->emit(ctx, a, (a)->buf + n * (a)->stride); \ + } \ + } while (0) + +/* + * Select an appropriate dispatch function for the given index buffer. + */ +static void +get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) +{ + if (!a->fields) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(L, ctx, start, delta, n); + }; + + *dispatch = f; + + } else if (a->type == GL_UNSIGNED_INT) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n); + }; + + *dispatch = f; + + } else { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n & 1); + EMIT_VBO(I16, ctx, start, delta, n & ~1); + }; + + *dispatch = f; + } +} + +/* + * Select appropriate element extraction functions for the given + * array. + */ +static void +get_array_extract(struct nouveau_array_state *a, + extract_u_t *extract_u, extract_f_t *extract_f) +{ +#define EXTRACT(in_t, out_t, k) \ + ({ \ + auto out_t f(struct nouveau_array_state *, int, int); \ + out_t f(struct nouveau_array_state *a, int i, int j) { \ + in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ + \ + return (out_t)x / (k); \ + }; \ + f; \ + }); + + switch (a->type) { + case GL_BYTE: + *extract_u = EXTRACT(char, unsigned, 1); + *extract_f = EXTRACT(char, float, SCHAR_MAX); + break; + case GL_UNSIGNED_BYTE: + *extract_u = EXTRACT(unsigned char, unsigned, 1); + *extract_f = EXTRACT(unsigned char, float, UCHAR_MAX); + break; + case GL_SHORT: + *extract_u = EXTRACT(short, unsigned, 1); + *extract_f = EXTRACT(short, float, SHRT_MAX); + break; + case GL_UNSIGNED_SHORT: + *extract_u = EXTRACT(unsigned short, unsigned, 1); + *extract_f = EXTRACT(unsigned short, float, USHRT_MAX); + break; + case GL_INT: + *extract_u = EXTRACT(int, unsigned, 1); + *extract_f = EXTRACT(int, float, INT_MAX); + break; + case GL_UNSIGNED_INT: + *extract_u = EXTRACT(unsigned int, unsigned, 1); + *extract_f = EXTRACT(unsigned int, float, UINT_MAX); + break; + case GL_FLOAT: + *extract_u = EXTRACT(float, unsigned, 1.0 / UINT_MAX); + *extract_f = EXTRACT(float, float, 1); + break; + + default: + assert(0); + } +} + +/* + * Returns a pointer to a chunk of <size> bytes long GART memory. <bo> + * will be updated with the buffer object the memory is located in. + * + * If <offset> is provided, it will be updated with the offset within + * <bo> of the allocated memory. Otherwise the returned memory will + * always be located right at the beginning of <bo>. + */ +static inline void * +get_scratch_vbo(GLcontext *ctx, unsigned size, struct nouveau_bo **bo, + unsigned *offset) +{ + struct nouveau_scratch_state *scratch = &to_render_state(ctx)->scratch; + void *buf; + + if (scratch->buf && offset && + size <= RENDER_SCRATCH_SIZE - scratch->offset) { + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + buf = scratch->buf + scratch->offset; + *offset = scratch->offset; + scratch->offset += size; + + } else if (size <= RENDER_SCRATCH_SIZE) { + scratch->index = (scratch->index + 1) % RENDER_SCRATCH_COUNT; + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = scratch->buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + scratch->offset = size; + + } else { + nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, 0, size, bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + } + + return buf; +} + +/* + * Returns how many vertices you can draw using <n> pushbuf dwords. + */ +static inline unsigned +get_max_vertices(GLcontext *ctx, const struct _mesa_index_buffer *ib, + unsigned n) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (render->mode == IMM) { + return MAX2(0, n - 4) / (render->vertex_size / 4 + + render->attr_count); + } else { + unsigned max_out; + + if (ib) { + switch (ib->type) { + case GL_UNSIGNED_INT: + max_out = MAX_OUT_I32; + break; + + case GL_UNSIGNED_SHORT: + max_out = MAX_OUT_I16; + break; + + case GL_UNSIGNED_BYTE: + max_out = MAX_OUT_I16; + break; + } + } else { + max_out = MAX_OUT_L; + } + + return MAX2(0, n - 7) * max_out * MAX_PACKET / (1 + MAX_PACKET); + } +} + +#include "nouveau_vbo_t.c" +#include "nouveau_swtnl_t.c" + +static void +TAG(emit_material)(GLcontext *ctx, struct nouveau_array_state *a, + const void *v) +{ + const int attr = a->attr - VERT_ATTRIB_GENERIC0; + const int state = ((int []) { + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS + }) [attr]; + + COPY_4V(ctx->Light.Material.Attrib[attr], (float *)v); + _mesa_update_material(ctx, 1 << attr); + + context_drv(ctx)->emit[state](ctx, state); +} + +static void +TAG(render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nouveau_validate_framebuffer(ctx); + + if (nctx->fallback == HWTNL) + TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); + + if (nctx->fallback == SWTNL) + _tnl_vbo_draw_prims(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); +} + +void +TAG(render_init)(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_scratch_state *scratch = &render->scratch; + int ret, i; + + for (i = 0; i < RENDER_SCRATCH_COUNT; i++) { + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, + 0, RENDER_SCRATCH_SIZE, &scratch->bo[i]); + assert(!ret); + } + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + render->map[i] = -1; + + TAG(swtnl_init)(ctx); + vbo_set_draw_func(ctx, TAG(render_prims)); +} + +void +TAG(render_destroy)(GLcontext *ctx) +{ + TAG(swtnl_destroy)(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..de6328251e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_drmif.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" + +static const __DRIextension *nouveau_screen_extensions[]; + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen); + +static void +nouveau_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) + nouveau_state_emit(&nctx->base); +} + +static const __DRIconfig ** +nouveau_get_configs(void) +{ + __DRIconfig **configs = NULL; + int i; + + const uint8_t depth_bits[] = { 0, 16, 24, 24 }; + const uint8_t stencil_bits[] = { 0, 0, 0, 8 }; + const uint8_t msaa_samples[] = { 0 }; + + const struct { + GLenum format; + GLenum type; + } fb_formats[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML + }; + + for (i = 0; i < Elements(fb_formats); i++) { + __DRIconfig **config; + + config = driCreateConfigs(fb_formats[i].format, + fb_formats[i].type, + depth_bits, stencil_bits, + Elements(depth_bits), + back_buffer_modes, + Elements(back_buffer_modes), + msaa_samples, + Elements(msaa_samples)); + assert(config); + + configs = configs ? driConcatConfigs(configs, config) + : config; + } + + return (const __DRIconfig **)configs; +} + +static const __DRIconfig ** +nouveau_init_screen2(__DRIscreen *dri_screen) +{ + const __DRIconfig **configs; + struct nouveau_screen *screen; + int ret; + + /* Allocate the screen. */ + screen = CALLOC_STRUCT(nouveau_screen); + if (!screen) + return NULL; + + dri_screen->private = screen; + dri_screen->extensions = nouveau_screen_extensions; + screen->dri_screen = dri_screen; + + /* Open the DRM device. */ + ret = nouveau_device_open_existing(&screen->device, 0, dri_screen->fd, + 0); + if (ret) { + nouveau_error("Error opening the DRM device.\n"); + goto fail; + } + + ret = nouveau_channel_alloc(screen->device, 0xbeef0201, 0xbeef0202, + &screen->chan); + if (ret) { + nouveau_error("Error initializing the FIFO.\n"); + goto fail; + } + screen->chan->flush_notify = nouveau_channel_flush_notify; + screen->chan->user_private = screen; + + /* Do the card specific initialization */ + switch (screen->device->chipset & 0xf0) { + case 0x00: + ret = nv04_screen_init(screen); + break; + case 0x10: + ret = nv10_screen_init(screen); + break; + case 0x20: + ret = nv20_screen_init(screen); + break; + default: + assert(0); + } + if (!ret) { + nouveau_error("Error initializing the hardware.\n"); + goto fail; + } + + configs = nouveau_get_configs(); + if (!configs) { + nouveau_error("Error creating the framebuffer configs.\n"); + goto fail; + } + + return configs; +fail: + nouveau_destroy_screen(dri_screen); + return NULL; + +} + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen) +{ + struct nouveau_screen *screen = dri_screen->private; + + if (!screen) + return; + + screen->driver->screen_destroy(screen); + + if (screen->chan) { + screen->chan->flush_notify = NULL; + nouveau_channel_free(&screen->chan); + } + + if (screen->device) + nouveau_device_close(&screen->device); + + FREE(screen); + dri_screen->private = NULL; +} + +static GLboolean +nouveau_create_buffer(__DRIscreen *dri_screen, + __DRIdrawable *drawable, + const __GLcontextModes *visual, + GLboolean is_pixmap) +{ + struct gl_renderbuffer *rb; + struct gl_framebuffer *fb; + GLenum color_format; + + if (is_pixmap) + return GL_FALSE; /* not implemented */ + + if (visual->redBits == 5) + color_format = GL_RGB5; + else if (visual->alphaBits == 0) + color_format = GL_RGB8; + else + color_format = GL_RGBA8; + + fb = nouveau_framebuffer_dri_new(visual); + if (!fb) + return GL_FALSE; + + /* Front buffer. */ + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb); + + /* Back buffer */ + if (visual->doubleBufferMode) { + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb); + } + + /* Depth/stencil buffer. */ + if (visual->depthBits == 24 && visual->stencilBits == 8) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); + + } else if (visual->depthBits == 24) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + + } else if (visual->depthBits == 16) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + } + + /* Software renderbuffers. */ + _mesa_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE, + visual->accumRedBits > 0, + GL_FALSE, GL_FALSE); + + drawable->driverPrivate = fb; + + return GL_TRUE; +} + +static void +nouveau_destroy_buffer(__DRIdrawable *drawable) +{ + _mesa_reference_framebuffer( + (struct gl_framebuffer **)&drawable->driverPrivate, NULL); +} + +static const __DRIextension *nouveau_screen_extensions[] = { + NULL +}; + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen2 = nouveau_init_screen2, + .DestroyScreen = nouveau_destroy_screen, + .CreateBuffer = nouveau_create_buffer, + .DestroyBuffer = nouveau_destroy_buffer, + .CreateContext = nouveau_context_create, + .DestroyContext = nouveau_context_destroy, + .MakeCurrent = nouveau_context_make_current, + .UnbindContext = nouveau_context_unbind, +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driDRI2Extension.base, + NULL +}; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h new file mode 100644 index 0000000000..5d45039b9e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +struct nouveau_context; + +struct nouveau_screen { + __DRIscreen *dri_screen; + + struct nouveau_device *device; + struct nouveau_channel *chan; + + struct nouveau_notifier *ntfy; + struct nouveau_grobj *eng3d; + struct nouveau_grobj *eng3dm; + struct nouveau_grobj *surf3d; + struct nouveau_grobj *m2mf; + struct nouveau_grobj *surf2d; + struct nouveau_grobj *rop; + struct nouveau_grobj *patt; + struct nouveau_grobj *rect; + struct nouveau_grobj *swzsurf; + struct nouveau_grobj *sifm; + + const struct nouveau_driver *driver; + struct nouveau_context *context; +}; + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c new file mode 100644 index 0000000000..dbbbf15b09 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_bo.h" + +#include "swrast/swrast.h" + +#define LOCAL_VARS \ + struct gl_framebuffer *fb = ctx->DrawBuffer; \ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; \ + GLuint p; \ + (void)p; + +#define LOCAL_DEPTH_VARS LOCAL_VARS + +#define HW_LOCK() +#define HW_UNLOCK() + +#define HW_CLIPLOOP() { \ + int minx = 0; \ + int miny = 0; \ + int maxx = fb->Width; \ + int maxy = fb->Height; + +#define HW_ENDCLIPLOOP() } + +#define Y_FLIP(y) (fb->Name ? (y) : rb->Height - 1 - (y)) + +/* RGB565 span functions */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 +#define TAG(x) nouveau_##x##_rgb565 +#define TAG2(x, y) nouveau_##x##_rgb565##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* ARGB8888 span functions */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +#define TAG(x) nouveau_##x##_argb8888 +#define TAG2(x, y) nouveau_##x##_argb8888##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* Z16 span functions */ +#define VALUE_TYPE uint16_t +#define READ_DEPTH(v, x, y) \ + v = *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z16 + +#include "depthtmp.h" + +/* Z24S8 span functions */ +#define VALUE_TYPE uint32_t +#define READ_DEPTH(v, x, y) \ + v = *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z24s8 + +#include "depthtmp.h" + +static void +renderbuffer_map_unmap(struct gl_renderbuffer *rb, GLboolean map) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (map) { + switch (rb->Format) { + case MESA_FORMAT_RGB565: + nouveau_InitPointers_rgb565(rb); + break; + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + nouveau_InitPointers_argb8888(rb); + break; + case MESA_FORMAT_Z16: + nouveau_InitDepthPointers_z16(rb); + break; + case MESA_FORMAT_Z24_S8: + nouveau_InitDepthPointers_z24s8(rb); + break; + default: + assert(0); + } + + nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + } else { + nouveau_bo_unmap(s->bo); + } +} + +static void +texture_unit_map_unmap(GLcontext *ctx, struct gl_texture_unit *u, GLboolean map) +{ + if (!u->_ReallyEnabled) + return; + + if (map) + ctx->Driver.MapTexture(ctx, u->_Current); + else + ctx->Driver.UnmapTexture(ctx, u->_Current); +} + +static void +span_map_unmap(GLcontext *ctx, GLboolean map) +{ + int i; + + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorDrawBuffers[i], map); + + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorReadBuffer, map); + + if (ctx->DrawBuffer->_DepthBuffer) + renderbuffer_map_unmap(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + texture_unit_map_unmap(ctx, &ctx->Texture.Unit[i], map); +} + +static void +nouveau_span_start(GLcontext *ctx) +{ + nouveau_fallback(ctx, SWRAST); + span_map_unmap(ctx, GL_TRUE); +} + +static void +nouveau_span_finish(GLcontext *ctx) +{ + span_map_unmap(ctx, GL_FALSE); + nouveau_fallback(ctx, HWTNL); +} + +void +nouveau_span_functions_init(GLcontext *ctx) +{ + struct swrast_device_driver *swdd = + _swrast_GetDeviceDriverReference(ctx); + + swdd->SpanRenderStart = nouveau_span_start; + swdd->SpanRenderFinish = nouveau_span_finish; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c new file mode 100644 index 0000000000..d727822175 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "swrast/swrast.h" +#include "tnl/tnl.h" + +static void +nouveau_alpha_func(GLcontext *ctx, GLenum func, GLfloat ref) +{ + context_dirty(ctx, ALPHA_FUNC); +} + +static void +nouveau_blend_color(GLcontext *ctx, const GLfloat color[4]) +{ + context_dirty(ctx, BLEND_COLOR); +} + +static void +nouveau_blend_equation_separate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + context_dirty(ctx, BLEND_EQUATION); +} + +static void +nouveau_blend_func_separate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + context_dirty(ctx, BLEND_FUNC); +} + +static void +nouveau_clip_plane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0); +} + +static void +nouveau_color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask) +{ + context_dirty(ctx, COLOR_MASK); +} + +static void +nouveau_color_material(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); +} + +static void +nouveau_cull_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, CULL_FACE); +} + +static void +nouveau_front_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, FRONT_FACE); +} + +static void +nouveau_depth_func(GLcontext *ctx, GLenum func) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_mask(GLcontext *ctx, GLboolean flag) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_range(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + context_dirty(ctx, VIEWPORT); +} + +static void +nouveau_draw_buffer(GLcontext *ctx, GLenum buffer) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_draw_buffers(GLcontext *ctx, GLsizei n, const GLenum *buffers) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + int i; + + switch (cap) { + case GL_ALPHA_TEST: + context_dirty(ctx, ALPHA_FUNC); + break; + case GL_BLEND: + context_dirty(ctx, BLEND_EQUATION); + break; + case GL_COLOR_LOGIC_OP: + context_dirty(ctx, LOGIC_OPCODE); + break; + case GL_COLOR_MATERIAL: + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_COLOR_SUM_EXT: + context_dirty(ctx, FRAG); + break; + case GL_CULL_FACE: + context_dirty(ctx, CULL_FACE); + break; + case GL_DEPTH_TEST: + context_dirty(ctx, DEPTH); + break; + case GL_DITHER: + context_dirty(ctx, DITHER); + break; + case GL_FOG: + context_dirty(ctx, FOG); + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LIGHTING: + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + + for (i = 0; i < MAX_LIGHTS; i++) { + if (ctx->Light.Light[i].Enabled) + context_dirty_i(ctx, LIGHT_SOURCE, i); + } + + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LINE_SMOOTH: + context_dirty(ctx, LINE_MODE); + break; + case GL_NORMALIZE: + context_dirty(ctx, LIGHT_ENABLE); + break; + case GL_POINT_SMOOTH: + context_dirty(ctx, POINT_MODE); + break; + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + case GL_POLYGON_OFFSET_FILL: + context_dirty(ctx, POLYGON_OFFSET); + break; + case GL_POLYGON_SMOOTH: + context_dirty(ctx, POLYGON_MODE); + break; + case GL_SCISSOR_TEST: + context_dirty(ctx, SCISSOR); + break; + case GL_STENCIL_TEST: + context_dirty(ctx, STENCIL_FUNC); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_fog(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, FOG); +} + +static void +nouveau_index_mask(GLcontext *ctx, GLuint mask) +{ + context_dirty(ctx, INDEX_MASK); +} + +static void +nouveau_light(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params) +{ + switch (pname) { + case GL_AMBIENT: + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + break; + case GL_DIFFUSE: + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + break; + case GL_SPECULAR: + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_SPOT_CUTOFF: + case GL_POSITION: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + default: + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + } +} + +static void +nouveau_light_model(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, LIGHT_MODEL); + context_dirty(ctx, MODELVIEW); +} + +static void +nouveau_line_stipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + context_dirty(ctx, LINE_STIPPLE); +} + +static void +nouveau_line_width(GLcontext *ctx, GLfloat width) +{ + context_dirty(ctx, LINE_MODE); +} + +static void +nouveau_logic_opcode(GLcontext *ctx, GLenum opcode) +{ + context_dirty(ctx, LOGIC_OPCODE); +} + +static void +nouveau_point_parameter(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, POINT_PARAMETER); +} + +static void +nouveau_point_size(GLcontext *ctx, GLfloat size) +{ + context_dirty(ctx, POINT_MODE); +} + +static void +nouveau_polygon_mode(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, POLYGON_MODE); +} + +static void +nouveau_polygon_offset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + context_dirty(ctx, POLYGON_OFFSET); +} + +static void +nouveau_polygon_stipple(GLcontext *ctx, const GLubyte *mask) +{ + context_dirty(ctx, POLYGON_STIPPLE); +} + +static void +nouveau_render_mode(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, RENDER_MODE); +} + +static void +nouveau_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, SCISSOR); +} + +static void +nouveau_shade_model(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, SHADE_MODEL); +} + +static void +nouveau_stencil_func_separate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + context_dirty(ctx, STENCIL_FUNC); +} + +static void +nouveau_stencil_mask_separate(GLcontext *ctx, GLenum face, GLuint mask) +{ + context_dirty(ctx, STENCIL_MASK); +} + +static void +nouveau_stencil_op_separate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + context_dirty(ctx, STENCIL_OP); +} + +static void +nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params) +{ + context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit); +} + +static void +nouveau_tex_env(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param) +{ + switch (target) { + case GL_TEXTURE_FILTER_CONTROL_EXT: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + default: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_tex_parameter(GLcontext *ctx, GLenum target, + struct gl_texture_object *t, GLenum pname, + const GLfloat *params) +{ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + case GL_TEXTURE_LOD_BIAS: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + texture_dirty(t); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, VIEWPORT); +} + +void +nouveau_emit_nothing(GLcontext *ctx, int emit) +{ +} + +int +nouveau_next_dirty_state(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + int i = BITSET_FFS(nctx->dirty) - 1; + + if (i < 0 || i >= context_drv(ctx)->num_emit) + return -1; + + return i; +} + +void +nouveau_state_emit(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + const struct nouveau_driver *drv = context_drv(ctx); + int i; + + while ((i = nouveau_next_dirty_state(ctx)) >= 0) { + BITSET_CLEAR(nctx->dirty, i); + drv->emit[i](ctx, i); + } + + BITSET_ZERO(nctx->dirty); + + nouveau_bo_state_emit(ctx); +} + +static void +nouveau_update_state(GLcontext *ctx, GLbitfield new_state) +{ + if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW)) + context_dirty(ctx, PROJECTION); + + if (new_state & _NEW_MODELVIEW) + context_dirty(ctx, MODELVIEW); + + if (new_state & _NEW_CURRENT_ATTRIB && + new_state & _NEW_LIGHT) { + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + } + + _swrast_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + + nouveau_state_emit(ctx); +} + +void +nouveau_state_init(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + ctx->Driver.AlphaFunc = nouveau_alpha_func; + ctx->Driver.BlendColor = nouveau_blend_color; + ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate; + ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate; + ctx->Driver.ClipPlane = nouveau_clip_plane; + ctx->Driver.ColorMask = nouveau_color_mask; + ctx->Driver.ColorMaterial = nouveau_color_material; + ctx->Driver.CullFace = nouveau_cull_face; + ctx->Driver.FrontFace = nouveau_front_face; + ctx->Driver.DepthFunc = nouveau_depth_func; + ctx->Driver.DepthMask = nouveau_depth_mask; + ctx->Driver.DepthRange = nouveau_depth_range; + ctx->Driver.DrawBuffer = nouveau_draw_buffer; + ctx->Driver.DrawBuffers = nouveau_draw_buffers; + ctx->Driver.Enable = nouveau_enable; + ctx->Driver.Fogfv = nouveau_fog; + ctx->Driver.IndexMask = nouveau_index_mask; + ctx->Driver.Lightfv = nouveau_light; + ctx->Driver.LightModelfv = nouveau_light_model; + ctx->Driver.LineStipple = nouveau_line_stipple; + ctx->Driver.LineWidth = nouveau_line_width; + ctx->Driver.LogicOpcode = nouveau_logic_opcode; + ctx->Driver.PointParameterfv = nouveau_point_parameter; + ctx->Driver.PointSize = nouveau_point_size; + ctx->Driver.PolygonMode = nouveau_polygon_mode; + ctx->Driver.PolygonOffset = nouveau_polygon_offset; + ctx->Driver.PolygonStipple = nouveau_polygon_stipple; + ctx->Driver.RenderMode = nouveau_render_mode; + ctx->Driver.Scissor = nouveau_scissor; + ctx->Driver.ShadeModel = nouveau_shade_model; + ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate; + ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate; + ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate; + ctx->Driver.TexGen = nouveau_tex_gen; + ctx->Driver.TexEnv = nouveau_tex_env; + ctx->Driver.TexParameter = nouveau_tex_parameter; + ctx->Driver.Viewport = nouveau_viewport; + + ctx->Driver.UpdateState = nouveau_update_state; + + BITSET_ONES(nctx->dirty); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h new file mode 100644 index 0000000000..d001fa259a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_STATE_H__ +#define __NOUVEAU_STATE_H__ + +enum { + NOUVEAU_STATE_ALPHA_FUNC, + NOUVEAU_STATE_BLEND_COLOR, + NOUVEAU_STATE_BLEND_EQUATION, + NOUVEAU_STATE_BLEND_FUNC, + NOUVEAU_STATE_CLIP_PLANE0, + NOUVEAU_STATE_CLIP_PLANE1, + NOUVEAU_STATE_CLIP_PLANE2, + NOUVEAU_STATE_CLIP_PLANE3, + NOUVEAU_STATE_CLIP_PLANE4, + NOUVEAU_STATE_CLIP_PLANE5, + NOUVEAU_STATE_COLOR_MASK, + NOUVEAU_STATE_COLOR_MATERIAL, + NOUVEAU_STATE_CULL_FACE, + NOUVEAU_STATE_FRONT_FACE, + NOUVEAU_STATE_DEPTH, + NOUVEAU_STATE_DITHER, + NOUVEAU_STATE_FRAG, + NOUVEAU_STATE_FRAMEBUFFER, + NOUVEAU_STATE_FOG, + NOUVEAU_STATE_INDEX_MASK, + NOUVEAU_STATE_LIGHT_ENABLE, + NOUVEAU_STATE_LIGHT_MODEL, + NOUVEAU_STATE_LIGHT_SOURCE0, + NOUVEAU_STATE_LIGHT_SOURCE1, + NOUVEAU_STATE_LIGHT_SOURCE2, + NOUVEAU_STATE_LIGHT_SOURCE3, + NOUVEAU_STATE_LIGHT_SOURCE4, + NOUVEAU_STATE_LIGHT_SOURCE5, + NOUVEAU_STATE_LIGHT_SOURCE6, + NOUVEAU_STATE_LIGHT_SOURCE7, + NOUVEAU_STATE_LINE_STIPPLE, + NOUVEAU_STATE_LINE_MODE, + NOUVEAU_STATE_LOGIC_OPCODE, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS, + NOUVEAU_STATE_MODELVIEW, + NOUVEAU_STATE_POINT_MODE, + NOUVEAU_STATE_POINT_PARAMETER, + NOUVEAU_STATE_POLYGON_MODE, + NOUVEAU_STATE_POLYGON_OFFSET, + NOUVEAU_STATE_POLYGON_STIPPLE, + NOUVEAU_STATE_PROJECTION, + NOUVEAU_STATE_RENDER_MODE, + NOUVEAU_STATE_SCISSOR, + NOUVEAU_STATE_SHADE_MODEL, + NOUVEAU_STATE_STENCIL_FUNC, + NOUVEAU_STATE_STENCIL_MASK, + NOUVEAU_STATE_STENCIL_OP, + NOUVEAU_STATE_TEX_ENV0, + NOUVEAU_STATE_TEX_ENV1, + NOUVEAU_STATE_TEX_ENV2, + NOUVEAU_STATE_TEX_ENV3, + NOUVEAU_STATE_TEX_GEN0, + NOUVEAU_STATE_TEX_GEN1, + NOUVEAU_STATE_TEX_GEN2, + NOUVEAU_STATE_TEX_GEN3, + NOUVEAU_STATE_TEX_OBJ0, + NOUVEAU_STATE_TEX_OBJ1, + NOUVEAU_STATE_TEX_OBJ2, + NOUVEAU_STATE_TEX_OBJ3, + NOUVEAU_STATE_VIEWPORT, + NUM_NOUVEAU_STATE, + + /* Room for card-specific states. */ + + MAX_NOUVEAU_STATE = NUM_NOUVEAU_STATE + 16, +}; + +typedef void (*nouveau_state_func)(GLcontext *ctx, int emit); + +void +nouveau_state_init(GLcontext *ctx); + +void +nouveau_emit_nothing(GLcontext *ctx, int emit); + +int +nouveau_next_dirty_state(GLcontext *ctx); + +void +nouveau_state_emit(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.c b/src/mesa/drivers/dri/nouveau/nouveau_surface.c new file mode 100644 index 0000000000..33393970a0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height) +{ + unsigned tile_mode, cpp = _mesa_get_format_bytes(format); + int ret; + + nouveau_bo_ref(NULL, &s->bo); + + *s = (struct nouveau_surface) { + .layout = layout, + .format = format, + .width = width, + .height = height, + .cpp = cpp, + .pitch = width * cpp, + }; + + if (layout == TILED) { + s->pitch = align(s->pitch, 256); + tile_mode = s->pitch; + } else { + s->pitch = align(s->pitch, 64); + tile_mode = 0; + } + + ret = nouveau_bo_new_tile(context_dev(ctx), flags, 0, s->pitch * height, + tile_mode, 0, &s->bo); + assert(!ret); +} + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst) +{ + if (src) { + dst->offset = src->offset; + dst->layout = src->layout; + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->cpp = src->cpp; + dst->pitch = src->pitch; + nouveau_bo_ref(src->bo, &dst->bo); + + } else { + nouveau_bo_ref(NULL, &dst->bo); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.h b/src/mesa/drivers/dri/nouveau/nouveau_surface.h new file mode 100644 index 0000000000..ebdc89afb4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_SURFACE_H__ +#define __NOUVEAU_SURFACE_H__ + +enum nouveau_surface_layout { + LINEAR = 0, + TILED, + SWIZZLED, +}; + +struct nouveau_surface { + struct nouveau_bo *bo; + unsigned offset; + + enum nouveau_surface_layout layout; + + gl_format format; + unsigned cpp, pitch; + + unsigned width, height; +}; + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height); + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c new file mode 100644 index 0000000000..8fa922f422 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +static enum tnl_attr_format +swtnl_get_format(int type, int fields) { + switch (type) { + case GL_FLOAT: + switch (fields){ + case 1: + return EMIT_1F; + case 2: + return EMIT_2F; + case 3: + return EMIT_3F; + case 4: + return EMIT_4F; + default: + assert(0); + } + case GL_UNSIGNED_BYTE: + switch (fields) { + case 4: + return EMIT_4UB_4F_RGBA; + default: + assert(0); + } + default: + assert(0); + } +} + +static struct swtnl_attr_info { + int type; + int fields; +} swtnl_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .type = GL_FLOAT, + .fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_COLOR0] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_FOG] = { + .type = GL_FLOAT, + .fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX1] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX2] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX3] = { + .type = GL_FLOAT, + .fields = -1, + }, +}; + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_clipspace *vtx = &tnl->clipspace; + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int fields, i, n = 0; + + render->mode = VBO; + render->attr_count = NUM_VERTEX_ATTRS; + + /* We always want non Ndc coords format */ + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.ClipPtr; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + struct nouveau_attr_info *ha = &TAG(vertex_attrs)[i]; + struct swtnl_attr_info *sa = &swtnl_attrs[i]; + struct nouveau_array_state *a = &render->attrs[i]; + + if (!sa->fields) + continue; /* Unsupported attribute. */ + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, i)) { + if (sa->fields > 0) + fields = sa->fields; + else + fields = tnl->vb.AttribPtr[i]->size; + + map[n++] = (struct tnl_attr_map) { + .attrib = i, + .format = swtnl_get_format(sa->type, fields), + }; + + render->map[ha->vbo_index] = i; + a->attr = i; + a->fields = fields; + a->type = sa->type; + } + } + + _tnl_install_attrs(ctx, map, n, NULL, 0); + + for (i = 0; i < vtx->attr_count; i++) { + struct tnl_clipspace_attr *ta = &vtx->attr[i]; + struct nouveau_array_state *a = &render->attrs[ta->attrib]; + + a->stride = vtx->vertex_size; + a->offset = ta->vertoffset; + } + + TAG(render_set_format)(ctx); +} + +static void +swtnl_alloc_vertices(GLcontext *ctx) +{ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + + nouveau_bo_ref(NULL, &swtnl->vbo); + swtnl->buf = get_scratch_vbo(ctx, RENDER_SCRATCH_SIZE, + &swtnl->vbo, NULL); + swtnl->vertex_count = 0; +} + +static void +swtnl_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_swtnl_state *swtnl = &render->swtnl; + int i; + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) + nouveau_bo_ref(swtnl->vbo, + &render->attrs[attr].bo); + } + + TAG(render_bind_vertices)(ctx); +} + +static void +swtnl_unbind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + nouveau_bo_ref(NULL, &render->attrs[*attr].bo); + *attr = -1; + } + } + + render->attr_count = 0; +} + +static void +swtnl_flush_vertices(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + unsigned push, start = 0, count = swtnl->vertex_count; + RENDER_LOCALS(ctx); + + swtnl_bind_vertices(ctx); + + while (count) { + push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining); + push = MIN2(push / 12 * 12, count); + count -= push; + + if (!push) { + FIRE_RING(chan); + continue; + } + + BATCH_BEGIN(nvgl_primitive(swtnl->primitive)); + EMIT_VBO(L, ctx, start, 0, push); + BATCH_END(); + + FIRE_RING(chan); + } + + swtnl_alloc_vertices(ctx); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + swtnl_flush_vertices(ctx); + swtnl_unbind_vertices(ctx); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(p, n) \ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size; \ + \ + if (swtnl->vertex_count + (n) > swtnl->vbo->size/vertex_len \ + || (swtnl->vertex_count && swtnl->primitive != p)) \ + swtnl_flush_vertices(ctx); \ + \ + swtnl->primitive = p; + +#define OUT_VERTEX(i) do { \ + memcpy(swtnl->buf + swtnl->vertex_count * vertex_len, \ + _tnl_get_vertex(ctx, (i)), vertex_len); \ + swtnl->vertex_count++; \ + } while (0) + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ + int i, count; + + while (first < last) { + BEGIN_PRIMITIVE(GL_POINTS, last - first); + + count = MIN2(swtnl->vbo->size / vertex_len, last - first); + for (i = 0; i < count; i++) + OUT_VERTEX(first + i); + + first += count; + } +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ + BEGIN_PRIMITIVE(GL_LINES, 2); + OUT_VERTEX(v1); + OUT_VERTEX(v2); +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(GL_TRIANGLES, 3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(GL_QUADS, 4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); +} + +/* TnL initialization. */ +static void +TAG(swtnl_init)(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_need_projected_coords(ctx, GL_FALSE); + _tnl_allow_vertex_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); + + swtnl_alloc_vertices(ctx); +} + +static void +TAG(swtnl_destroy)(GLcontext *ctx) +{ + nouveau_bo_ref(NULL, &to_render_state(ctx)->swtnl.vbo); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c new file mode 100644 index 0000000000..ab6e93cceb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "main/texobj.h" +#include "main/texstore.h" +#include "main/texformat.h" +#include "main/texcompress.h" +#include "main/texgetimage.h" +#include "main/mipmap.h" +#include "main/texfetch.h" + +static struct gl_texture_object * +nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target) +{ + struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture); + + _mesa_initialize_texture_object(&nt->base, name, target); + + return &nt->base; +} + +static void +nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_surface_ref(NULL, &nt->surfaces[i]); + + _mesa_delete_texture_object(ctx, t); +} + +static struct gl_texture_image * +nouveau_teximage_new(GLcontext *ctx) +{ + struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage); + + return &nti->base; +} + +static void +nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_teximage *nti = to_nouveau_teximage(ti); + + nouveau_surface_ref(NULL, &nti->surface); +} + +static void +nouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + int ret; + + ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + assert(!ret); + + ti->Data = s->bo->map; +} + +static void +nouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + nouveau_bo_unmap(s->bo); + ti->Data = NULL; +} + +static gl_format +nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + case GL_RGBA8: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return MESA_FORMAT_ARGB8888; + case GL_RGB5_A1: + return MESA_FORMAT_ARGB1555; + case GL_RGBA2: + case GL_RGBA4: + return MESA_FORMAT_ARGB4444; + + case 3: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + return MESA_FORMAT_RGB565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_ALPHA8: + return MESA_FORMAT_A8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_LUMINANCE8: + return MESA_FORMAT_L8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_LUMINANCE8_ALPHA8: + return MESA_FORMAT_ARGB8888; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_INTENSITY8: + return MESA_FORMAT_ARGB8888; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + case GL_COLOR_INDEX8_EXT: + return MESA_FORMAT_CI8; + + default: + assert(0); + } +} + +static void +nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + unsigned bo_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RDWR | NOUVEAU_BO_MAP; + int ret; + + /* Allocate a new bo for the image. */ + nouveau_surface_alloc(ctx, s, LINEAR, bo_flags, ti->TexFormat, + width, height); + ti->RowStride = s->pitch / s->cpp; + + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, + format, type, pixels, packing, + "glTexImage"); + if (!pixels) + return; + + /* Store the pixel data. */ + nouveau_teximage_map(ctx, ti); + + ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, + ti->TexFormat, ti->Data, + 0, 0, 0, s->pitch, + ti->ImageOffsets, + width, height, depth, + format, type, pixels, packing); + assert(ret); + + nouveau_teximage_unmap(ctx, ti); + _mesa_unmap_teximage_pbo(ctx, packing); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 1, target, level, internalFormat, + width, 1, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 2, target, level, internalFormat, + width, height, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 3, target, level, internalFormat, + width, height, depth, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage1d(ctx, target, level, xoffset, + width, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_get_teximage(ctx, target, level, format, type, pixels, + t, ti); + nouveau_teximage_unmap(ctx, ti); +} + +static void +nouveau_bind_texture(GLcontext *ctx, GLenum target, + struct gl_texture_object *t) +{ + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); +} + +static void +nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_map(ctx, t->Image[0][i]); + } +} + +static void +nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_unmap(ctx, t->Image[0][i]); + } +} + +static void +relayout_miptree(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; + unsigned last_level, offset = 0; + unsigned size; + int i, ret; + + if (t->MinFilter == GL_NEAREST || + t->MinFilter == GL_LINEAR) + last_level = t->BaseLevel; + else + last_level = t->_MaxLevel; + + /* Deallocate the old storage. */ + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_bo_ref(NULL, &ss[i].bo); + + /* Relayout the mipmap tree. */ + for (i = t->BaseLevel; i <= last_level; i++) { + struct nouveau_surface *s = + &to_nouveau_teximage(t->Image[0][i])->surface; + + size = s->width * s->height * s->cpp; + + /* Images larger than 16B have to be aligned. */ + if (size > 16) + offset = align(offset, 64); + + ss[i] = (struct nouveau_surface) { + .offset = offset, + .layout = SWIZZLED, + .format = s->format, + .width = s->width, + .height = s->height, + .cpp = s->cpp, + .pitch = s->width * s->cpp, + }; + + offset += size; + } + + /* Get new storage. */ + size = align(offset, 64); + + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM, + 0, size, &ss[last_level].bo); + assert(!ret); + + for (i = t->BaseLevel; i < last_level; i++) + nouveau_bo_ref(ss[last_level].bo, &ss[i].bo); +} + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + if (!nt->dirty) + return; + + nt->dirty = GL_FALSE; + + relayout_miptree(ctx, t); + + /* Copy the teximages to the actual swizzled miptree. */ + for (i = t->BaseLevel; i < MAX_TEXTURE_LEVELS; i++) { + struct gl_texture_image *ti = t->Image[0][i]; + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + if (!nt->surfaces[i].bo) + break; + + context_drv(ctx)->surface_copy(ctx, &nt->surfaces[i], s, + 0, 0, 0, 0, + s->width, s->height); + } +} + +void +nouveau_texture_functions_init(struct dd_function_table *functions) +{ + functions->NewTextureObject = nouveau_texture_new; + functions->DeleteTexture = nouveau_texture_free; + functions->NewTextureImage = nouveau_teximage_new; + functions->FreeTexImageData = nouveau_teximage_free; + functions->ChooseTextureFormat = nouveau_choose_tex_format; + functions->TexImage1D = nouveau_teximage_1d; + functions->TexImage2D = nouveau_teximage_2d; + functions->TexImage3D = nouveau_teximage_3d; + functions->TexSubImage1D = nouveau_texsubimage_1d; + functions->TexSubImage2D = nouveau_texsubimage_2d; + functions->TexSubImage3D = nouveau_texsubimage_3d; + functions->GetTexImage = nouveau_get_teximage; + functions->BindTexture = nouveau_bind_texture; + functions->MapTexture = nouveau_texture_map; + functions->UnmapTexture = nouveau_texture_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.h b/src/mesa/drivers/dri/nouveau/nouveau_texture.h new file mode 100644 index 0000000000..695c0897b5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_TEXTURE_H__ +#define __NOUVEAU_TEXTURE_H__ + +struct nouveau_teximage { + struct gl_texture_image base; + struct nouveau_surface surface; +}; +#define to_nouveau_teximage(x) ((struct nouveau_teximage *)(x)) + +struct nouveau_texture { + struct gl_texture_object base; + struct nouveau_surface surfaces[MAX_TEXTURE_LEVELS]; + GLboolean dirty; +}; +#define to_nouveau_texture(x) ((struct nouveau_texture *)(x)) + +#define texture_dirty(t) \ + to_nouveau_texture(t)->dirty = GL_TRUE; + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h new file mode 100644 index 0000000000..076f225fed --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_UTIL_H__ +#define __NOUVEAU_UTIL_H__ + +#include "main/formats.h" +#include "main/colormac.h" + +static inline unsigned +pack_rgba_i(gl_format f, uint8_t c[]) +{ + switch (f) { + case MESA_FORMAT_ARGB8888: + return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_ARGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); + case MESA_FORMAT_XRGB8888: + return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_XRGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); + case MESA_FORMAT_RGBA8888: + return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); + case MESA_FORMAT_RGBA8888_REV: + return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); + case MESA_FORMAT_RGB565: + return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]); + default: + assert(0); + } +} + +static inline unsigned +pack_zs_i(gl_format f, uint32_t z, uint8_t s) +{ + switch (f) { + case MESA_FORMAT_Z24_S8: + return (z & 0xffffff00) | (s & 0xff); + case MESA_FORMAT_Z24_X8: + return (z & 0xffffff00); + case MESA_FORMAT_Z16: + return (z & 0xffff0000) >> 16; + default: + assert(0); + } +} + +static inline unsigned +pack_rgba_f(gl_format f, float c[]) +{ + return pack_rgba_i(f, (uint8_t []) { + FLOAT_TO_UBYTE(c[RCOMP]), + FLOAT_TO_UBYTE(c[GCOMP]), + FLOAT_TO_UBYTE(c[BCOMP]), + FLOAT_TO_UBYTE(c[ACOMP]) }); +} + +static inline unsigned +pack_zs_f(gl_format f, float z, uint8_t s) +{ + return pack_zs_i(f, FLOAT_TO_UINT(z), s); +} + +/* Integer base-2 logarithm, rounded towards zero. */ +static inline unsigned +log2i(unsigned i) +{ + unsigned r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +static inline unsigned +align(unsigned x, unsigned m) +{ + return (x + m - 1) & ~(m - 1); +} + +static inline void +get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) +{ + *w = fb->_Xmax - fb->_Xmin; + *h = fb->_Ymax - fb->_Ymin; + *x = fb->_Xmin; + *y = (fb->Name ? fb->_Ymin : + /* Window system FBO: Flip the Y coordinate. */ + fb->Height - fb->_Ymax); +} + +static inline void +get_viewport_scale(GLcontext *ctx, float a[16]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[MAT_SX] = (float)vp->Width / 2; + + if (fb->Name) + a[MAT_SY] = (float)vp->Height / 2; + else + /* Window system FBO: Flip the Y coordinate. */ + a[MAT_SY] = - (float)vp->Height / 2; + + a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; +} + +static inline void +get_viewport_translate(GLcontext *ctx, float a[4]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[0] = (float)vp->Width / 2 + vp->X; + + if (fb->Name) + a[1] = (float)vp->Height / 2 + vp->Y; + else + /* Window system FBO: Flip the Y coordinate. */ + a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; + + a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; +} + +static inline void +OUT_RINGm(struct nouveau_channel *chan, float m[16]) +{ + int i, j; + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m[4*j + i]); +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c new file mode 100644 index 0000000000..ba1192a170 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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/bufferobj.h" +#include "nouveau_bufferobj.h" + +/* Arbitrary pushbuf length we can assume we can get with a single + * WAIT_RING. */ +#define PUSHBUF_DWORDS 2048 + +/* Functions to set up struct nouveau_array_state from something like + * a GL array or index buffer. */ + +static void +vbo_init_array(struct nouveau_array_state *a, int attr, int stride, + int fields, int type, struct gl_buffer_object *obj, + const void *ptr, GLboolean map) +{ + a->attr = attr; + a->stride = stride; + a->fields = fields; + a->type = type; + + if (_mesa_is_bufferobj(obj)) { + nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &a->bo); + a->offset = (intptr_t)ptr; + + if (map) { + nouveau_bo_map(a->bo, NOUVEAU_BO_RD); + a->buf = a->bo->map + a->offset; + } else { + a->buf = NULL; + } + + } else { + nouveau_bo_ref(NULL, &a->bo); + a->offset = 0; + a->buf = ptr; + } + + if (a->buf) + get_array_extract(a, &a->extract_u, &a->extract_f); +} + +static void +vbo_deinit_array(struct nouveau_array_state *a) +{ + if (a->bo) { + if (a->bo->map) + nouveau_bo_unmap(a->bo); + nouveau_bo_ref(NULL, &a->bo); + } + + a->buf = NULL; + a->fields = 0; +} + +static void +vbo_init_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_init_array(&render->ib, 0, 0, ib->count, ib->type, + ib->obj, ib->ptr, GL_TRUE); + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + + vbo_init_array(&render->attrs[attr], attr, + array->StrideB, array->Size, + array->Type, array->BufferObj, + array->Ptr, render->mode == IMM); + } + } +} + +static void +vbo_deinit_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_deinit_array(&render->ib); + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + vbo_deinit_array(&render->attrs[*attr]); + *attr = -1; + } + } + + render->attr_count = 0; +} + +/* Make some rendering decisions from the GL context. */ + +static void +vbo_choose_render_mode(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + render->mode = VBO; + + if (ctx->Light.Enabled) { + for (i = 0; i < MAT_ATTRIB_MAX; i++) { + if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) { + render->mode = IMM; + break; + } + } + } + + if (render->mode == VBO) + render->attr_count = NUM_VERTEX_ATTRS; + else + render->attr_count = 0; +} + +static void +vbo_emit_attr(GLcontext *ctx, const struct gl_client_array **arrays, int attr) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_render_state *render = to_render_state(ctx); + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + RENDER_LOCALS(ctx); + + if (!array->StrideB) { + if (attr >= VERT_ATTRIB_GENERIC0) + /* nouveau_update_state takes care of materials. */ + return; + + /* Constant attribute. */ + vbo_init_array(a, attr, array->StrideB, array->Size, + array->Type, array->BufferObj, array->Ptr, + GL_TRUE); + EMIT_IMM(ctx, a, 0); + vbo_deinit_array(a); + + } else { + /* Varying attribute. */ + struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr]; + + if (render->mode == VBO) { + render->map[info->vbo_index] = attr; + render->vertex_size += array->_ElementSize; + } else { + render->map[render->attr_count++] = attr; + render->vertex_size += 4 * info->imm_fields; + } + } +} + +#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a) + +static void +vbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + /* Reset the vertex size. */ + render->vertex_size = 0; + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0); + if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1); + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture._EnabledCoordUnits & (1 << i)) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i); + } + + if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG); + + if (ctx->Light.Enabled) { + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL); + + vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS)); + + if (ctx->Light.Model.TwoSide) { + vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS)); + } + } + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS); +} + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index); + +static GLboolean +vbo_maybe_split(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * nctx->bo.count, + vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail), + idx_avail = get_max_vertices(ctx, ib, pushbuf_avail); + + if ((ib && ib->count > idx_avail) || + (!ib && max_index - min_index > vert_avail)) { + struct split_limits limits = { + .max_verts = vert_avail, + .max_indices = idx_avail, + .max_vb_size = ~0, + }; + + vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index, + max_index, TAG(vbo_render_prims), &limits); + return GL_TRUE; + } + + return GL_FALSE; +} + +/* VBO rendering path. */ + +static void +vbo_bind_vertices(GLcontext *ctx, const struct gl_client_array **arrays, + GLint basevertex, GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + unsigned delta = (basevertex + min_index) * a->stride, + size = (max_index - min_index + 1) * a->stride; + + if (a->bo) { + a->offset = (intptr_t)array->Ptr + delta; + } else { + void *scratch = get_scratch_vbo(ctx, size, + &a->bo, + &a->offset); + + memcpy(scratch, a->buf + delta, size); + } + } + } + + TAG(render_bind_vertices)(ctx); +} + +static void +vbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_channel *chan = context_chan(ctx); + dispatch_t dispatch; + int delta = -min_index, basevertex = 0, i; + RENDER_LOCALS(ctx); + + get_array_dispatch(&to_render_state(ctx)->ib, &dispatch); + + TAG(render_set_format)(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + count = prims[i].count; + + if (i == 0 || basevertex != prims[i].basevertex) { + basevertex = prims[i].basevertex; + vbo_bind_vertices(ctx, arrays, basevertex, + min_index, max_index); + } + + if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + dispatch(ctx, start, delta, count); + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* Immediate rendering path. */ + +static unsigned +extract_id(struct nouveau_array_state *a, int i, int j) +{ + return j; +} + +static void +vbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + extract_u_t extract = ib ? render->ib.extract_u : extract_id; + int i, j, k; + RENDER_LOCALS(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + end = start + prims[i].count; + + if (prims[i].count > get_max_vertices(ctx, ib, + chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + + for (; start < end; start++) { + j = prims[i].basevertex + + extract(&render->ib, 0, start); + + for (k = 0; k < render->attr_count; k++) + EMIT_IMM(ctx, &render->attrs[render->map[k]], + j); + } + + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* draw_prims entry point when we're doing hw-tnl. */ + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (!index_bounds_valid) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + + vbo_choose_render_mode(ctx, arrays); + vbo_choose_attrs(ctx, arrays); + + if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index, + max_index)) + return; + + vbo_init_arrays(ctx, ib, arrays); + + if (render->mode == VBO) + vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + else + vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + + vbo_deinit_arrays(ctx, ib, arrays); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c new file mode 100644 index 0000000000..5548286a73 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx) +{ + struct nv04_context *nctx = to_nv04_context(ctx); + struct nouveau_screen *screen = nctx->base.screen; + struct nouveau_grobj *fahrenheit; + + if (ctx->Texture.Unit[0].EnvMode == GL_COMBINE || + ctx->Texture.Unit[0].EnvMode == GL_BLEND || + ctx->Texture.Unit[1]._ReallyEnabled || + ctx->Stencil.Enabled) + fahrenheit = screen->eng3dm; + else + fahrenheit = screen->eng3d; + + if (fahrenheit != nctx->eng3d) { + nctx->eng3d = fahrenheit; + + if (nv04_mtex_engine(fahrenheit)) { + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } else { + context_bctx_i(ctx, TEXTURE, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } + } + + return fahrenheit; +} + +static void +init_dummy_texture(GLcontext *ctx) +{ + struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture; + + nouveau_surface_alloc(ctx, s, SWIZZLED, + NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM, + MESA_FORMAT_ARGB8888, 1, 1); + + nouveau_bo_map(s->bo, NOUVEAU_BO_WR); + *(uint32_t *)s->bo->map = 0xffffffff; + nouveau_bo_unmap(s->bo); +} + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nv04_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nv04_context); + if (!nctx) + return NULL; + + ctx = &nctx->base.base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + + init_dummy_texture(ctx); + nv04_render_init(ctx); + + return ctx; +} + +void +nv04_context_destroy(GLcontext *ctx) +{ + nv04_render_destroy(ctx); + nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture); + + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.h b/src/mesa/drivers/dri/nouveau/nv04_context.h new file mode 100644 index 0000000000..ed4eec9865 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV04_CONTEXT_H__ +#define __NV04_CONTEXT_H__ + +#include "nouveau_context.h" + +struct nv04_context { + struct nouveau_context base; + struct nouveau_grobj *eng3d; + struct nouveau_surface dummy_texture; + float viewport[16]; +}; +#define to_nv04_context(ctx) ((struct nv04_context *)(ctx)) + +#define nv04_mtex_engine(obj) ((obj)->grclass == NV04_MULTITEX_TRIANGLE) + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx); + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv04_context_destroy(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_driver.h b/src/mesa/drivers/dri/nouveau/nv04_driver.h new file mode 100644 index 0000000000..00668710ac --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_driver.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV04_DRIVER_H__ +#define __NV04_DRIVER_H__ + +#include "nv04_context.h" + +enum { + NOUVEAU_STATE_BLEND = NUM_NOUVEAU_STATE, + NOUVEAU_STATE_CONTROL, + NUM_NV04_STATE +}; + +#define NV04_TEXTURE_UNITS 2 + +/* nv04_screen.c */ +GLboolean +nv04_screen_init(struct nouveau_screen *screen); + +/* nv04_render.c */ +void +nv04_render_init(GLcontext *ctx); + +void +nv04_render_destroy(GLcontext *ctx); + +/* nv04_surface.c */ +GLboolean +nv04_surface_init(struct nouveau_screen *screen); + +void +nv04_surface_takedown(struct nouveau_screen *screen); + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + +/* nv04_state_fb.c */ +void +nv04_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv04_emit_scissor(GLcontext *ctx, int emit); + +/* nv04_state_raster.c */ +void +nv04_defer_control(GLcontext *ctx, int emit); + +void +nv04_emit_control(GLcontext *ctx, int emit); + +void +nv04_defer_blend(GLcontext *ctx, int emit); + +void +nv04_emit_blend(GLcontext *ctx, int emit); + +/* nv04_state_frag.c */ +void +nv04_emit_tex_env(GLcontext *ctx, int emit); + +/* nv04_state_tex.c */ +void +nv04_emit_tex_obj(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_render.c b/src/mesa/drivers/dri/nouveau/nv04_render.c new file mode 100644 index 0000000000..b5943d9987 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_render.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#define NUM_VERTEX_ATTRS 6 + +static void +swtnl_update_viewport(GLcontext *ctx) +{ + float *viewport = to_nv04_context(ctx)->viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + get_viewport_scale(ctx, viewport); + get_viewport_translate(ctx, &viewport[MAT_TX]); + + /* It wants normalized Z coordinates. */ + viewport[MAT_SZ] /= fb->_DepthMaxF; + viewport[MAT_TZ] /= fb->_DepthMaxF; +} + +static void +swtnl_emit_attr(GLcontext *ctx, struct tnl_attr_map *m, int attr, int emit) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, attr)) + *m = (struct tnl_attr_map) { + .attrib = attr, + .format = emit, + }; + else + *m = (struct tnl_attr_map) { + .format = EMIT_PAD, + .offset = _tnl_format_info[emit].attrsize, + }; +} + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nv04_context *nctx = to_nv04_context(ctx); + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int n = 0; + + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.NdcPtr; + + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_FOG, EMIT_1UB_1F); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX0, EMIT_2F); + if (nv04_mtex_engine(fahrenheit)) + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX1, EMIT_2F); + + swtnl_update_viewport(ctx); + + _tnl_install_attrs(ctx, map, n, nctx->viewport, 0); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + FIRE_RING(context_chan(ctx)); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(n) \ + struct nouveau_channel *chan = context_chan(ctx); \ + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4; \ + \ + if (nv04_mtex_engine(fahrenheit)) \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_TLMTVERTEX_SX(0), \ + n * vertex_len); \ + else \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0), \ + n * vertex_len); \ + +#define OUT_VERTEX(i) \ + OUT_RINGp(chan, _tnl_get_vertex(ctx, i), vertex_len); + +#define END_PRIMITIVE(draw) \ + if (nv04_mtex_engine(fahrenheit)) { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } else { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + END_PRIMITIVE(0x210); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); + END_PRIMITIVE(0x320210); +} + +/* TnL initialization. */ +void +nv04_render_init(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_need_projected_coords(ctx, GL_TRUE); + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_allow_pixel_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); +} + +void +nv04_render_destroy(GLcontext *ctx) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_screen.c b/src/mesa/drivers/dri/nouveau/nv04_screen.c new file mode 100644 index 0000000000..0fc0f4c391 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_screen.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static const struct nouveau_driver nv04_driver; + +static void +nv04_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_grobj *eng3d = screen->eng3d; + struct nouveau_grobj *eng3dm = screen->eng3dm; + + BIND_RING(chan, surf3d, 7); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + FIRE_RING(chan); +} + +static void +nv04_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) { + GLcontext *ctx = &nctx->base; + + /* Flushing seems to clobber the engine context. */ + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + + nouveau_state_emit(ctx); + } +} + +GLboolean +nv04_screen_init(struct nouveau_screen *screen) +{ + int ret; + + screen->driver = &nv04_driver; + screen->chan->flush_notify = nv04_channel_flush_notify; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, + NV04_TEXTURED_TRIANGLE, &screen->eng3d); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0002, + NV04_MULTITEX_TRIANGLE, &screen->eng3dm); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0003, + NV04_CONTEXT_SURFACES_3D, &screen->surf3d); + if (ret) + return GL_FALSE; + + nv04_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv04_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + if (screen->eng3dm) + nouveau_grobj_free(&screen->eng3dm); + + if (screen->surf3d) + nouveau_grobj_free(&screen->surf3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv04_driver = { + .screen_destroy = nv04_screen_destroy, + .context_create = nv04_context_create, + .context_destroy = nv04_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_blend, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nv04_defer_control, + nouveau_emit_nothing, + nv04_emit_framebuffer, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_scissor, + nv04_defer_blend, + nv04_defer_control, + nv04_defer_control, + nv04_defer_control, + nv04_emit_tex_env, + nv04_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_tex_obj, + nv04_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_blend, + nv04_emit_control, + }, + .num_emit = NUM_NV04_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_fb.c b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c new file mode 100644 index 0000000000..e97eb2a03b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + default: + assert(0); + } +} + +void +nv04_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + uint32_t rt_format = NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH; + uint32_t rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + OUT_RING(chan, rt_format); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_PITCH, 1); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the scissor state. */ + context_dirty(ctx, SCISSOR); +} + +void +nv04_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); + + /* Messing with surf3d invalidates some engine state. */ + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_frag.c b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c new file mode 100644 index 0000000000..34ee296202 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#define COMBINER_SHIFT(in) \ + (NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##_SHIFT \ + - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_SHIFT) +#define COMBINER_SOURCE(reg) \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg +#define COMBINER_INVERT \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_INVERSE0 +#define COMBINER_ALPHA \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0 + +struct combiner_state { + int unit; + GLboolean alpha; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint32_t hw; +}; + +#define __INIT_COMBINER_ALPHA_A GL_TRUE +#define __INIT_COMBINER_ALPHA_RGB GL_FALSE + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->alpha = __INIT_COMBINER_ALPHA_##chan; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->hw = 0; \ + } while (0) + +/* Get the combiner source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_arg_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return rc->unit ? COMBINER_SOURCE(TEXTURE1) : + COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE0: + return COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return COMBINER_SOURCE(TEXTURE1); + + case GL_CONSTANT: + return COMBINER_SOURCE(CONSTANT); + + case GL_PRIMARY_COLOR: + return COMBINER_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? COMBINER_SOURCE(PREVIOUS) : + COMBINER_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the (possibly inverted) combiner input mapping for the + * specified argument. */ +#define INVERT 0x1 + +static uint32_t +get_arg_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= rc->alpha ? 0 : COMBINER_ALPHA; + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= flags & INVERT ? COMBINER_INVERT : 0; + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= flags & INVERT ? 0 : COMBINER_INVERT; + break; + } + + return map; +} + +/* Bind the combiner input <in> to the combiner source <src>, + * possibly inverted. */ +#define INPUT_SRC(rc, in, src, flags) \ + (rc)->hw |= ((flags & INVERT ? COMBINER_INVERT : 0) | \ + COMBINER_SOURCE(src)) << COMBINER_SHIFT(in) + +/* Bind the combiner input <in> to the EXT_texture_env_combine + * argument <arg>, possibly inverted. */ +#define INPUT_ARG(rc, in, arg, flags) \ + (rc)->hw |= (get_arg_source(rc, arg) | \ + get_arg_mapping(rc, arg, flags)) << COMBINER_SHIFT(in) + +#define UNSIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_IDENTITY) +#define SIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS) + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_MODULATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 1, 0); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_ADD: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 2, 0); + INPUT_ARG(rc, 2, 1, 0); + INPUT_ARG(rc, 3, 2, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + SIGNED_OP(rc); + break; + + default: + assert(0); + } +} + +void +nv04_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct combiner_state rc_a = {}, rc_c = {}; + + if (!nv04_mtex_engine(fahrenheit)) { + context_dirty(ctx, BLEND); + return; + } + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(A, &rc_a, i); + setup_combiner(&rc_a); + + INIT_COMBINER(RGB, &rc_c, i); + setup_combiner(&rc_c); + + } else { + if (i == 0) { + INPUT_SRC(&rc_a, 0, PRIMARY_COLOR, 0); + INPUT_SRC(&rc_c, 0, PRIMARY_COLOR, 0); + } else { + INPUT_SRC(&rc_a, 0, PREVIOUS, 0); + INPUT_SRC(&rc_c, 0, PREVIOUS, 0); + } + + INPUT_SRC(&rc_a, 1, ZERO, INVERT); + INPUT_SRC(&rc_c, 1, ZERO, INVERT); + INPUT_SRC(&rc_a, 2, ZERO, 0); + INPUT_SRC(&rc_c, 2, ZERO, 0); + INPUT_SRC(&rc_a, 3, ZERO, 0); + INPUT_SRC(&rc_c, 3, ZERO, 0); + + UNSIGNED_OP(&rc_a); + UNSIGNED_OP(&rc_c); + } + + /* Write the register combiner state out to the hardware. */ + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_ALPHA(i), 2); + OUT_RING(chan, rc_a.hw); + OUT_RING(chan, rc_c.hw); + + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_FACTOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[0].EnvColor)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c new file mode 100644 index 0000000000..5e3788d185 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static unsigned +get_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x1; + case GL_LESS: + return 0x2; + case GL_EQUAL: + return 0x3; + case GL_LEQUAL: + return 0x4; + case GL_GREATER: + return 0x5; + case GL_NOTEQUAL: + return 0x6; + case GL_GEQUAL: + return 0x7; + case GL_ALWAYS: + return 0x8; + default: + assert(0); + } +} + +static unsigned +get_stencil_op(unsigned op) +{ + switch (op) { + case GL_KEEP: + return 0x1; + case GL_INCR: + return 0x4; + case GL_DECR: + return 0x5; + case GL_INVERT: + return 0x6; + default: + assert(0); + } +} + +static unsigned +get_texenv_mode(unsigned mode) +{ + switch (mode) { + case GL_REPLACE: + return 0x1; + case GL_ADD: + return 0x2; + case GL_DECAL: + return 0x3; + case GL_MODULATE: + return 0x4; + default: + assert(0); + } +} + +static unsigned +get_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x1; + case GL_ONE: + return 0x2; + case GL_SRC_COLOR: + return 0x3; + case GL_ONE_MINUS_SRC_COLOR: + return 0x4; + case GL_SRC_ALPHA: + return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x6; + case GL_DST_ALPHA: + return 0x7; + case GL_ONE_MINUS_DST_ALPHA: + return 0x8; + case GL_DST_COLOR: + return 0x9; + case GL_ONE_MINUS_DST_COLOR: + return 0xa; + case GL_SRC_ALPHA_SATURATE: + return 0xb; + default: + assert(0); + } +} + +void +nv04_defer_control(GLcontext *ctx, int emit) +{ + context_dirty(ctx, CONTROL); +} + +void +nv04_emit_control(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl0 = 1 << 30 | + NV04_MULTITEX_TRIANGLE_CONTROL0_ORIGIN; + uint32_t ctrl1 = 0, ctrl2 = 0; + + /* Color mask. */ + if (ctx->Color.ColorMask[0][RCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; + if (ctx->Color.ColorMask[0][GCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; + if (ctx->Color.ColorMask[0][BCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; + if (ctx->Color.ColorMask[0][ACOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_BOTH; + else + ctrl0 |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CW : + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE; + + if (ctx->Depth.Mask) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE; + + ctrl0 |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_ENABLE; + + ctrl0 |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + /* Stencil test. */ + if (ctx->Stencil.WriteMask[0]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; + + if (ctx->Stencil.Enabled) + ctrl1 |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; + + ctrl1 |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | + ctx->Stencil.Ref[0] << 8 | + ctx->Stencil.ValueMask[0] << 16 | + ctx->Stencil.WriteMask[0] << 24; + + ctrl2 |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | + get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | + get_stencil_op(ctx->Stencil.FailFunc[0]); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_CONTROL0, 3); + OUT_RING(chan, ctrl0); + OUT_RING(chan, ctrl1); + OUT_RING(chan, ctrl2); + + } else { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl = 1 << 30 | + NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; + else + ctrl |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; + if (ctx->Depth.Mask) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; + + ctrl |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; + + ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(chan, ctrl); + } +} + +void +nv04_defer_blend(GLcontext *ctx, int emit) +{ + context_dirty(ctx, BLEND); +} + +void +nv04_emit_blend(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + uint32_t blend = 0x2 << 4 | + NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + + } else { + uint32_t blend = 0x2 << 4 | + NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Texture environment. */ + blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode); + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_tex.c b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c new file mode 100644 index 0000000000..99ea310c65 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_Y8; + case MESA_FORMAT_ARGB1555: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A1R5G5B5; + case MESA_FORMAT_ARGB4444: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A4R4G4B4; + case MESA_FORMAT_RGB565: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_R5G6B5; + case MESA_FORMAT_ARGB8888: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + default: + assert(0); + } +} + +static inline unsigned +get_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + default: + assert(0); + } +} + +void +nv04_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct nouveau_surface *s; + uint32_t format = 0xa0, filter = 0x1010; + + if (i && !nv04_mtex_engine(fahrenheit)) + return; + + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *t = ctx->Texture.Unit[i]._Current; + struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; + int lod_max = 1, lod_bias = 0; + + nouveau_texture_validate(ctx, t); + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda), + 0, 15) + 1; + + lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias + + t->LodBias, 0, 15); + } + + format |= get_wrap_mode(t->WrapT) << 28 | + get_wrap_mode(t->WrapS) << 24 | + ti->HeightLog2 << 20 | + ti->WidthLog2 << 16 | + lod_max << 12 | + get_tex_format(ti); + + filter |= log2i(t->MaxAnisotropy) << 31 | + nvgl_filter_mode(t->MagFilter) << 28 | + log2i(t->MaxAnisotropy) << 27 | + nvgl_filter_mode(t->MinFilter) << 24 | + lod_bias << 16; + + } else { + s = &to_nv04_context(ctx)->dummy_texture; + + format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT | + NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT | + 1 << 12 | + NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + + filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST | + NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; + } + + if (nv04_mtex_engine(fahrenheit)) { + nouveau_bo_markl(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_OFFSET(i), + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_FORMAT(i), + s->bo, format, 0, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1); + OUT_RING(chan, filter); + + } else { + nouveau_bo_markl(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_OFFSET, + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_FORMAT, + s->bo, format, 0, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); + OUT_RING(chan, filter); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_surface.c b/src/mesa/drivers/dri/nouveau/nv04_surface.c new file mode 100644 index 0000000000..0d40349345 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_surface.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_class.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nv04_driver.h" + +static inline int +swzsurf_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +surf2d_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + + default: + assert(0); + } +} + +static inline int +rect_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +sifm_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static void +nv04_surface_copy_swizzle(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *swzsurf = screen->swzsurf; + struct nouveau_grobj *sifm = screen->sifm; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + /* Max width & height may not be the same on all HW, but must be POT */ + const unsigned max_w = 1024; + const unsigned max_h = 1024; + unsigned sub_w = w > max_w ? max_w : w; + unsigned sub_h = h > max_h ? max_h : h; + unsigned x, y; + + /* Swizzled surfaces must be POT */ + assert(_mesa_is_pow_two(dst->width) && + _mesa_is_pow_two(dst->height)); + + /* If area is too large to copy in one shot we must copy it in + * POT chunks to meet alignment requirements */ + assert(sub_w == w || _mesa_is_pow_two(sub_w)); + assert(sub_h == h || _mesa_is_pow_two(sub_h)); + + nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, + dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, + dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); + OUT_RING (chan, swzsurf_format(dst->format) | + log2i(dst->width) << 16 | + log2i(dst->height) << 24); + + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, swzsurf->handle); + + for (y = 0; y < h; y += sub_h) { + sub_h = MIN2(sub_h, h - y); + + for (x = 0; x < w; x += sub_w) { + sub_w = MIN2(sub_w, w - x); + /* Must be 64-byte aligned */ + assert(!(dst->offset & 63)); + + MARK_RING(chan, 15, 1); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8); + OUT_RING(chan, sifm_format(src->format)); + OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, 1 << 20); + OUT_RING(chan, 1 << 20); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, src->pitch | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, src->bo, src->offset + + (y + sy) * src->pitch + + (x + sx) * src->cpp, + bo_flags | NOUVEAU_BO_RD); + OUT_RING(chan, 0); + } + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +static void +nv04_surface_copy_m2mf(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *m2mf = screen->m2mf; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; + unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; + + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT, + dst->bo, bo_flags | NOUVEAU_BO_WR); + + while (h) { + int count = (h > 2047) ? 2047 : h; + + MARK_RING(chan, 9, 2); + + BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->bo, src_offset, + bo_flags | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->bo, dst_offset, + bo_flags | NOUVEAU_BO_WR); + OUT_RING (chan, src->pitch); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->pitch * count; + dst_offset += dst->pitch * count; + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + /* Setup transfer to swizzle the texture to vram if needed */ + if (src->layout != SWIZZLED && + dst->layout == SWIZZLED && + dst->width > 2 && dst->height > 1) { + nv04_surface_copy_swizzle(ctx, dst, src, + dx, dy, sx, sy, w, h); + return; + } + + nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h); +} + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf2d = screen->surf2d; + struct nouveau_grobj *patt = screen->patt; + struct nouveau_grobj *rect = screen->rect; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + + MARK_RING (chan, 19, 4); + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, surf2d_format(dst->format)); + OUT_RING (chan, (dst->pitch << 16) | dst->pitch); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1); + OUT_RING (chan, mask | ~0 << (8 * dst->cpp)); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_takedown(struct nouveau_screen *screen) +{ + nouveau_grobj_free(&screen->swzsurf); + nouveau_grobj_free(&screen->sifm); + nouveau_grobj_free(&screen->rect); + nouveau_grobj_free(&screen->rop); + nouveau_grobj_free(&screen->patt); + nouveau_grobj_free(&screen->surf2d); + nouveau_grobj_free(&screen->m2mf); + nouveau_notifier_free(&screen->ntfy); +} + +GLboolean +nv04_surface_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + const unsigned chipset = screen->device->chipset; + unsigned handle = 0x88000000, class; + int ret; + + /* Notifier object. */ + ret = nouveau_notifier_alloc(chan, handle++, 1, &screen->ntfy); + if (ret) + goto fail; + + /* Memory to memory format. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_MEMORY_TO_MEMORY_FORMAT, + &screen->m2mf); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + /* Context surfaces 2D. */ + if (chan->device->chipset < 0x10) + class = NV04_CONTEXT_SURFACES_2D; + else + class = NV10_CONTEXT_SURFACES_2D; + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->surf2d); + if (ret) + goto fail; + + /* Raster op. */ + ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP, + &screen->rop); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_ROP, 1); + OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */ + + /* Image pattern. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN, + &screen->patt); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); + OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, ~0); + OUT_RING (chan, ~0); + + /* GDI rectangle text. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT, + &screen->rect); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, screen->surf2d->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1); + OUT_RING (chan, screen->rop->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); + OUT_RING (chan, screen->patt->handle); + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); + BEGIN_RING(chan, screen->rect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + /* Swizzled surface. */ + switch (chan->device->chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->swzsurf); + if (ret) + goto fail; + + /* Scaled image from memory. */ + switch (chan->device->chipset & 0xf0) { + case 0x10: + case 0x20: + class = NV10_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x30: + class = NV30_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x40: + case 0x60: + class = NV40_SCALED_IMAGE_FROM_MEMORY; + break; + default: + class = NV04_SCALED_IMAGE_FROM_MEMORY; + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->sifm); + if (ret) + goto fail; + + if (chipset >= 0x10) { + BEGIN_RING(chan, screen->sifm, + NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1); + OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + } + + return GL_TRUE; + +fail: + nv04_surface_takedown(screen); + return GL_FALSE; +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c new file mode 100644 index 0000000000..d1afa87c8a --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +static void +nv10_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer( + ctx->DrawBuffer); + + nouveau_validate_framebuffer(ctx); + + /* Clear the LMA depth buffer, if present. */ + if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask && + nfb->lma_bo) { + struct nouveau_surface *s = &to_nouveau_renderbuffer( + nfb->base._DepthBuffer->Wrapped)->surface; + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_FILL_VALUE, 1); + OUT_RING(chan, pack_zs_f(s->format, ctx->Depth.Clear, 0)); + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_CLEAR, 1); + OUT_RING(chan, 1); + } + + nouveau_clear(ctx, buffers); +} + +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureLevels = 12; + ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + ctx->Driver.Clear = nv10_clear; + + nv10_render_init(ctx); + + return ctx; +} + +void +nv10_context_destroy(GLcontext *ctx) +{ + nv10_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_driver.h b/src/mesa/drivers/dri/nouveau/nv10_driver.h new file mode 100644 index 0000000000..2a1ef7b08e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_driver.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV10_DRIVER_H__ +#define __NV10_DRIVER_H__ + +#define NV10_TEXTURE_UNITS 2 + +/* nv10_screen.c */ +GLboolean +nv10_screen_init(struct nouveau_screen *screen); + +/* nv10_context.c */ +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv10_context_destroy(GLcontext *ctx); + +/* nv10_render.c */ +void +nv10_render_init(GLcontext *ctx); + +void +nv10_render_destroy(GLcontext *ctx); + +/* nv10_state_fb.c */ +void +nv10_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv10_emit_render_mode(GLcontext *ctx, int emit); + +void +nv10_emit_scissor(GLcontext *ctx, int emit); + +void +nv10_emit_viewport(GLcontext *ctx, int emit); + +/* nv10_state_polygon.c */ +void +nv10_emit_cull_face(GLcontext *ctx, int emit); + +void +nv10_emit_front_face(GLcontext *ctx, int emit); + +void +nv10_emit_line_mode(GLcontext *ctx, int emit); + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit); + +void +nv10_emit_point_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit); + +/* nv10_state_raster.c */ +void +nv10_emit_alpha_func(GLcontext *ctx, int emit); + +void +nv10_emit_blend_color(GLcontext *ctx, int emit); + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit); + +void +nv10_emit_blend_func(GLcontext *ctx, int emit); + +void +nv10_emit_color_mask(GLcontext *ctx, int emit); + +void +nv10_emit_depth(GLcontext *ctx, int emit); + +void +nv10_emit_dither(GLcontext *ctx, int emit); + +void +nv10_emit_index_mask(GLcontext *ctx, int emit); + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit); + +void +nv10_emit_shade_model(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit); + +/* nv10_state_frag.c */ +void +nv10_emit_tex_env(GLcontext *ctx, int emit); + +void +nv10_emit_frag(GLcontext *ctx, int emit); + +/* nv10_state_tex.c */ +void +nv10_emit_tex_gen(GLcontext *ctx, int emit); + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit); + +/* nv10_state_tnl.c */ +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]); + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]); + +void +nv10_get_shininess_coeff(float s, float k[6]); + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv10_emit_color_material(GLcontext *ctx, int emit); + +void +nv10_emit_fog(GLcontext *ctx, int emit); + +void +nv10_emit_light_enable(GLcontext *ctx, int emit); + +void +nv10_emit_light_model(GLcontext *ctx, int emit); + +void +nv10_emit_light_source(GLcontext *ctx, int emit); + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv10_emit_material_specular(GLcontext *ctx, int emit); + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv10_emit_modelview(GLcontext *ctx, int emit); + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit); + +void +nv10_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv10_render.c b/src/mesa/drivers/dri/nouveau/nv10_render.c new file mode 100644 index 0000000000..54245ea6ba --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_render.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +#define NUM_VERTEX_ATTRS 8 + +static void +nv10_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv10_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV10TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 1, + .imm_method = NV10TCL_VERTEX_COL_4F_R, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 2, + .imm_method = NV10TCL_VERTEX_COL2_3F_R, + .imm_fields = 3, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 3, + .imm_method = NV10TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 4, + .imm_method = NV10TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 5, + .imm_method = NV10TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 7, + .imm_method = NV10TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv10_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV10TCL_VTXFMT_TYPE_FLOAT; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return NV10TCL_VTXFMT_TYPE_SHORT; + case GL_UNSIGNED_BYTE: + return NV10TCL_VTXFMT_TYPE_BYTE_RGBA; + default: + assert(0); + } +} + +static void +nv10_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + if (attr == VERT_ATTRIB_POS && a->fields == 4) + hw_format |= NV10TCL_VTXFMT_POS_HOMOGENEOUS; + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv10_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_markl(bctx, celsius, + NV10TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_VALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *celsius = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, celsius, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv10_##x +#include "nouveau_render_t.c" diff --git a/src/mesa/drivers/dri/nouveau/nv10_screen.c b/src/mesa/drivers/dri/nouveau/nv10_screen.c new file mode 100644 index 0000000000..8665ad1410 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_screen.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" + +static const struct nouveau_driver nv10_driver; + +static void +nv10_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *celsius = screen->eng3d; + const unsigned chipset = screen->device->chipset; + int i; + + BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1); + OUT_RING(chan, screen->ntfy->handle); + + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 3); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, chan->gart->handle); + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + + for (i = 1; i < 8; i++) { + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, 0x290, 1); + OUT_RING(chan, 0x10 << 16 | 1); + BEGIN_RING(chan, celsius, 0x3f4, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + if (chipset >= 0x17) { + BEGIN_RING(chan, celsius, NV17TCL_DMA_IN_MEMORY4, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, 0xd84, 1); + OUT_RING(chan, 0x3); + + BEGIN_RING(chan, celsius, NV17TCL_COLOR_MASK_ENABLE, 1); + OUT_RING(chan, 1); + } + + if (chipset >= 0x11) { + BEGIN_RING(chan, celsius, 0x120, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 1); + OUT_RING(chan, 2); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + /* Set state */ + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0x8006); + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1d01); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, 0x201); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, 0x1b02); + OUT_RING(chan, 0x1b02); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); + OUT_RING(chan, 0x405); + OUT_RING(chan, 0x901); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8); + for (i = 0; i < 8; i++) + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_TX_MATRIX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RING(chan, 0x3fc00000); /* -1.50 */ + OUT_RING(chan, 0xbdb8aa0a); /* -0.09 */ + OUT_RING(chan, 0); /* 0.00 */ + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2); + OUT_RING(chan, 0x802); + OUT_RING(chan, 2); + /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when + * using texturing, except when using the texture matrix + */ + BEGIN_RING(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); + OUT_RING(chan, 6); + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, 0x01010101); + + /* Set vertex component */ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1); + OUT_RINGf(chan, 0.0); + BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + OUT_RING(chan, 1); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); + OUT_RING(chan, 0.0); + OUT_RINGf(chan, 16777216.0); + + FIRE_RING(chan); +} + +GLboolean +nv10_screen_init(struct nouveau_screen *screen) +{ + unsigned chipset = screen->device->chipset; + unsigned celsius_class; + int ret; + + screen->driver = &nv10_driver; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + if (chipset >= 0x17) + celsius_class = NV17TCL; + else if (chipset >= 0x11) + celsius_class = NV11TCL; + else + celsius_class = NV10TCL; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, celsius_class, + &screen->eng3d); + if (ret) + return GL_FALSE; + + nv10_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv10_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv10_driver = { + .screen_destroy = nv10_screen_destroy, + .context_create = nv10_context_create, + .context_destroy = nv10_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_color_mask, + nv10_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv10_emit_framebuffer, + nv10_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv10_emit_light_model, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv10_emit_logic_opcode, + nv10_emit_material_ambient, + nouveau_emit_nothing, + nv10_emit_material_diffuse, + nouveau_emit_nothing, + nv10_emit_material_specular, + nouveau_emit_nothing, + nv10_emit_material_shininess, + nouveau_emit_nothing, + nv10_emit_modelview, + nv10_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv10_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_obj, + nv10_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_viewport + }, + .num_emit = NUM_NOUVEAU_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_fb.c b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c new file mode 100644 index 0000000000..05c36b4f8f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x0; + default: + assert(0); + } +} + +static void +setup_lma_buffer(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, LMA_DEPTH); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb); + unsigned pitch = align(fb->Width, 128), + height = align(fb->Height, 2), + size = pitch * height; + + if (!nfb->lma_bo || nfb->lma_bo->size != size) { + nouveau_bo_ref(NULL, &nfb->lma_bo); + nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_VRAM, 0, size, + &nfb->lma_bo); + } + + nouveau_bo_markl(bctx, celsius, NV17TCL_LMA_DEPTH_BUFFER_OFFSET, + nfb->lma_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_WINDOW_X, 4); + OUT_RINGf(chan, - 1792); + OUT_RINGf(chan, - 2304 + fb->Height); + OUT_RINGf(chan, fb->_DepthMaxF / 2); + OUT_RINGf(chan, 0); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING(chan, pitch); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_ENABLE, 1); + OUT_RING(chan, 1); +} + +void +nv10_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* At least nv11 seems to get sad if we don't do this before + * swapping RTs.*/ + if (context_chipset(ctx) < 0x17) { + int i; + + for (i = 0; i < 6; i++) { + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + } + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + + if (context_chipset(ctx) >= 0x17) + setup_lma_buffer(ctx); + } + + BEGIN_RING(chan, celsius, NV10TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv10_emit_render_mode(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); +} + +void +nv10_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + a[0] -= 2048; + a[1] -= 2048; + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16 | 0x08000800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16 | 0x08000800); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_frag.c b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c new file mode 100644 index 0000000000..c1df26ecce --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#define RC_IN_SHIFT_A 24 +#define RC_IN_SHIFT_B 16 +#define RC_IN_SHIFT_C 8 +#define RC_IN_SHIFT_D 0 +#define RC_IN_SHIFT_E 56 +#define RC_IN_SHIFT_F 48 +#define RC_IN_SHIFT_G 40 + +#define RC_IN_SOURCE(source) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_INPUT_##source) +#define RC_IN_USAGE(usage) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE_##usage) +#define RC_IN_MAPPING(mapping) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_MAPPING_##mapping) + +#define RC_OUT_BIAS NV10TCL_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF +#define RC_OUT_SCALE_1 NV10TCL_RC_OUT_RGB_SCALE_NONE +#define RC_OUT_SCALE_2 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_TWO +#define RC_OUT_SCALE_4 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_FOUR + +/* Make the combiner do: spare0_i = A_i * B_i */ +#define RC_OUT_AB NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 +/* spare0_i = dot3(A, B) */ +#define RC_OUT_DOT_AB (NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 | \ + NV10TCL_RC_OUT_RGB_AB_DOT_PRODUCT) +/* spare0_i = A_i * B_i + C_i * D_i */ +#define RC_OUT_SUM NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE0 + +struct combiner_state { + GLcontext *ctx; + int unit; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint64_t in; + uint32_t out; +}; + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, ctx, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->ctx = ctx; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->in = (rc)->out = 0; \ + } while (0) + +/* Get the RC input source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_input_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return RC_IN_SOURCE(TEXTURE0) + rc->unit; + + case GL_TEXTURE0: + return RC_IN_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return RC_IN_SOURCE(TEXTURE1); + + case GL_TEXTURE2: + return RC_IN_SOURCE(TEXTURE2); + + case GL_TEXTURE3: + return RC_IN_SOURCE(TEXTURE3); + + case GL_CONSTANT: + return context_chipset(rc->ctx) >= 0x20 ? + RC_IN_SOURCE(CONSTANT_COLOR0) : + RC_IN_SOURCE(CONSTANT_COLOR0) + rc->unit; + + case GL_PRIMARY_COLOR: + return RC_IN_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? RC_IN_SOURCE(SPARE0) + : RC_IN_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the RC input mapping for the specified argument, possibly + * inverted or biased. */ +#define INVERT 0x1 +#define HALF_BIAS 0x2 + +static uint32_t +get_input_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + map |= RC_IN_USAGE(RGB); + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= RC_IN_USAGE(ALPHA); + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_INVERT) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NORMAL) : + RC_IN_MAPPING(UNSIGNED_IDENTITY)); + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_IDENTITY) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NEGATE) : + RC_IN_MAPPING(UNSIGNED_INVERT)); + break; + } + + return map; +} + +/* Bind the RC input variable <var> to the EXT_texture_env_combine + * argument <arg>, possibly inverted or biased. */ +#define INPUT_ARG(rc, var, arg, flags) \ + (rc)->in |= (get_input_mapping(rc, arg, flags) | \ + get_input_source(rc, arg)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to the RC source <src>. */ +#define INPUT_SRC(rc, var, src, chan) \ + (rc)->in |= (RC_IN_SOURCE(src) | \ + RC_IN_USAGE(chan)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to a constant +/-1 */ +#define INPUT_ONE(rc, var, flags) \ + (rc)->in |= (RC_IN_SOURCE(ZERO) | \ + (flags & INVERT ? RC_IN_MAPPING(EXPAND_NORMAL) : \ + RC_IN_MAPPING(UNSIGNED_INVERT))) << RC_IN_SHIFT_##var + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_MODULATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 1, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_ADD: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM; + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM | RC_OUT_BIAS; + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 2, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ARG(rc, D, 2, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_SUBTRACT: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + INPUT_ARG(rc, A, 0, HALF_BIAS); + INPUT_ARG(rc, B, 1, HALF_BIAS); + + rc->out = RC_OUT_DOT_AB | RC_OUT_SCALE_4; + + assert(!rc->logscale); + break; + + default: + assert(0); + } + + switch (rc->logscale) { + case 0: + rc->out |= RC_OUT_SCALE_1; + break; + case 1: + rc->out |= RC_OUT_SCALE_2; + break; + case 2: + rc->out |= RC_OUT_SCALE_4; + break; + default: + assert(0); + } +} + +/* Write the register combiner state out to the hardware. */ +static void +nv10_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + /* Enable the combiners we're going to need. */ + if (i == 1) { + if (rc_c->out || rc_a->out) + rc_c->out |= 0x5 << 27; + else + rc_c->out |= 0x3 << 27; + } + + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_COLOR(i), 1); + OUT_RING(chan, rc_const); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); +} + +static void +nv10_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); +} + +static void +nv20_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_CONSTANT_COLOR0(i), 1); + OUT_RING(chan, rc_const); +} + +static void +nv20_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_ENABLE, 1); + OUT_RING(chan, n); +} + +void +nv10_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct combiner_state rc_a, rc_c; + uint32_t rc_const; + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(RGB, ctx, &rc_c, i); + + if (rc_c.mode == GL_DOT3_RGBA) + rc_a = rc_c; + else + INIT_COMBINER(A, ctx, &rc_a, i); + + setup_combiner(&rc_c); + setup_combiner(&rc_a); + + rc_const = pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[i].EnvColor); + + } else { + rc_a.in = rc_a.out = rc_c.in = rc_c.out = rc_const = 0; + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + else + nv10_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + + context_dirty(ctx, FRAG); +} + +void +nv10_emit_frag(GLcontext *ctx, int emit) +{ + struct combiner_state rc = {}; + int n = log2i(ctx->Texture._EnabledUnits) + 1; + + /* + * The final fragment value equation is something like: + * x_i = A_i * B_i + (1 - A_i) * C_i + D_i + * x_alpha = G_alpha + * where D_i = E_i * F_i, i one of {red, green, blue}. + */ + if (ctx->Fog.ColorSumEnabled || ctx->Light.Enabled) { + INPUT_SRC(&rc, D, E_TIMES_F, RGB); + INPUT_SRC(&rc, F, SECONDARY_COLOR, RGB); + } + + if (ctx->Fog.Enabled) { + INPUT_SRC(&rc, A, FOG, ALPHA); + INPUT_SRC(&rc, C, FOG, RGB); + INPUT_SRC(&rc, E, FOG, ALPHA); + } else { + INPUT_ONE(&rc, A, 0); + INPUT_ONE(&rc, C, 0); + INPUT_ONE(&rc, E, 0); + } + + if (ctx->Texture._EnabledUnits) { + INPUT_SRC(&rc, B, SPARE0, RGB); + INPUT_SRC(&rc, G, SPARE0, ALPHA); + } else { + INPUT_SRC(&rc, B, PRIMARY_COLOR, RGB); + INPUT_SRC(&rc, G, PRIMARY_COLOR, ALPHA); + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_final(ctx, &rc, n); + else + nv10_load_final(ctx, &rc, n); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c new file mode 100644 index 0000000000..deddca1011 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_cull_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLenum mode = ctx->Polygon.CullFaceMode; + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.CullFlag ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 1); + OUT_RING(chan, (mode == GL_FRONT ? NV10TCL_CULL_FACE_FRONT : + mode == GL_BACK ? NV10TCL_CULL_FACE_BACK : + NV10TCL_CULL_FACE_FRONT_AND_BACK)); +} + +void +nv10_emit_front_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_FRONT_FACE, 1); + OUT_RING(chan, ctx->Polygon.FrontFace == GL_CW ? + NV10TCL_FRONT_FACE_CW : NV10TCL_FRONT_FACE_CCW); +} + +void +nv10_emit_line_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLboolean smooth = ctx->Line.SmoothFlag && + ctx->Hint.LineSmooth == GL_NICEST; + + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, MAX2(smooth ? 0 : 1, + ctx->Line.Width) * 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, smooth ? 1 : 0); +} + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Point.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.FrontMode)); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.BackMode)); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, ctx->Polygon.OffsetPoint ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetLine ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetFill ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RINGf(chan, ctx->Polygon.OffsetFactor); + OUT_RINGf(chan, ctx->Polygon.OffsetUnits); +} + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_raster.c b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c new file mode 100644 index 0000000000..68882ef05f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_alpha_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.AlphaEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, nvgl_comparison_op(ctx->Color.AlphaFunc)); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.AlphaRef)); +} + +void +nv10_emit_blend_color(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.BlendColor[3]) << 24 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[0]) << 16 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[1]) << 8 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[2]) << 0); +} + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.BlendEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_EQUATION, 1); + OUT_RING(chan, nvgl_blend_eqn(ctx->Color.BlendEquationRGB)); +} + +void +nv10_emit_blend_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 2); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendSrcRGB)); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendDstRGB)); +} + +void +nv10_emit_color_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, ((ctx->Color.ColorMask[0][3] ? 1 << 24 : 0) | + (ctx->Color.ColorMask[0][0] ? 1 << 16 : 0) | + (ctx->Color.ColorMask[0][1] ? 1 << 8 : 0) | + (ctx->Color.ColorMask[0][2] ? 1 << 0 : 0))); +} + +void +nv10_emit_depth(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Test ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Mask ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, nvgl_comparison_op(ctx->Depth.Func)); +} + +void +nv10_emit_dither(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING(chan, ctx->Color.DitherFlag ? 1 : 0); +} + +void +nv10_emit_index_mask(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + assert(!ctx->Color.ColorLogicOpEnabled + || context_chipset(ctx) >= 0x11); + + BEGIN_RING(chan, celsius, NV11TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} + +void +nv10_emit_shade_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 1); + OUT_RING(chan, ctx->Light.ShadeModel == GL_SMOOTH ? + NV10TCL_SHADE_MODEL_SMOOTH : NV10TCL_SHADE_MODEL_FLAT); +} + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING(chan, ctx->Stencil.Enabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_FUNC_FUNC, 3); + OUT_RING(chan, nvgl_comparison_op(ctx->Stencil.Function[0])); + OUT_RING(chan, ctx->Stencil.Ref[0]); + OUT_RING(chan, ctx->Stencil.ValueMask[0]); +} + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 1); + OUT_RING(chan, ctx->Stencil.WriteMask[0]); +} + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_OP_FAIL, 3); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.FailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZFailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZPassFunc[0])); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c new file mode 100644 index 0000000000..e5d4f3d18d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +void +nv10_emit_tex_gen(GLcontext *ctx, int emit) +{ +} + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV10TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV10TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV10TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV10TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV10TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = nvgl_wrap_mode(t->WrapT) << 28 + | nvgl_wrap_mode(t->WrapS) << 24 + | ti->HeightLog2 << 20 + | ti->WidthLog2 << 16 + | get_tex_format(ti) + | 5 << 4 | 1 << 12; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 28 + | nvgl_filter_mode(t->MinFilter) << 24; + + tx_enable = NV10TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV10TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, celsius, NV10TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV10TCL_TX_FORMAT_DMA0, + NV10TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, celsius, NV10TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, celsius, NV10TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); +} + diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c new file mode 100644 index 0000000000..6db14d83b8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c @@ -0,0 +1,514 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV10TCL_COLOR_MATERIAL_EMISSION; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV10TCL_COLOR_MATERIAL_AMBIENT; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV10TCL_COLOR_MATERIAL_DIFFUSE; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV10TCL_COLOR_MATERIAL_SPECULAR; + + return ret; +} + +void +nv10_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV10TCL_FOG_MODE_LINEAR; + case GL_EXP: + return NV10TCL_FOG_MODE_EXP; + case GL_EXP2: + return NV10TCL_FOG_MODE_EXP2; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV10TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV10TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]) +{ + struct gl_fog_attrib *f = &ctx->Fog; + + switch (f->Mode) { + case GL_LINEAR: + k[0] = 2 + f->Start / (f->End - f->Start); + k[1] = -1 / (f->End - f->Start); + break; + + case GL_EXP: + k[0] = 1.5; + k[1] = -0.09 * f->Density; + break; + + case GL_EXP2: + k[0] = 1.5; + k[1] = -0.21 * f->Density; + break; + + default: + assert(0); + } + + k[2] = 0; +} + +void +nv10_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 4); + OUT_RING(chan, get_fog_mode(f->Mode)); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + + context_dirty(ctx, FRAG); +} + +static inline unsigned +get_light_mode(struct gl_light *l) +{ + if (l->Enabled) { + if (l->_Flags & LIGHT_SPOT) + return NV10TCL_ENABLED_LIGHTS_0_DIRECTIONAL; + else if (l->_Flags & LIGHT_POSITIONAL) + return NV10TCL_ENABLED_LIGHTS_0_POSITIONAL; + else + return NV10TCL_ENABLED_LIGHTS_0_NONPOSITIONAL; + } else { + return NV10TCL_ENABLED_LIGHTS_0_DISABLED; + } +} + +void +nv10_emit_light_enable(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + uint32_t en_lights = 0; + int i; + + if (nctx->fallback != HWTNL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, 0); + return; + } + + for (i = 0; i < MAX_LIGHTS; i++) + en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i; + + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, en_lights); + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, ctx->Light.Enabled ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, ctx->Transform.Normalize ? 1 : 0); +} + +void +nv10_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV10TCL_LIGHT_MODEL_LOCAL_VIEWER : 0) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV10TCL_LIGHT_MODEL_SEPARATE_SPECULAR : 0))); +} + +static float +get_shine(const float p[], float x) +{ + const int n = 15; + const float *y = &p[1]; + float f = (n - 1) * (1 - 1 / (1 + p[0] * x)) + / (1 - 1 / (1 + p[0] * 1024)); + int i = f; + + /* Linear interpolation in f-space (Faster and somewhat more + * accurate than x-space). */ + if (x == 0) + return y[0]; + else if (i > n - 2) + return y[n - 1]; + else + return y[i] + (y[i + 1] - y[i]) * (f - i); +} + +static const float nv10_spot_params[2][16] = { + { 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06, + -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 }, + { 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06, + 3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 }, +}; + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]) +{ + float e = l->SpotExponent; + float a0, b0, a1, a2, b2, a3; + + if (e > 0) + a0 = -1 - 5.36e-3 / sqrt(e); + else + a0 = -1; + b0 = 1 / (1 + 0.273 * e); + + a1 = get_shine(nv10_spot_params[0], e); + + a2 = get_shine(nv10_spot_params[1], e); + b2 = 1 / (1 + 0.273 * e); + + a3 = 0.9 + 0.278 * e; + + if (l->SpotCutoff > 0) { + float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff)); + + k[0] = MAX2(0, a0 + b0 * cutoff); + k[1] = a1; + k[2] = a2 + b2 * cutoff; + k[3] = - cutoff * l->_NormSpotDirection[0]; + k[4] = - cutoff * l->_NormSpotDirection[1]; + k[5] = - cutoff * l->_NormSpotDirection[2]; + k[6] = 1 - cutoff; + + } else { + k[0] = b0; + k[1] = a1; + k[2] = a2 + b2; + k[3] = - l->_NormSpotDirection[0]; + k[4] = - l->_NormSpotDirection[1]; + k[5] = - l->_NormSpotDirection[2]; + k[6] = -1; + } +} + +void +nv10_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, celsius, + NV10TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr)) + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT)) { + COPY_3V(c_scene, ctx->Light.Model.Ambient); + COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]); + + } else if (USE_COLOR_MATERIAL(EMISSION)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT], + ctx->Light.Model.Ambient); + ZERO_3V(c_factor); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[0]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL_AMBIENT_R, 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_R, 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? + l->Ambient : + l->_MatAmbient[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_AMBIENT_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + struct gl_light *l; + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_A, 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? + l->Diffuse : + l->_MatDiffuse[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIFFUSE_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_specular(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? + l->Specular : + l->_MatSpecular[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPECULAR_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +static const float nv10_shininess_param[6][16] = { + { 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00, + -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 }, + { 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18, + -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 }, + { 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15, + 3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 }, + { 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04, + 0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 }, + { 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05, + -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 }, + { 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15, + 3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 }, +}; + +void +nv10_get_shininess_coeff(float s, float k[6]) +{ + int i; + + for (i = 0; i < 6; i++) + k[i] = get_shine(nv10_shininess_param[i], s); +} + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024), + k); + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_SHININESS(0), 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv10_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, celsius, NV10TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, celsius, + NV10TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c new file mode 100644 index 0000000000..698b83431b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_context.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nv20_driver.h" + +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 8; + ctx->Const.MaxTextureLodBias = 15; + + nv20_render_init(ctx); + + return ctx; +} + +void +nv20_context_destroy(GLcontext *ctx) +{ + nv20_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_driver.h b/src/mesa/drivers/dri/nouveau/nv20_driver.h new file mode 100644 index 0000000000..2de18ee4af --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_driver.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV20_DRIVER_H__ +#define __NV20_DRIVER_H__ + +enum { + NOUVEAU_STATE_TEX_SHADER = NUM_NOUVEAU_STATE, + NUM_NV20_STATE +}; + +#define NV20_TEXTURE_UNITS 4 + +/* nv20_screen.c */ +GLboolean +nv20_screen_init(struct nouveau_screen *screen); + +/* nv20_context.c */ +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv20_context_destroy(GLcontext *ctx); + +/* nv20_render.c */ +void +nv20_render_init(GLcontext *ctx); + +void +nv20_render_destroy(GLcontext *ctx); + +/* nv20_state_fb.c */ +void +nv20_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv20_emit_viewport(GLcontext *ctx, int emit); + +/* nv20_state_polygon.c */ +void +nv20_emit_point_mode(GLcontext *ctx, int emit); + +/* nv20_state_raster.c */ +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit); + +/* nv20_state_tex.c */ +void +nv20_emit_tex_obj(GLcontext *ctx, int emit); + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit); + +/* nv20_state_tnl.c */ +void +nv20_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv20_emit_color_material(GLcontext *ctx, int emit); + +void +nv20_emit_fog(GLcontext *ctx, int emit); + +void +nv20_emit_light_model(GLcontext *ctx, int emit); + +void +nv20_emit_light_source(GLcontext *ctx, int emit); + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv20_emit_material_specular(GLcontext *ctx, int emit); + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv20_emit_modelview(GLcontext *ctx, int emit); + +void +nv20_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv20_render.c b/src/mesa/drivers/dri/nouveau/nv20_render.c new file mode 100644 index 0000000000..a696ac107f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_render.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +#define NUM_VERTEX_ATTRS 16 + +static void +nv20_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv20_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV20TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 2, + .imm_method = NV20TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 3, + .imm_method = NV20TCL_VERTEX_COL_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 4, + .imm_method = NV20TCL_VERTEX_COL2_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 5, + .imm_method = NV20TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 9, + .imm_method = NV20TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 10, + .imm_method = NV20TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX2] = { + .vbo_index = 11, + .imm_method = NV20TCL_VERTEX_TX2_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX3] = { + .vbo_index = 12, + .imm_method = NV20TCL_VERTEX_TX3_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC1] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC3] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC5] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC7] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC9] = { + .emit = nv20_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV20TCL_VTXFMT_TYPE_FLOAT; + case GL_UNSIGNED_SHORT: + return NV20TCL_VTXFMT_TYPE_USHORT; + case GL_UNSIGNED_BYTE: + return NV20TCL_VTXFMT_TYPE_UBYTE; + default: + assert(0); + } +} + +static void +nv20_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv20_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_mark(bctx, kelvin, + NV20TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, 0, + 0, NV20TCL_VTXBUF_ADDRESS_DMA1, + NOUVEAU_BO_LOW | NOUVEAU_BO_OR | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTX_CACHE_INVALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *kelvin = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_VERTEX_BATCH, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, kelvin, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv20_##x +#include "nouveau_render_t.c" diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_screen.c index 5b80af2d22..1d29fc9976 100644 --- a/src/gallium/drivers/nv20/nv20_context.c +++ b/src/mesa/drivers/dri/nouveau/nv20_screen.c @@ -1,65 +1,69 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" - -#include "nv20_context.h" -#include "nv20_screen.h" +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +static const struct nouveau_driver nv20_driver; static void -nv20_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) +nv20_hwctx_init(struct nouveau_screen *screen) { - struct nv20_context *nv20 = nv20_context(pipe); - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv20->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -static void -nv20_destroy(struct pipe_context *pipe) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - if (nv20->draw) - draw_destroy(nv20->draw); - - FREE(nv20); -} - -static void nv20_init_hwctx(struct nv20_context *nv20) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *kelvin = screen->eng3d; + const unsigned chipset = screen->device->chipset; int i; - float projectionmatrix[16]; - const boolean is_nv25tcl = (kelvin->grclass == NV25TCL); BEGIN_RING(chan, kelvin, NV20TCL_DMA_NOTIFY, 1); - OUT_RING (chan, screen->sync->handle); + OUT_RING (chan, screen->ntfy->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_TEXTURE0, 2); OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->gart->handle); /* TEXTURE1 */ + OUT_RING (chan, chan->gart->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 2); OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); /* ZETA */ + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_QUERY, 1); - OUT_RING (chan, 0); /* renouveau: beef0351, unique */ + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); OUT_RING (chan, 0); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); - OUT_RING (chan, (0xfff << 16) | 0x0); + OUT_RING (chan, 0xfff << 16 | 0x0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); - OUT_RING (chan, (0xfff << 16) | 0x0); + OUT_RING (chan, 0xfff << 16 | 0x0); for (i = 1; i < NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1); @@ -76,7 +80,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 1.0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1); OUT_RING (chan, NV20TCL_TX_RCOMP_LEQUAL | 0xdb0); } else { @@ -87,7 +91,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) } BEGIN_RING(chan, kelvin, 0x290, 1); - OUT_RING (chan, (0x10 << 16) | 1); + OUT_RING (chan, 0x10 << 16 | 1); BEGIN_RING(chan, kelvin, 0x9fc, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x1d80, 1); @@ -99,7 +103,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RINGf (chan, 1.0); OUT_RINGf (chan, 0.0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x1d88, 1); OUT_RING (chan, 3); @@ -108,21 +112,13 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY8, 1); OUT_RING (chan, chan->vram->handle); } + BEGIN_RING(chan, kelvin, NV20TCL_DMA_FENCE, 1); - OUT_RING (chan, 0); /* renouveau: beef1e10 */ + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x1e98, 1); OUT_RING (chan, 0); -#if 0 - if (is_nv25tcl) { - BEGIN_RING(chan, NvSub3D, NV25TCL_DMA_IN_MEMORY4, 2); - OUT_RING (chan, NvDmaTT); /* renouveau: beef0202 */ - OUT_RING (chan, NvDmaFB); /* renouveau: beef0201 */ - BEGIN_RING(chan, NvSub3D, NV20TCL_DMA_TEXTURE1, 1); - OUT_RING (chan, NvDmaTT); /* renouveau: beef0202 */ - } -#endif BEGIN_RING(chan, kelvin, NV20TCL_NOTIFY, 1); OUT_RING (chan, 0); @@ -131,53 +127,35 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 1); OUT_RING (chan, 2); -/* error: ILLEGAL_MTHD, PROTECTION_FAULT - BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 512.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); -*/ - - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x022c, 2); OUT_RING (chan, 0x280); OUT_RING (chan, 0x07d28000); - } -/* * illegal method, protection fault - BEGIN_RING(chan, NvSub3D, 0x1c2c, 1); - OUT_RING (chan, 0); */ - - if (is_nv25tcl) { BEGIN_RING(chan, kelvin, 0x1da4, 1); OUT_RING (chan, 0); } -/* * crashes with illegal method, protection fault - BEGIN_RING(chan, NvSub3D, 0x1c18, 1); - OUT_RING (chan, 0x200); */ - BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); - OUT_RING (chan, (0 << 16) | 0); - OUT_RING (chan, (0 << 16) | 0); - - /* *** Set state *** */ + OUT_RING (chan, 0 << 16 | 0); + OUT_RING (chan, 0 << 16 | 0); BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2); OUT_RING (chan, NV20TCL_ALPHA_FUNC_FUNC_ALWAYS); - OUT_RING (chan, 0); /* NV20TCL_ALPHA_FUNC_REF */ + OUT_RING (chan, 0); - for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; ++i) { + for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); OUT_RING (chan, 0); } + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1); OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(0), 4); OUT_RING (chan, 0x30d410d0); OUT_RING (chan, 0); @@ -211,9 +189,9 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 0); OUT_RING (chan, 0x40002000); OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1); OUT_RING (chan, 0xffff0000); - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1); @@ -223,13 +201,13 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 4); OUT_RING (chan, NV20TCL_BLEND_FUNC_SRC_ONE); OUT_RING (chan, NV20TCL_BLEND_FUNC_DST_ZERO); - OUT_RING (chan, 0); /* NV20TCL_BLEND_COLOR */ + OUT_RING (chan, 0); OUT_RING (chan, NV20TCL_BLEND_EQUATION_FUNC_ADD); BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7); OUT_RING (chan, 0xff); OUT_RING (chan, NV20TCL_STENCIL_FUNC_FUNC_ALWAYS); - OUT_RING (chan, 0); /* NV20TCL_STENCIL_FUNC_REF */ - OUT_RING (chan, 0xff); /* NV20TCL_STENCIL_FUNC_MASK */ + OUT_RING (chan, 0); + OUT_RING (chan, 0xff); OUT_RING (chan, NV20TCL_STENCIL_OP_FAIL_KEEP); OUT_RING (chan, NV20TCL_STENCIL_OP_ZFAIL_KEEP); OUT_RING (chan, NV20TCL_STENCIL_OP_ZPASS_KEEP); @@ -239,14 +217,14 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, NV20TCL_COLOR_LOGIC_OP_OP_COPY); BEGIN_RING(chan, kelvin, 0x17cc, 1); OUT_RING (chan, 0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x1d84, 1); OUT_RING (chan, 1); } BEGIN_RING(chan, kelvin, NV20TCL_LIGHTING_ENABLE, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_CONTROL, 1); - OUT_RING (chan, 0x00020000); + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); + OUT_RING (chan, NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL); BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); @@ -256,15 +234,15 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_NORMALIZE_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0), - NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE); - for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; ++i) { + NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE); + for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; i++) { OUT_RING(chan, 0xffffffff); } BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3); OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.POLYGON_OFFSET_LINE_ENABLE */ - OUT_RING (chan, 0); /* NV20TCL.POLYGON_OFFSET_FILL_ENABLE */ + OUT_RING (chan, 0); + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1); OUT_RING (chan, NV20TCL_DEPTH_FUNC_LESS); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1); @@ -273,29 +251,30 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2); OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); /* NV20TCL.POLYGON_OFFSET_UNITS */ + OUT_RINGf (chan, 0.0); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1); OUT_RING (chan, 1); - if (!is_nv25tcl) { + if (chipset < 0x25) { BEGIN_RING(chan, kelvin, 0x1d84, 1); OUT_RING (chan, 3); } BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); - if (!is_nv25tcl) { - OUT_RING (chan, 8); - } else { + if (chipset >= 0x25) OUT_RINGf (chan, 1.0); - } - if (!is_nv25tcl) { - BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.POINT_SMOOTH_ENABLE */ - } else { + else + OUT_RING (chan, 8); + + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x0a1c, 1); OUT_RING (chan, 0x800); + } else { + BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); } + BEGIN_RING(chan, kelvin, NV20TCL_LINE_WIDTH, 1); OUT_RING (chan, 8); BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1); @@ -314,33 +293,45 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, NV20TCL_SHADE_MODEL_SMOOTH); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), 4 * NV20TCL_TX_GEN_S__SIZE); - for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; ++i) { + + BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), + 4 * NV20TCL_TX_GEN_S__SIZE); + for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; i++) OUT_RING(chan, 0); - } + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); OUT_RINGf (chan, 1.5); - OUT_RINGf (chan, -0.090168); /* NV20TCL.FOG_EQUATION_LINEAR */ - OUT_RINGf (chan, 0.0); /* NV20TCL.FOG_EQUATION_QUADRATIC */ + OUT_RINGf (chan, -0.090168); + OUT_RINGf (chan, 0.0); BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 2); OUT_RING (chan, NV20TCL_FOG_MODE_EXP_SIGNED); OUT_RING (chan, NV20TCL_FOG_COORD_FOG); BEGIN_RING(chan, kelvin, NV20TCL_FOG_ENABLE, 2); OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.FOG_COLOR */ + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_ENGINE, 1); OUT_RING (chan, NV20TCL_ENGINE_FIXED); - for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; ++i) { + for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1); OUT_RING (chan, 0); } BEGIN_RING(chan, kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15); - OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0); - OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); - OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); - for (i = 4; i < 16; ++i) { + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + for (i = 0; i < 12; i++) { OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); @@ -354,71 +345,139 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_CLEAR_VALUE, 1); OUT_RING (chan, 0); - memset(projectionmatrix, 0, sizeof(projectionmatrix)); - projectionmatrix[0*4+0] = 1.0; - projectionmatrix[1*4+1] = 1.0; - projectionmatrix[2*4+2] = 16777215.0; - projectionmatrix[3*4+3] = 1.0; - BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16); - for (i = 0; i < 16; i++) { - OUT_RINGf (chan, projectionmatrix[i]); - } - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2); OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 16777216.0); /* [0, 1] scaled approx to [0, 2^24] */ + OUT_RINGf (chan, 16777216.0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, 0.0); /* x-offset, w/2 + 1.031250 */ - OUT_RINGf (chan, 0.0); /* y-offset, h/2 + 0.030762 */ + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 16777215.0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_SCALE_X, 4); - OUT_RINGf (chan, 0.0); /* no effect?, w/2 */ - OUT_RINGf (chan, 0.0); /* no effect?, h/2 */ + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 16777215.0 * 0.5); OUT_RINGf (chan, 65535.0); - FIRE_RING (chan); + FIRE_RING(chan); } -struct pipe_context * -nv20_create(struct pipe_screen *pscreen, unsigned pctx_id) +GLboolean +nv20_screen_init(struct nouveau_screen *screen) { - struct nv20_screen *screen = nv20_screen(pscreen); - struct pipe_winsys *ws = pscreen->winsys; - struct nv20_context *nv20; - struct nouveau_winsys *nvws = screen->nvws; + unsigned chipset = screen->device->chipset; + unsigned kelvin_class; + int ret; - nv20 = CALLOC(1, sizeof(struct nv20_context)); - if (!nv20) - return NULL; - nv20->screen = screen; - nv20->pctx_id = pctx_id; + screen->driver = &nv20_driver; - nv20->nvws = nvws; + /* 2D engine */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; - nv20->pipe.winsys = ws; - nv20->pipe.screen = pscreen; - nv20->pipe.destroy = nv20_destroy; - nv20->pipe.draw_arrays = nv20_draw_arrays; - nv20->pipe.draw_elements = nv20_draw_elements; - nv20->pipe.clear = nv20_clear; - nv20->pipe.flush = nv20_flush; + /* 3D engine. */ + if (chipset >= 0x25) + kelvin_class = NV25TCL; + else + kelvin_class = NV20TCL; - nv20->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv20->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, kelvin_class, + &screen->eng3d); + if (ret) + return GL_FALSE; - nv20_init_surface_functions(nv20); - nv20_init_state_functions(nv20); + nv20_hwctx_init(screen); - nv20->draw = draw_create(); - assert(nv20->draw); - draw_set_rasterize_stage(nv20->draw, nv20_draw_vbuf_stage(nv20)); + return GL_TRUE; +} - nv20_init_hwctx(nv20); +static void +nv20_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); - return &nv20->pipe; + nv04_surface_takedown(screen); } +static const struct nouveau_driver nv20_driver = { + .screen_destroy = nv20_screen_destroy, + .context_create = nv20_context_create, + .context_destroy = nv20_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv10_emit_color_mask, + nv20_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv20_emit_framebuffer, + nv20_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv20_emit_light_model, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv20_emit_logic_opcode, + nv20_emit_material_ambient, + nv20_emit_material_ambient, + nv20_emit_material_diffuse, + nv20_emit_material_diffuse, + nv20_emit_material_specular, + nv20_emit_material_specular, + nv20_emit_material_shininess, + nv20_emit_material_shininess, + nv20_emit_modelview, + nv20_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv20_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_viewport, + nv20_emit_tex_shader + }, + .num_emit = NUM_NV20_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_fb.c b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c new file mode 100644 index 0000000000..869acd6e31 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x20; + default: + assert(0); + } +} + +void +nv20_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, kelvin, NV20TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the viewport/scissor state. */ + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv20_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16); + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c new file mode 100644 index 0000000000..3a320e2dac --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); + if (context_chipset(ctx) >= 0x25) + OUT_RINGf(chan, ctx->Point.Size); + else + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_raster.c b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c new file mode 100644 index 0000000000..b43b29bb23 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c new file mode 100644 index 0000000000..d01e91f8ee --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv20_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV20TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV20TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV20TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV20TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV20TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV20TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV20TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv20_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_wrap, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + + context_dirty(ctx, TEX_SHADER); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = ti->DepthLog2 << 28 + | ti->HeightLog2 << 24 + | ti->WidthLog2 << 20 + | get_tex_format(ti) + | NV20TCL_TX_FORMAT_DIMS_2D + | NV20TCL_TX_FORMAT_NO_BORDER + | 1 << 16; + + tx_wrap = nvgl_wrap_mode(t->WrapR) << 16 + | nvgl_wrap_mode(t->WrapT) << 8 + | nvgl_wrap_mode(t->WrapS) << 0; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 24 + | nvgl_filter_mode(t->MinFilter) << 16; + + tx_enable = NV20TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV20TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, kelvin, NV20TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV20TCL_TX_FORMAT_DMA0, + NV20TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, kelvin, NV20TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_WRAP(i), 1); + OUT_RING(chan, tx_wrap); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); + + context_dirty(ctx, TEX_SHADER); +} + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + uint32_t tx_shader_op = 0; + int i; + + for (i = 0; i < NV20_TEXTURE_UNITS; i++) { + if (!ctx->Texture.Unit[i]._ReallyEnabled) + continue; + + tx_shader_op |= NV20TCL_TX_SHADER_OP_TX0_TEXTURE_2D << 5 * i; + } + + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); + OUT_RING(chan, tx_shader_op); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c new file mode 100644 index 0000000000..0d566064f6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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 (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 COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +void +nv20_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_EMISSION_COL1; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_AMBIENT_COL1; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_DIFFUSE_COL1; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_SPECULAR_COL1; + + if (m & MAT_BIT_BACK_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_BACK_EMISSION_COL1; + if (m & MAT_BIT_BACK_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_BACK_AMBIENT_COL1; + if (m & MAT_BIT_BACK_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_BACK_DIFFUSE_COL1; + if (m & MAT_BIT_BACK_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_BACK_SPECULAR_COL1; + + return ret; +} + +void +nv20_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode_signed(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_SIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_SIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_SIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_mode_unsigned(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_UNSIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_UNSIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_UNSIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV20TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV20TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv20_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 4); + OUT_RING(chan, (source == GL_FOG_COORDINATE_EXT ? + get_fog_mode_signed(f->Mode) : + get_fog_mode_unsigned(f->Mode))); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); +} + +void +nv20_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV20TCL_LIGHT_MODEL_VIEWER_LOCAL : + NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV20TCL_LIGHT_MODEL_SEPARATE_SPECULAR : + 0))); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); + OUT_RING(chan, ctx->Light.Model.TwoSide ? 1 : 0); +} + +void +nv20_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr, side) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_##attr(side))) + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_scene[] = { NV20TCL_LIGHT_MODEL_FRONT_AMBIENT_R, + NV20TCL_LIGHT_MODEL_BACK_AMBIENT_R }; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_R, + NV20TCL_MATERIAL_FACTOR_BACK_R }; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT, side)) { + COPY_3V(c_scene, mat[MAT_ATTRIB_EMISSION(side)]); + COPY_3V(c_factor, ctx->Light.Model.Ambient); + + } else if (USE_COLOR_MATERIAL(EMISSION, side)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_AMBIENT(side)], + ctx->Light.Model.Ambient); + ASSIGN_3V(c_factor, 1, 1, 1); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[side]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, kelvin, m_scene[side], 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, kelvin, m_factor[side], 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_AMBIENT_R(i), + NV20TCL_LIGHT_BACK_AMBIENT_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT, side) ? + l->Ambient : + l->_MatAmbient[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_A, + NV20TCL_MATERIAL_FACTOR_BACK_A }; + struct gl_light *l; + + BEGIN_RING(chan, kelvin, m_factor[side], 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_DIFFUSE(side)][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_DIFFUSE_R(i), + NV20TCL_LIGHT_BACK_DIFFUSE_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE, side) ? + l->Diffuse : + l->_MatDiffuse[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_specular(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_SPECULAR_R(i), + NV20TCL_LIGHT_BACK_SPECULAR_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR, side) ? + l->Specular : + l->_MatSpecular[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SHININESS; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t mthd[] = { NV20TCL_FRONT_MATERIAL_SHININESS(0), + NV20TCL_BACK_MATERIAL_SHININESS(0) }; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_SHININESS(side)][0], 0, 1024), + k); + + BEGIN_RING(chan, kelvin, mthd[side], 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv20_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, kelvin, NV20TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, kelvin, + NV20TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv20_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index e389e1c87b..67e9240505 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/r128/r128_dd.c b/src/mesa/drivers/dri/r128/r128_dd.c index dfe47f2dd6..64dec70cdd 100644 --- a/src/mesa/drivers/dri/r128/r128_dd.c +++ b/src/mesa/drivers/dri/r128/r128_dd.c @@ -34,12 +34,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" -#include "r128_state.h" #include "r128_dd.h" -#include "swrast/swrast.h" #include "main/context.h" -#include "main/framebuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/r128/r128_lock.c b/src/mesa/drivers/dri/r128/r128_lock.c index 9bc3515b5a..c1fa068d1f 100644 --- a/src/mesa/drivers/dri/r128/r128_lock.c +++ b/src/mesa/drivers/dri/r128/r128_lock.c @@ -33,8 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_lock.h" -#include "r128_tex.h" -#include "r128_state.h" #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 80b265811e..ef6b5a35c4 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -37,7 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" #include "r128_span.h" -#include "r128_tris.h" #include "main/context.h" #include "main/imports.h" diff --git a/src/mesa/drivers/dri/r128/r128_span.c b/src/mesa/drivers/dri/r128/r128_span.c index 0413e5b4f1..2fbe93c590 100644 --- a/src/mesa/drivers/dri/r128/r128_span.c +++ b/src/mesa/drivers/dri/r128/r128_span.c @@ -35,9 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_context.h" #include "r128_ioctl.h" -#include "r128_state.h" #include "r128_span.h" -#include "r128_tex.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 2254a7a4ff..42f6dd7388 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -47,8 +47,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/r128/r128_tex.c b/src/mesa/drivers/dri/r128/r128_tex.c index f1be7cc1c4..24fbf8f519 100644 --- a/src/mesa/drivers/dri/r128/r128_tex.c +++ b/src/mesa/drivers/dri/r128/r128_tex.c @@ -33,21 +33,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" -#include "r128_tris.h" #include "r128_tex.h" #include "r128_texobj.h" -#include "main/context.h" -#include "main/macros.h" #include "main/simple_list.h" #include "main/enums.h" #include "main/texstore.h" #include "main/teximage.h" #include "main/texobj.h" #include "main/imports.h" -#include "main/colormac.h" #include "main/texobj.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/r128/r128_texmem.c b/src/mesa/drivers/dri/r128/r128_texmem.c index 4ddcb86bcd..5eec8c08cd 100644 --- a/src/mesa/drivers/dri/r128/r128_texmem.c +++ b/src/mesa/drivers/dri/r128/r128_texmem.c @@ -33,12 +33,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" -#include "r128_tris.h" #include "r128_tex.h" -#include "main/context.h" #include "main/macros.h" #include "main/simple_list.h" #include "main/imports.h" diff --git a/src/mesa/drivers/dri/r128/r128_texstate.c b/src/mesa/drivers/dri/r128/r128_texstate.c index cb2b5f9536..2505b5cd65 100644 --- a/src/mesa/drivers/dri/r128/r128_texstate.c +++ b/src/mesa/drivers/dri/r128/r128_texstate.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "r128_context.h" -#include "r128_state.h" #include "r128_ioctl.h" #include "r128_tris.h" #include "r128_tex.h" diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 8212dc1203..14eb96c1ba 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -9,10 +9,6 @@ LIBNAME = r200_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -29,8 +25,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_queryobj.c \ radeon_span.c \ - radeon_texture.c - + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = r200_context.c \ r200_ioctl.c \ @@ -46,6 +42,7 @@ DRIVER_SOURCES = r200_context.c \ r200_sanity.c \ r200_fragshader.c \ r200_vertprog.c \ + r200_blit.c \ radeon_screen.c \ $(EGL_SOURCES) \ $(RADEON_COMMON_SOURCES) \ @@ -55,7 +52,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) X86_SOURCES = -DRIVER_DEFINES = -DRADEON_R200 -Wall +DRIVER_DEFINES = -DRADEON_R200 DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r200/r200_blit.c b/src/mesa/drivers/dri/r200/r200_blit.c new file mode 100644 index 0000000000..e446d532cf --- /dev/null +++ b/src/mesa/drivers/dri/r200/r200_blit.c @@ -0,0 +1,407 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * 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 (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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "r200_context.h" +#include "r200_blit.h" + +static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) +{ + if (count) + return CP_PACKET0(reg, count - 1); + return CP_PACKET2; +} + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_A8: + break; + default: + return 0; + } + + /* ??? */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void emit_vtx_state(struct r200_context *r200) +{ + BATCH_LOCALS(&r200->radeon); + + BEGIN_BATCH(14); + if (r200->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, 0); + } else { + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS); + } + OUT_BATCH_REGVAL(R200_SE_VAP_CNTL, (R200_VAP_FORCE_W_TO_ONE | + (9 << R200_VAP_VF_MAX_VTX_NUM__SHIFT))); + OUT_BATCH_REGVAL(R200_SE_VTX_STATE_CNTL, 0); + OUT_BATCH_REGVAL(R200_SE_VTE_CNTL, 0); + OUT_BATCH_REGVAL(R200_SE_VTX_FMT_0, R200_VTX_XY); + OUT_BATCH_REGVAL(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); + OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX)); + END_BATCH(); +} + +static void inline emit_tx_setup(struct r200_context *r200, + gl_format mesa_format, + struct radeon_bo *bo, + intptr_t offset, + unsigned width, + unsigned height, + unsigned pitch) +{ + uint32_t txformat = R200_TXFORMAT_NON_POWER2; + BATCH_LOCALS(&r200->radeon); + + assert(width <= 2047); + assert(height <= 2047); + assert(offset % 32 == 0); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + txformat |= R200_TXFORMAT_ARGB8888 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_XRGB8888: + txformat |= R200_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat |= R200_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + txformat |= R200_TXFORMAT_ARGB4444 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_ARGB1555: + txformat |= R200_TXFORMAT_ARGB1555 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_A8: + txformat |= R200_TXFORMAT_I8 | R200_TXFORMAT_ALPHA_IN_MAP; + break; + default: + break; + } + + BEGIN_BATCH(28); + OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); + OUT_BATCH_REGVAL(R200_PP_CNTL_X, 0); + OUT_BATCH_REGVAL(R200_PP_TXMULTI_CTL_0, 0); + OUT_BATCH_REGVAL(R200_PP_TXCBLEND_0, (R200_TXC_ARG_A_ZERO | + R200_TXC_ARG_B_ZERO | + R200_TXC_ARG_C_R0_COLOR | + R200_TXC_OP_MADD)); + OUT_BATCH_REGVAL(R200_PP_TXCBLEND2_0, R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0); + OUT_BATCH_REGVAL(R200_PP_TXABLEND_0, (R200_TXA_ARG_A_ZERO | + R200_TXA_ARG_B_ZERO | + R200_TXA_ARG_C_R0_ALPHA | + R200_TXA_OP_MADD)); + OUT_BATCH_REGVAL(R200_PP_TXABLEND2_0, R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0); + OUT_BATCH_REGVAL(R200_PP_TXFILTER_0, (R200_CLAMP_S_CLAMP_LAST | + R200_CLAMP_T_CLAMP_LAST | + R200_MAG_FILTER_NEAREST | + R200_MIN_FILTER_NEAREST)); + OUT_BATCH_REGVAL(R200_PP_TXFORMAT_0, txformat); + OUT_BATCH_REGVAL(R200_PP_TXFORMAT_X_0, 0); + OUT_BATCH_REGVAL(R200_PP_TXSIZE_0, ((width - 1) | + ((height - 1) << RADEON_TEX_VSIZE_SHIFT))); + OUT_BATCH_REGVAL(R200_PP_TXPITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 32); + + OUT_BATCH_REGSEQ(R200_PP_TXOFFSET_0, 1); + OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + + END_BATCH(); +} + +static inline void emit_cb_setup(struct r200_context *r200, + struct radeon_bo *bo, + intptr_t offset, + gl_format mesa_format, + unsigned pitch, + unsigned width, + unsigned height) +{ + uint32_t dst_pitch = pitch; + uint32_t dst_format = 0; + BATCH_LOCALS(&r200->radeon); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + dst_format = RADEON_COLOR_FORMAT_ARGB4444; + break; + case MESA_FORMAT_ARGB1555: + dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case MESA_FORMAT_A8: + dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + break; + } + + BEGIN_BATCH_NO_AUTOSTATE(22); + OUT_BATCH_REGVAL(R200_RE_AUX_SCISSOR_CNTL, 0); + OUT_BATCH_REGVAL(R200_RE_CNTL, 0); + OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0); + OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) | + (height << RADEON_RE_HEIGHT_SHIFT))); + OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff); + OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); + OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format); + + OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1); + OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1); + OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); +} + +static GLboolean validate_buffers(struct r200_context *r200, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(r200->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(r200->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check_with_bo(r200->radeon.cmdbuf.cs, + first_elem(&r200->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static inline void calc_tex_coords(float img_width, float img_height, + float x, float y, + float reg_width, float reg_height, + unsigned flip_y, float *buf) +{ + buf[0] = x / img_width; + buf[1] = buf[0] + reg_width / img_width; + buf[2] = y / img_height; + buf[3] = buf[2] + reg_height / img_height; + if (flip_y) + { + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; + } +} + +static inline void emit_draw_packet(struct r200_context *r200, + unsigned src_width, unsigned src_height, + unsigned src_x_offset, unsigned src_y_offset, + unsigned dst_x_offset, unsigned dst_y_offset, + unsigned reg_width, unsigned reg_height, + unsigned flip_y) +{ + float texcoords[4]; + float verts[12]; + BATCH_LOCALS(&r200->radeon); + + calc_tex_coords(src_width, src_height, + src_x_offset, src_y_offset, + reg_width, reg_height, + flip_y, texcoords); + + verts[0] = dst_x_offset; + verts[1] = dst_y_offset + reg_height; + verts[2] = texcoords[0]; + verts[3] = texcoords[3]; + + verts[4] = dst_x_offset + reg_width; + verts[5] = dst_y_offset + reg_height; + verts[6] = texcoords[1]; + verts[7] = texcoords[3]; + + verts[8] = dst_x_offset + reg_width; + verts[9] = dst_y_offset; + verts[10] = texcoords[1]; + verts[11] = texcoords[2]; + + BEGIN_BATCH(14); + OUT_BATCH(R200_CP_CMD_3D_DRAW_IMMD_2 | (12 << 16)); + OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING | + RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | + (3 << 16)); + OUT_BATCH_TABLE(verts, 12); + END_BATCH(); +} + +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r200 r200 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */ +unsigned r200_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) +{ + struct r200_context *r200 = R200_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + /* Make sure that colorbuffer has even width - hw limitation */ + if (dst_pitch % 2 > 0) + ++dst_pitch; + + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return GL_FALSE; + + /* Need to clamp the region size to make sure + * we don't read outside of the source buffer + * or write outside of the destination buffer. + */ + if (reg_width + src_x_offset > src_width) + reg_width = src_width - src_x_offset; + if (reg_height + src_y_offset > src_height) + reg_height = src_height - src_y_offset; + if (reg_width + dst_x_offset > dst_width) + reg_width = dst_width - dst_x_offset; + if (reg_height + dst_y_offset > dst_height) + reg_height = dst_height - dst_y_offset; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 32 || dst_offset % 32) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: size [%d x %d], pitch %d, " + "offset [%d x %d], format %s, bo %p\n", + src_width, src_height, src_pitch, + src_x_offset, src_y_offset, + _mesa_get_format_name(src_mesaformat), + src_bo); + fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", + dst_pitch, dst_x_offset, dst_y_offset, + _mesa_get_format_name(dst_mesaformat), dst_bo); + fprintf(stderr, "region: %d x %d\n", reg_width, reg_height); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(r200->radeon.glCtx); + + rcommonEnsureCmdBufSpace(&r200->radeon, 78, __FUNCTION__); + + if (!validate_buffers(r200, src_bo, dst_bo)) + return GL_FALSE; + + /* 14 */ + emit_vtx_state(r200); + /* 28 */ + emit_tx_setup(r200, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch); + /* 22 */ + emit_cb_setup(r200, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); + /* 14 */ + emit_draw_packet(r200, src_width, src_height, + src_x_offset, src_y_offset, + dst_x_offset, dst_y_offset, + reg_width, reg_height, + flip_y); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/r200/r200_blit.h b/src/mesa/drivers/dri/r200/r200_blit.h new file mode 100644 index 0000000000..38487266ae --- /dev/null +++ b/src/mesa/drivers/dri/r200/r200_blit.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com> + * + * 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef R200_BLIT_H +#define R200_BLIT_H + +void r200_blit_init(struct r200_context *r200); + +unsigned r200_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned width, + unsigned height, + unsigned flip_y); + +#endif // R200_BLIT_H diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c index 1d1bea6f5f..2f2b8d94dc 100644 --- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c +++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c @@ -35,15 +35,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/macros.h" #include "main/context.h" -#include "swrast/swrast.h" #include "main/simple_list.h" #include "radeon_common.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tcl.h" -#include "r200_sanity.h" #include "radeon_reg.h" /* The state atoms will be emitted in the order they appear in the atom list, @@ -92,6 +88,7 @@ void r200SetUpAtomList( r200ContextPtr rmesa ) insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] ); insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] ); insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] ); + insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.stp ); for (i = 0; i < 8; ++i) insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] ); for (i = 0; i < 3 + mtu; ++i) diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index f34e319222..8986191c39 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -37,10 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -58,9 +55,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" #include "r200_swtcl.h" #include "r200_tcl.h" -#include "r200_maos.h" #include "r200_vertprog.h" #include "radeon_queryobj.h" +#include "r200_blit.h" #include "radeon_span.h" @@ -79,7 +76,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRIVER_DATE "20060602" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -268,6 +264,7 @@ static void r200_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = r200Fallback; radeon->vtbl.update_scissor = r200_vtbl_update_scissor; radeon->vtbl.emit_query_finish = r200_emit_query_finish; + radeon->vtbl.blit = r200_blit; } @@ -294,6 +291,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + rmesa->radeon.radeonScreen = screen; r200_init_vtbl(&rmesa->radeon); /* init exp fog table data */ r200InitStaticFogData(); @@ -326,7 +324,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, r200InitDriverFuncs(&functions); r200InitIoctlFuncs(&functions); r200InitStateFuncs(&functions); - r200InitTextureFuncs(&functions); + r200InitTextureFuncs(&rmesa->radeon, &functions); r200InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); @@ -352,6 +350,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits; + i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); /* FIXME: When no memory manager is available we should set this diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 17e4d8962e..a9dce310ae 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -645,6 +645,8 @@ extern GLboolean r200MakeCurrent( __DRIcontext *driContextPriv, __DRIdrawable *driReadPriv ); extern GLboolean r200UnbindContext( __DRIcontext *driContextPriv ); +extern void r200_init_texcopy_functions(struct dd_function_table *table); + /* ================================================================ * Debugging: */ diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 66c5d3655a..a1b505707e 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -46,13 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_common.h" #include "radeon_lock.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tcl.h" -#include "r200_sanity.h" #include "radeon_reg.h" -#include "drirenderbuffer.h" #include "vblank.h" #define R200_TIMEOUT 512 diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 249c0bbc11..aecba7f894 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -74,7 +74,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, GLvoid *data, int stride, int count) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - uint32_t *out; + GLfloat *out; int i; int size = 1; @@ -91,7 +91,7 @@ static void r200_emit_vecfog(GLcontext *ctx, struct radeon_aos *aos, aos->count = count; radeon_bo_map(aos->bo, 1); - out = (uint32_t*)((char*)aos->bo->ptr + aos->offset); + out = (GLfloat*)((char*)aos->bo->ptr + aos->offset); for (i = 0; i < count; i++) { out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data ); out++; diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 526a624b69..59115212ce 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -938,7 +938,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_CLAMP_Q_CLAMP_GL (6 << 9) #define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) #define R200_CLAMP_Q_MASK (7 << 9) -#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) +#define R200_MIN_MIP_LEVEL_MASK (0x0f << 12) #define R200_MIN_MIP_LEVEL_SHIFT 12 #define R200_TEXCOORD_NONPROJ (0 << 16) #define R200_TEXCOORD_CUBIC_ENV (1 << 16) @@ -950,6 +950,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_TEXCOORD_ZERO (7 << 16) #define R200_TEXCOORD_MASK (7 << 16) #define R200_LOD_BIAS_MASK (0xfff80000) +#define R200_LOD_BIAS_FIXED_ONE (0x08000000) +#define R200_LOD_BIAS_CORRECTION (0x00600000) #define R200_LOD_BIAS_SHIFT 19 #define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ #define R200_PP_TX_WIDTHMASK_SHIFT 0 diff --git a/src/mesa/drivers/dri/r200/r200_sanity.c b/src/mesa/drivers/dri/r200/r200_sanity.c index 1241a926ba..a439fd84ed 100644 --- a/src/mesa/drivers/dri/r200/r200_sanity.c +++ b/src/mesa/drivers/dri/r200/r200_sanity.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "r200_context.h" -#include "r200_ioctl.h" #include "r200_sanity.h" #include "radeon_reg.h" #include "r200_reg.h" diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 7fe482fe15..b9ec6f428f 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -57,8 +57,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_swtcl.h" #include "r200_vertprog.h" -#include "drirenderbuffer.h" - /* ============================================================= * Alpha blending @@ -597,6 +595,13 @@ static void r200PointSize( GLcontext *ctx, GLfloat size ) r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd; + radeon_print(RADEON_STATE, RADEON_TRACE, + "%s(%p) size: %f, fixed point result: %d.%d (%d/16)\n", + __func__, ctx, size, + ((GLuint)(ctx->Point.Size * 16.0))/16, + (((GLuint)(ctx->Point.Size * 16.0))&15)*100/16, + ((GLuint)(ctx->Point.Size * 16.0))&15); + R200_STATECHANGE( rmesa, cst ); R200_STATECHANGE( rmesa, ptp ); rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff; @@ -2466,6 +2471,12 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask ) radeon_firevertices(&r200->radeon); + radeon_print(RADEON_STATE, RADEON_TRACE, + "%s(%p) first 32 bits are %x.\n", + __func__, + ctx, + *(uint32_t*)mask); + R200_STATECHANGE(r200, stp); /* Must flip pattern upside down. diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 6c5a0b79ee..e06437bd50 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "vbo/vbo.h" -#include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -48,9 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_ioctl.h" #include "r200_state.h" -#include "r200_tcl.h" -#include "r200_tex.h" -#include "r200_swtcl.h" #include "radeon_queryobj.h" #include "xmlpool.h" @@ -351,6 +347,15 @@ static int check_rrb(GLcontext *ctx, struct radeon_state_atom *atom) return atom->cmd_size; } +static int check_polygon_stipple(GLcontext *ctx, + struct radeon_state_atom *atom) +{ + r200ContextPtr r200 = R200_CONTEXT(ctx); + if (r200->hw.set.cmd[SET_RE_CNTL] & R200_STIPPLE_ENABLE) + return atom->cmd_size; + return 0; +} + static void mtl_emit(GLcontext *ctx, struct radeon_state_atom *atom) { r200ContextPtr r200 = R200_CONTEXT(ctx); @@ -698,7 +703,8 @@ static void tex_emit_mm(GLcontext *ctx, struct radeon_state_atom *atom) uint32_t dwords = atom->check(ctx, atom); int i = atom->idx; radeonTexObj *t = r200->state.texture.unit[i].texobj; - if (!r200->state.texture.unit[i].unitneeded) + + if (!r200->state.texture.unit[i].unitneeded && !(dwords <= atom->cmd_size)) dwords -= 4; BEGIN_BATCH_NO_AUTOSTATE(dwords); @@ -888,7 +894,7 @@ void r200InitState( r200ContextPtr rmesa ) } } - ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 ); + ALLOC_STATE( stp, polygon_stipple, STP_STATE_SIZE, "STP/stp", 0 ); for (i = 0; i < 6; i++) if (rmesa->radeon.radeonScreen->kernel_mm) @@ -1380,7 +1386,7 @@ void r200InitState( r200ContextPtr rmesa ) rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT_X] = (/* R200_TEXCOORD_PROJ | */ - 0x100000); /* Small default bias */ + R200_LOD_BIAS_CORRECTION); /* Small default bias */ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) { rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET_NEWDRM] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index 4596912ddc..e220e40b01 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -44,7 +44,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/s_context.h" #include "swrast/s_fog.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index e7d48a7f29..f3f558b7de 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_state.h" #include "r200_ioctl.h" -#include "r200_tex.h" #include "r200_tcl.h" #include "r200_swtcl.h" #include "r200_maos.h" diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index 5b87ba6ccd..6723b12bf4 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -44,9 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_mipmap_tree.h" #include "r200_context.h" -#include "r200_state.h" #include "r200_ioctl.h" -#include "r200_swtcl.h" #include "r200_tex.h" #include "xmlpool.h" @@ -67,6 +65,13 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu GLboolean is_clamp_to_border = GL_FALSE; struct gl_texture_object *tObj = &t->base; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) sw %s, tw %s, rw %s\n", + __func__, t, + _mesa_lookup_enum_by_nr(swrap), + _mesa_lookup_enum_by_nr(twrap), + _mesa_lookup_enum_by_nr(rwrap)); + t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D); switch ( swrap ) { @@ -182,6 +187,9 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu static void r200SetTexMaxAnisotropy( radeonTexObjPtr t, GLfloat max ) { t->pp_txfilter &= ~R200_MAX_ANISO_MASK; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) max %f.\n", + __func__, t, max); if ( max <= 1.0 ) { t->pp_txfilter |= R200_MAX_ANISO_1_TO_1; @@ -214,6 +222,13 @@ static void r200SetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) t->pp_txfilter &= ~(R200_MIN_FILTER_MASK | R200_MAG_FILTER_MASK); t->pp_txformat_x &= ~R200_VOLUME_FILTER_MASK; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(tex %p) minf %s, maxf %s, anisotropy %d.\n", + __func__, t, + _mesa_lookup_enum_by_nr(minf), + _mesa_lookup_enum_by_nr(magf), + anisotropy); + if ( anisotropy == R200_MAX_ANISO_1_TO_1 ) { switch ( minf ) { case GL_NEAREST: @@ -286,10 +301,8 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if ( R200_DEBUG & RADEON_STATE ) { - fprintf( stderr, "%s( %s )\n", + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); - } /* This is incorrect: Need to maintain this data for each of * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch @@ -311,18 +324,19 @@ static void r200TexEnv( GLcontext *ctx, GLenum target, case GL_TEXTURE_LOD_BIAS_EXT: { GLfloat bias, min; GLuint b; - const int fixed_one = 0x8000000; + const int fixed_one = R200_LOD_BIAS_FIXED_ONE; /* The R200's LOD bias is a signed 2's complement value with a * range of -16.0 <= bias < 16.0. * * NOTE: Add a small bias to the bias for conform mipsel.c test. */ - bias = *param + .01; + bias = *param; min = driQueryOptionb (&rmesa->radeon.optionCache, "no_neg_lod_bias") ? 0.0 : -16.0; bias = CLAMP( bias, min, 16.0 ); - b = (int)(bias * fixed_one) & R200_LOD_BIAS_MASK; + b = ((int)(bias * fixed_one) + + R200_LOD_BIAS_CORRECTION) & R200_LOD_BIAS_MASK; if ( (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT_X] & R200_LOD_BIAS_MASK) != b ) { R200_STATECHANGE( rmesa, tex[unit] ); @@ -358,10 +372,11 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, { radeonTexObj* t = radeon_tex_obj(texObj); - if ( R200_DEBUG & (RADEON_STATE|RADEON_TEXTURE) ) { - fprintf( stderr, "%s( %s )\n", __FUNCTION__, + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_VERBOSE, + "%s(%p, tex %p) target %s, pname %s\n", + __FUNCTION__, ctx, texObj, + _mesa_lookup_enum_by_nr( target ), _mesa_lookup_enum_by_nr( pname ) ); - } switch ( pname ) { case GL_TEXTURE_MIN_FILTER: @@ -399,11 +414,10 @@ static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) r200ContextPtr rmesa = R200_CONTEXT(ctx); radeonTexObj* t = radeon_tex_obj(texObj); - if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - (void *)texObj, - _mesa_lookup_enum_by_nr(texObj->Target)); - } + radeon_print(RADEON_TEXTURE | RADEON_STATE, RADEON_NORMAL, + "%s( %p (target = %s) )\n", __FUNCTION__, + (void *)texObj, + _mesa_lookup_enum_by_nr(texObj->Target)); if (rmesa) { int i; @@ -458,10 +472,10 @@ static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx, radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); - if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - t, _mesa_lookup_enum_by_nr(target)); - } + radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p) target %s, new texture %p.\n", + __FUNCTION__, ctx, + _mesa_lookup_enum_by_nr(target), t); _mesa_initialize_texture_object(&t->base, name, target); t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; @@ -477,7 +491,7 @@ static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx, -void r200InitTextureFuncs( struct dd_function_table *functions ) +void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -511,6 +525,11 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; functions->NewTextureImage = radeonNewTextureImage; diff --git a/src/mesa/drivers/dri/r200/r200_tex.h b/src/mesa/drivers/dri/r200/r200_tex.h index e122de6e5e..1a1e7038df 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.h +++ b/src/mesa/drivers/dri/r200/r200_tex.h @@ -48,7 +48,7 @@ extern int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint extern void r200DestroyTexObj( r200ContextPtr rmesa, radeonTexObjPtr t ); -extern void r200InitTextureFuncs( struct dd_function_table *functions ); +extern void r200InitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ); extern void r200UpdateFragmentShader( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index e2f9cf0ea8..458de08522 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -1055,6 +1055,7 @@ static GLboolean r200UpdateAllTexEnv( GLcontext *ctx ) #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ R200_TEXCOORD_MASK | \ + R200_MIN_MIP_LEVEL_MASK | \ R200_CLAMP_Q_MASK | \ R200_VOLUME_FILTER_MASK) @@ -1410,6 +1411,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) { const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod]; GLint log2Width, log2Height, log2Depth, texelBytes; + uint extra_size = 0; if ( t->bo ) { return; @@ -1420,6 +1422,10 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) log2Depth = firstImage->DepthLog2; texelBytes = _mesa_get_format_bytes(firstImage->TexFormat); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n", + __func__, rmesa, t, log2Width, log2Height, + log2Depth, texelBytes, firstImage->TexFormat); if (!t->image_override) { if (VALID_FORMAT(firstImage->TexFormat)) { @@ -1432,6 +1438,8 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) t->pp_txformat |= table[ firstImage->TexFormat ].format; t->pp_txfilter |= table[ firstImage->TexFormat ].filter; + + } else { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); @@ -1440,19 +1448,34 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) } t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; - t->pp_txfilter |= (t->maxLod - t->minLod) << R200_MAX_MIP_LEVEL_SHIFT; - + t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT) + & R200_MAX_MIP_LEVEL_MASK; + + if ( t->pp_txfilter & + (R200_MIN_FILTER_NEAREST_MIP_NEAREST + | R200_MIN_FILTER_NEAREST_MIP_LINEAR + | R200_MIN_FILTER_LINEAR_MIP_NEAREST + | R200_MIN_FILTER_LINEAR_MIP_LINEAR + | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST + | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR)) + extra_size = t->minLod; + t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | R200_TXFORMAT_HEIGHT_MASK | R200_TXFORMAT_CUBIC_MAP_ENABLE | R200_TXFORMAT_F5_WIDTH_MASK | R200_TXFORMAT_F5_HEIGHT_MASK); - t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | - (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); + t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) | + ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT)); t->tile_bits = 0; - t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK); + t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK + | R200_MIN_MIP_LEVEL_MASK); + + t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT) + & R200_MIN_MIP_LEVEL_MASK; + if (t->base.Target == GL_TEXTURE_3D) { t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); t->pp_txformat_x |= R200_TEXCOORD_VOLUME; @@ -1480,7 +1503,7 @@ static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) */ t->pp_txformat_x |= R200_TEXCOORD_PROJ; } - + /* FIXME: NPOT sizes, Is it correct realy? */ t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT) | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT)); diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 11405d7cae..12f869d96f 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -437,7 +437,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) | (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) { if (R200_DEBUG & RADEON_FALLBACKS) { - fprintf(stderr, "can't handle vert prog outputs 0x%x\n", + fprintf(stderr, "can't handle vert prog outputs 0x%llx\n", mesa_vp->Base.OutputsWritten); } return GL_FALSE; @@ -1218,7 +1218,7 @@ r200DeleteProgram(GLcontext *ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) { struct r200_vertex_program *vp = (void *)prog; @@ -1237,7 +1237,10 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) break; } /* need this for tcl fallbacks */ - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/r200/radeon_tex_copy.c b/src/mesa/drivers/dri/r200/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r200/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r200/server/radeon_egl.c b/src/mesa/drivers/dri/r200/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r200/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index be005bd164..04459c2ddf 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -9,10 +9,6 @@ LIBNAME = r300_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -39,7 +35,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_span.c \ radeon_queryobj.c \ - radeon_texture.c + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_screen.c \ @@ -50,7 +47,6 @@ DRIVER_SOURCES = \ r300_state.c \ r300_render.c \ r300_tex.c \ - r300_texcopy.c \ r300_texstate.c \ r300_vertprog.c \ r300_fragprog_common.c \ @@ -66,7 +62,6 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) DRIVER_DEFINES = -DRADEON_R300 # -DRADEON_BO_TRACK \ - -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c index aa69b0fc72..928c15e1e4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c @@ -297,7 +297,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (flags[0] != 0) { sprintf(tmp, "o%i.%s", (code->alu.inst[i]. - rgb_addr >> R300_ALU_DSTC_SHIFT) & 31, + rgb_addr >> 29) & 3, flags); strcat(dstc, tmp); } @@ -311,7 +311,7 @@ void r300FragmentProgramDump(struct rX00_fragment_program_code *c) if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) { sprintf(tmp, "o%i.w ", (code->alu.inst[i]. - alpha_addr >> R300_ALU_DSTA_SHIFT) & 31); + alpha_addr >> 25) & 3); strcat(dsta, tmp); } if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) { diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c index 375838d98e..cc552aee17 100644 --- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c @@ -176,7 +176,9 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); } if (inst->RGB.OutputWriteMask) { - code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT); + code->alu.inst[ip].rgb_addr |= + (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | + R300_RGB_TARGET(inst->RGB.Target); emit->node_flags |= R300_RGBA_OUT; } @@ -187,7 +189,8 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i R300_ALU_DSTA_REG; } if (inst->Alpha.OutputWriteMask) { - code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT; + code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | + R300_ALPHA_TARGET(inst->Alpha.Target); emit->node_flags |= R300_RGBA_OUT; } if (inst->Alpha.DepthWriteMask) { diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index 5581f25352..c2d5dc27b4 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -35,7 +35,10 @@ static void dataflow_outputs_mark_use(void * userdata, void * data, void (*callback)(void *, unsigned int, unsigned int)) { struct r300_fragment_program_compiler * c = userdata; - callback(data, c->OutputColor, RC_MASK_XYZW); + callback(data, c->OutputColor[0], RC_MASK_XYZW); + callback(data, c->OutputColor[1], RC_MASK_XYZW); + callback(data, c->OutputColor[2], RC_MASK_XYZW); + callback(data, c->OutputColor[3], RC_MASK_XYZW); callback(data, c->OutputDepth, RC_MASK_W); } diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index b1b14394b6..c2eb613b23 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -241,6 +241,9 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; + code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target); + code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target); + if (inst->WriteALUResult) { code->inst[ip].inst3 |= R500_ALU_RGB_WMASK; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h index 731adc1af2..6bfda0574f 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h @@ -23,6 +23,8 @@ #ifndef RADEON_COMPILER_H #define RADEON_COMPILER_H +#include "../../../../main/compiler.h" + #include "memory_pool.h" #include "radeon_code.h" #include "radeon_program.h" @@ -81,8 +83,10 @@ struct r300_fragment_program_compiler { struct rX00_fragment_program_code *code; struct r300_fragment_program_external_state state; unsigned is_r500; + /* Register corresponding to the depthbuffer. */ unsigned OutputDepth; - unsigned OutputColor; + /* Registers corresponding to the four colorbuffers. */ + unsigned OutputColor[4]; void * UserData; void (*AllocateHwInputs)( diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c index 7211768272..fff5b0c217 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c @@ -203,12 +203,21 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c, /* Destination handling */ if (inst->DstReg.File == RC_FILE_OUTPUT) { - if (inst->DstReg.Index == c->OutputColor) { - pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ; - pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } else if (inst->DstReg.Index == c->OutputDepth) { - pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); - } + if (inst->DstReg.Index == c->OutputDepth) { + pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3); + } else { + for (i = 0; i < 4; i++) { + if (inst->DstReg.Index == c->OutputColor[i]) { + pair->RGB.Target = i; + pair->Alpha.Target = i; + pair->RGB.OutputWriteMask |= + inst->DstReg.WriteMask & RC_MASK_XYZ; + pair->Alpha.OutputWriteMask |= + GET_BIT(inst->DstReg.WriteMask, 3); + break; + } + } + } } else { if (needrgb) { pair->RGB.DestIndex = inst->DstReg.Index; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h index 6685ade3ea..511cc707a3 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h @@ -60,6 +60,7 @@ struct radeon_pair_instruction_rgb { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:3; + unsigned int Target:2; unsigned int OutputWriteMask:3; unsigned int Saturate:1; @@ -77,6 +78,7 @@ struct radeon_pair_instruction_alpha { unsigned int Opcode:8; unsigned int DestIndex:RC_REGISTER_INDEX_BITS; unsigned int WriteMask:1; + unsigned int Target:2; unsigned int OutputWriteMask:1; unsigned int DepthWriteMask:1; unsigned int Saturate:1; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c index d863b82d53..28fb9eae92 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_print.c @@ -229,7 +229,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst (inst->RGB.WriteMask & 2) ? "y" : "", (inst->RGB.WriteMask & 4) ? "z" : ""); if (inst->RGB.OutputWriteMask) - fprintf(f, " color.%s%s%s", + fprintf(f, " color[%i].%s%s%s", inst->RGB.Target, (inst->RGB.OutputWriteMask & 1) ? "x" : "", (inst->RGB.OutputWriteMask & 2) ? "y" : "", (inst->RGB.OutputWriteMask & 4) ? "z" : ""); @@ -255,7 +255,7 @@ static void rc_print_pair_instruction(FILE * f, struct rc_instruction * fullinst if (inst->Alpha.WriteMask) fprintf(f, " temp[%i].w", inst->Alpha.DestIndex); if (inst->Alpha.OutputWriteMask) - fprintf(f, " color.w"); + fprintf(f, " color[%i].w", inst->Alpha.Target); if (inst->Alpha.DepthWriteMask) fprintf(f, " depth.w"); if (inst->WriteALUResult == RC_ALURESULT_W) diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c index 2eec27e900..54ac2510e7 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.c +++ b/src/mesa/drivers/dri/r300/r300_blit.c @@ -114,7 +114,7 @@ static void create_fragment_program(struct r300_context *r300) inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW; compiler.Base.Program.InputsRead = (1 << FRAG_ATTRIB_TEX0); - compiler.OutputColor = FRAG_RESULT_COLOR; + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.OutputDepth = FRAG_RESULT_DEPTH; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515); compiler.code = &r300->blit.fp_code; @@ -150,8 +150,8 @@ static void r300_emit_tx_setup(struct r300_context *r300, (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT) | (R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT) | R300_TX_MIN_FILTER_MIP_NONE | - R300_TX_MIN_FILTER_LINEAR | - R300_TX_MAG_FILTER_LINEAR | + R300_TX_MIN_FILTER_NEAREST | + R300_TX_MAG_FILTER_NEAREST | (0 << 28)); OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0); OUT_BATCH_REGVAL(R300_TX_SIZE_0, @@ -403,9 +403,8 @@ static void calc_tex_coords(float img_width, float img_height, buf[3] = buf[2] + reg_height / img_height; if (flip_y) { - float tmp = buf[2]; - buf[2] = 1.0 - buf[3]; - buf[3] = 1.0 - tmp; + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; } } @@ -424,13 +423,13 @@ static void emit_draw_packet(struct r300_context *r300, flip_y, texcoords); float verts[] = { dst_x_offset, dst_y_offset, - texcoords[0], texcoords[3], - dst_x_offset, dst_y_offset + reg_height, texcoords[0], texcoords[2], + dst_x_offset, dst_y_offset + reg_height, + texcoords[0], texcoords[3], dst_x_offset + reg_width, dst_y_offset + reg_height, - texcoords[1], texcoords[2], + texcoords[1], texcoords[3], dst_x_offset + reg_width, dst_y_offset, - texcoords[1], texcoords[3] }; + texcoords[1], texcoords[2] }; BATCH_LOCALS(&r300->radeon); @@ -495,6 +494,27 @@ static void emit_cb_setup(struct r300_context *r300, END_BATCH(); } +static unsigned is_blit_supported(gl_format dst_format) +{ + switch (dst_format) { + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888: + break; + default: + return 0; + } + + if (_mesa_get_format_bits(dst_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + /** * Copy a region of [@a width x @a height] pixels from source buffer * to destination buffer. @@ -519,29 +539,31 @@ static void emit_cb_setup(struct r300_context *r300, * @param[in] height region height * @param[in] flip_y set if y coords of the source image need to be flipped */ -GLboolean r300_blit(struct r300_context *r300, - struct radeon_bo *src_bo, - intptr_t src_offset, - gl_format src_mesaformat, - unsigned src_pitch, - unsigned src_width, - unsigned src_height, - unsigned src_x_offset, - unsigned src_y_offset, - struct radeon_bo *dst_bo, - intptr_t dst_offset, - gl_format dst_mesaformat, - unsigned dst_pitch, - unsigned dst_width, - unsigned dst_height, - unsigned dst_x_offset, - unsigned dst_y_offset, - unsigned reg_width, - unsigned reg_height, - unsigned flip_y) +unsigned r300_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) { - if (_mesa_get_format_bits(src_mesaformat, GL_DEPTH_BITS) > 0) - return GL_FALSE; + r300ContextPtr r300 = R300_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return 0; /* Make sure that colorbuffer has even width - hw limitation */ if (dst_pitch % 2 > 0) @@ -551,7 +573,7 @@ GLboolean r300_blit(struct r300_context *r300, * Looks like a hw limitation. */ if (dst_pitch < 32) - return GL_FALSE; + return 0; /* Need to clamp the region size to make sure * we don't read outside of the source buffer @@ -567,6 +589,10 @@ GLboolean r300_blit(struct r300_context *r300, reg_height = dst_height - dst_y_offset; if (src_bo == dst_bo) { + return 0; + } + + if (src_offset % 32 || dst_offset % 32) { return GL_FALSE; } @@ -587,7 +613,7 @@ GLboolean r300_blit(struct r300_context *r300, radeonFlush(r300->radeon.glCtx); if (!validate_buffers(r300, src_bo, dst_bo)) - return GL_FALSE; + return 0; rcommonEnsureCmdBufSpace(&r300->radeon, 200, __FUNCTION__); @@ -618,5 +644,5 @@ GLboolean r300_blit(struct r300_context *r300, radeonFlush(r300->radeon.glCtx); - return GL_TRUE; -}
\ No newline at end of file + return 1; +} diff --git a/src/mesa/drivers/dri/r300/r300_blit.h b/src/mesa/drivers/dri/r300/r300_blit.h index dc21e88098..735acaddd7 100644 --- a/src/mesa/drivers/dri/r300/r300_blit.h +++ b/src/mesa/drivers/dri/r300/r300_blit.h @@ -30,25 +30,25 @@ void r300_blit_init(struct r300_context *r300); -GLboolean r300_blit(struct r300_context *r300, - struct radeon_bo *src_bo, - intptr_t src_offset, - gl_format src_mesaformat, - unsigned src_pitch, - unsigned src_width, - unsigned src_height, - unsigned src_x_offset, - unsigned src_y_offset, - struct radeon_bo *dst_bo, - intptr_t dst_offset, - gl_format dst_mesaformat, - unsigned dst_pitch, - unsigned dst_width, - unsigned dst_height, - unsigned dst_x_offset, - unsigned dst_y_offset, - unsigned width, - unsigned height, - unsigned flip_y); +unsigned r300_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y); #endif // R300_BLIT_H
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index e1c33bbb2c..4787bafc66 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "drm.h" #include "radeon_drm.h" @@ -50,7 +49,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_emit.h" #include "radeon_bocs_wrapper.h" #include "radeon_mipmap_tree.h" -#include "r300_state.h" #include "radeon_queryobj.h" /** # of dwords reserved for additional instructions that may need to be written diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 1f6ccf6ddc..7c21efb1de 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -40,9 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/state.h" #include "main/bufferobj.h" #include "main/texobj.h" @@ -52,13 +50,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "drivers/common/driverfuncs.h" #include "drivers/common/meta.h" #include "r300_context.h" -#include "radeon_context.h" #include "radeon_span.h" #include "r300_blit.h" #include "r300_cmdbuf.h" @@ -70,7 +66,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_buffer_objects.h" #include "radeon_queryobj.h" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -93,8 +88,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/remap_helper.h" -void r300_init_texcopy_functions(struct dd_function_table *table); - static const struct dri_extension card_extensions[] = { /* *INDENT-OFF* */ {"GL_ARB_depth_texture", NULL}, @@ -326,6 +319,8 @@ static void r300_init_vtbl(radeonContextPtr radeon) radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z; } else radeon->vtbl.emit_query_finish = r300_emit_query_finish; + + radeon->vtbl.blit = r300_blit; } static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) @@ -338,6 +333,10 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen) driQueryOptioni(&r300->radeon.optionCache, "texture_coord_units"); ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); + ctx->Const.MaxCombinedTextureImageUnits = + ctx->Const.MaxVertexTextureImageUnits + + ctx->Const.MaxTextureImageUnits; + ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; @@ -451,6 +450,8 @@ static void r300InitGLExtensions(GLcontext *ctx) if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) { _mesa_disable_extension(ctx, "GL_ARB_occlusion_query"); } + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV350) + _mesa_enable_extension(ctx, "GL_ARB_half_float_vertex"); } static void r300InitIoctlFuncs(struct dd_function_table *functions) @@ -488,15 +489,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, _mesa_init_driver_functions(&functions); r300InitIoctlFuncs(&functions); r300InitStateFuncs(&functions); - r300InitTextureFuncs(&functions); + r300InitTextureFuncs(&r300->radeon, &functions); r300InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); radeonInitBufferObjectFuncs(&functions); - if (r300->radeon.radeonScreen->kernel_mm) { - r300_init_texcopy_functions(&functions); - } - if (!radeonInitContext(&r300->radeon, &functions, glVisual, driContextPriv, sharedContextPrivate)) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 546cd8ddde..78ab43a99f 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -554,8 +554,6 @@ extern void r300InitShaderFunctions(r300ContextPtr r300); extern void r300InitDraw(GLcontext *ctx); -extern void r300_init_texcopy_functions(struct dd_function_table *table); - #define r300PackFloat32 radeonPackFloat32 #define r300PackFloat24 radeonPackFloat24 diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 3dcd986e22..4ae0d6fe48 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -29,7 +29,6 @@ #include "main/glheader.h" #include "main/context.h" #include "main/state.h" -#include "main/api_validate.h" #include "main/enums.h" #include "main/simple_list.h" @@ -47,8 +46,6 @@ #include "tnl/tnl.h" #include "tnl/t_vp_build.h" #include "vbo/vbo_context.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" static int getTypeSize(GLenum type) @@ -56,6 +53,8 @@ static int getTypeSize(GLenum type) switch (type) { case GL_DOUBLE: return sizeof(GLdouble); + case GL_HALF_FLOAT: + return sizeof(GLhalfARB); case GL_FLOAT: return sizeof(GLfloat); case GL_INT: @@ -385,6 +384,18 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st r300_attr._signed = 0; r300_attr.normalize = 0; break; + case GL_HALF_FLOAT: + switch (input->Size) { + case 1: + case 2: + r300_attr.data_type = R300_DATA_TYPE_FLT16_2; + break; + case 3: + case 4: + r300_attr.data_type = R300_DATA_TYPE_FLT16_4; + break; + } + break; case GL_SHORT: r300_attr._signed = 1; r300_attr.normalize = input->Normalized; @@ -594,13 +605,23 @@ static void r300FreeData(GLcontext *ctx) } } -static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, GLuint nr_prims) +static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, + GLuint nr_prims, const struct _mesa_prim *prim) { struct r300_context *r300 = R300_CONTEXT(ctx); struct r300_vertex_buffer *vbuf = &r300->vbuf; GLboolean flushed; GLuint dwords; GLuint state_size; + int i; + GLuint extra_prims = 0; + + /* Check for primitive splitting. */ + for (i = 0; i < nr_prims; ++i) { + const GLuint num_verts = r300NumVerts(r300, prim[i].count, prim[i].mode); + extra_prims += num_verts/(65535 - 32); + } + nr_prims += extra_prims; dwords = 2*CACHE_FLUSH_BUFSZ; dwords += PRE_EMIT_STATE_BUFSZ; @@ -656,7 +677,7 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, /* ensure we have the cmd buf space in advance to cover * the state + DMA AOS pointers */ - GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims) + GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims, prim) + r300->radeon.cmdbuf.cs->cdw; r300SetupIndexBuffer(ctx, ib); diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 15aeaf0514..a24d431611 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -39,18 +39,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "main/imports.h" #include "main/macros.h" -#include "main/image.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "r300_context.h" -#include "r300_state.h" #include "r300_emit.h" -#include "r300_render.h" -#include "r300_swtcl.h" + GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead) { diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c index 2933d31136..a0e2dd3c09 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c @@ -38,14 +38,12 @@ #include "r300_fragprog_common.h" -#include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "compiler/radeon_compiler.h" #include "radeon_mesa_to_rc.h" -#include "r300_state.h" static GLuint build_dtm(GLuint depthmode) @@ -223,7 +221,8 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog compiler.state = fp->state; compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE; compiler.OutputDepth = FRAG_RESULT_DEPTH; - compiler.OutputColor = FRAG_RESULT_COLOR; + memset(compiler.OutputColor, 0, 4 * sizeof(unsigned)); + compiler.OutputColor[0] = FRAG_RESULT_COLOR; compiler.AllocateHwInputs = &allocate_hw_inputs; if (compiler.Base.Debug) { diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index ea684e7df1..d18ebab8ff 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -230,6 +230,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_DATA_TYPE_SHORT_4 7 # define R300_DATA_TYPE_VECTOR_3_TTT 8 # define R300_DATA_TYPE_VECTOR_3_EET 9 +# define R300_DATA_TYPE_FLT16_2 11 +# define R300_DATA_TYPE_FLT16_4 12 + # define R300_SKIP_DWORDS_SHIFT 4 # define R300_DST_VEC_LOC_SHIFT 8 # define R300_LAST_VEC (1 << 13) diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 02c94250a8..e3e6285784 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -53,7 +53,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_render.h" #include "main/glheader.h" -#include "main/state.h" #include "main/imports.h" #include "main/enums.h" #include "main/macros.h" @@ -65,14 +64,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "vbo/vbo.h" #include "vbo/vbo_split.h" -#include "tnl/tnl.h" -#include "tnl/t_vp_build.h" #include "r300_context.h" #include "r300_state.h" #include "r300_reg.h" -#include "r300_tex.h" #include "r300_emit.h" -#include "r300_fragprog_common.h" #include "r300_swtcl.h" /** diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index a4f9db13ec..3638010e48 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -98,7 +98,7 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog; @@ -116,7 +116,10 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) } /* need this for tcl fallbacks */ - _tnl_program_string(ctx, target, prog); + (void) _tnl_program_string(ctx, target, prog); + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index c51285aad9..017d45a503 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -58,13 +58,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_reg.h" #include "r300_emit.h" -#include "r300_tex.h" #include "r300_fragprog_common.h" #include "r300_render.h" #include "r300_vertprog.h" -#include "drirenderbuffer.h" - static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4]) { r300ContextPtr rmesa = R300_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 963f648cb1..8dd8507395 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -41,18 +41,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/mipmap.h" #include "main/simple_list.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "texmem.h" #include "r300_context.h" -#include "r300_state.h" #include "radeon_mipmap_tree.h" #include "r300_tex.h" -#include "xmlpool.h" - static unsigned int translate_wrap_mode(GLenum wrapmode) { @@ -312,7 +308,7 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, return &t->base; } -void r300InitTextureFuncs(struct dd_function_table *functions) +void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -340,6 +336,11 @@ void r300InitTextureFuncs(struct dd_function_table *functions) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; driInitTextureFormats(); diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index 6ede0fe25c..9694e703b8 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -49,7 +49,7 @@ extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, extern GLboolean r300ValidateBuffers(GLcontext * ctx); -extern void r300InitTextureFuncs(struct dd_function_table *functions); +extern void r300InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions); int32_t r300TranslateTexFormat(gl_format mesaFormat); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 78ff54574f..09e046859a 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "r300_context.h" -#include "r300_state.h" #include "radeon_mipmap_tree.h" #include "r300_tex.h" #include "r300_reg.h" diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index aa98a049aa..e6fa57d439 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -34,7 +34,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "shader/program.h" #include "shader/programopt.h" #include "shader/prog_instruction.h" -#include "shader/prog_optimize.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/r300/radeon_tex_copy.c b/src/mesa/drivers/dri/r300/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r300/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r300/server/radeon_egl.c b/src/mesa/drivers/dri/r300/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r300/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile index 26f47b7268..5d50941539 100644 --- a/src/mesa/drivers/dri/r600/Makefile +++ b/src/mesa/drivers/dri/r600/Makefile @@ -9,10 +9,6 @@ LIBNAME = r600_dri.so MINIGLX_SOURCES = server/radeon_dri.c -ifeq ($(USING_EGL), 1) -EGL_SOURCES = server/radeon_egl.c -endif - ifeq ($(RADEON_LDFLAGS),) CS_SOURCES = radeon_cs_space_drm.c radeon_bo.c radeon_cs.c endif @@ -39,7 +35,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_span.c \ radeon_texture.c \ - radeon_queryobj.c + radeon_queryobj.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_screen.c \ @@ -59,6 +56,7 @@ DRIVER_SOURCES = \ r700_render.c \ r600_tex.c \ r600_texstate.c \ + r600_blit.c \ r700_debug.c \ $(RADEON_COMMON_SOURCES) \ $(EGL_SOURCES) \ @@ -66,9 +64,8 @@ DRIVER_SOURCES = \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -DRIVER_DEFINES = -DRADEON_R600 \ +DRIVER_DEFINES = -DRADEON_R600 # -DRADEON_BO_TRACK \ - -Wall DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/r600/r600_blit.c b/src/mesa/drivers/dri/r600/r600_blit.c new file mode 100644 index 0000000000..4bb77a398f --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit.c @@ -0,0 +1,1661 @@ +/* + * Copyright (C) 2009 Advanced Micro Devices, 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 (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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "r600_context.h" + +#include "r600_blit.h" +#include "r600_blit_shaders.h" +#include "r600_cmdbuf.h" + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_SIGNED_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_SIGNED_RGBA8888_REV: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888_REV: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_A8: + case MESA_FORMAT_I8: + case MESA_FORMAT_CI8: + case MESA_FORMAT_L8: + case MESA_FORMAT_RGBA_FLOAT32: + case MESA_FORMAT_RGBA_FLOAT16: + case MESA_FORMAT_ALPHA_FLOAT32: + case MESA_FORMAT_ALPHA_FLOAT16: + case MESA_FORMAT_LUMINANCE_FLOAT32: + case MESA_FORMAT_LUMINANCE_FLOAT16: + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + case MESA_FORMAT_X8_Z24: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z16: + case MESA_FORMAT_Z32: + case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SLA8: + case MESA_FORMAT_SL8: + break; + default: + return 0; + } + + /* ??? */ + /* not sure blit to depth works or not yet */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void +set_render_target(context_t *context, struct radeon_bo *bo, gl_format mesa_format, + int nPitchInPixel, int w, int h, intptr_t dst_offset) +{ + uint32_t cb_color0_base, cb_color0_size = 0, cb_color0_info = 0, cb_color0_view = 0; + int id = 0; + uint32_t comp_swap, format; + BATCH_LOCALS(&context->radeon); + + cb_color0_base = dst_offset / 256; + + SETfield(cb_color0_size, (nPitchInPixel / 8) - 1, + PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask); + SETfield(cb_color0_size, ((nPitchInPixel * h) / 64) - 1, + SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); + + SETfield(cb_color0_info, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask); + SETfield(cb_color0_info, ARRAY_LINEAR_GENERAL, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + + SETbit(cb_color0_info, BLEND_BYPASS_bit); + + switch(mesa_format) { + case MESA_FORMAT_RGBA8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SIGNED_RGBA8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SIGNED_RGBA8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + format = COLOR_8_8_8_8; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_XRGB8888_REV: + format = COLOR_8_8_8_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB565: + format = COLOR_5_6_5; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB565_REV: + format = COLOR_5_6_5; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB4444: + format = COLOR_4_4_4_4; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB4444_REV: + format = COLOR_4_4_4_4; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB1555: + format = COLOR_1_5_5_5; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ARGB1555_REV: + format = COLOR_1_5_5_5; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_AL88: + format = COLOR_8_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_AL88_REV: + format = COLOR_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGB332: + format = COLOR_3_3_2; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_A8: + format = COLOR_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_I8: + case MESA_FORMAT_CI8: + format = COLOR_8; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_L8: + format = COLOR_8; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA_FLOAT32: + format = COLOR_32_32_32_32_FLOAT; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_RGBA_FLOAT16: + format = COLOR_16_16_16_16_FLOAT; + comp_swap = SWAP_STD_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT32: + format = COLOR_32_FLOAT; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT16: + format = COLOR_16_FLOAT; + comp_swap = SWAP_ALT_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT32: + format = COLOR_32_FLOAT; + comp_swap = SWAP_ALT; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT16: + format = COLOR_16_FLOAT; + comp_swap = SWAP_ALT; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + format = COLOR_32_32_FLOAT; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + format = COLOR_16_16_FLOAT; + comp_swap = SWAP_ALT_REV; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + format = COLOR_32_FLOAT; + comp_swap = SWAP_STD; + SETbit(cb_color0_info, BLEND_FLOAT32_bit); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + format = COLOR_16_FLOAT; + comp_swap = SWAP_STD; + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_FLOAT, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_X8_Z24: + case MESA_FORMAT_S8_Z24: + format = COLOR_8_24; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z24_S8: + format = COLOR_24_8; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z16: + format = COLOR_16; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_Z32: + format = COLOR_32; + comp_swap = SWAP_STD; + SETfield(cb_color0_info, ARRAY_1D_TILED_THIN1, + CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); + CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SRGBA8: + format = COLOR_8_8_8_8; + comp_swap = SWAP_STD_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SLA8: + format = COLOR_8_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + case MESA_FORMAT_SL8: + format = COLOR_8; + comp_swap = SWAP_ALT_REV; + SETbit(cb_color0_info, SOURCE_FORMAT_bit); + SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); + break; + default: + fprintf(stderr,"Invalid format for copy %s\n",_mesa_get_format_name(mesa_format)); + assert("Invalid format for US output\n"); + return; + } + + SETfield(cb_color0_info, format, CB_COLOR0_INFO__FORMAT_shift, + CB_COLOR0_INFO__FORMAT_mask); + SETfield(cb_color0_info, comp_swap, COMP_SWAP_shift, COMP_SWAP_mask); + + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_BASE + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + + if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) && + (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) { + BEGIN_BATCH_NO_AUTOSTATE(2); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); + R600_OUT_BATCH((2 << id)); + END_BATCH(); + } + + /* Set CMASK & TILE buffer to the offset of color buffer as + * we don't use those this shouldn't cause any issue and we + * then have a valid cmd stream + */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_TILE + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_FRAG + (4 * id), 1); + R600_OUT_BATCH(cb_color0_base); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(12); + R600_OUT_BATCH_REGVAL(CB_COLOR0_SIZE + (4 * id), cb_color0_size); + R600_OUT_BATCH_REGVAL(CB_COLOR0_VIEW + (4 * id), cb_color0_view); + R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), cb_color0_info); + R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), 0); + END_BATCH(); + + COMMIT_BATCH(); + +} + +static inline void load_shaders(GLcontext * ctx) +{ + + radeonContextPtr radeonctx = RADEON_CONTEXT(ctx); + context_t *context = R700_CONTEXT(ctx); + int i, size; + uint32_t *shader; + + if (context->blit_bo_loaded == 1) + return; + + size = 4096; + context->blit_bo = radeon_bo_open(radeonctx->radeonScreen->bom, 0, + size, 256, RADEON_GEM_DOMAIN_GTT, 0); + radeon_bo_map(context->blit_bo, 1); + shader = context->blit_bo->ptr; + + for(i=0; i<sizeof(r6xx_vs)/4; i++) { + shader[128+i] = r6xx_vs[i]; + } + for(i=0; i<sizeof(r6xx_ps)/4; i++) { + shader[256+i] = r6xx_ps[i]; + } + + radeon_bo_unmap(context->blit_bo); + context->blit_bo_loaded = 1; + +} + +static inline void +set_shaders(context_t *context) +{ + struct radeon_bo * pbo = context->blit_bo; + BATCH_LOCALS(&context->radeon); + + uint32_t sq_pgm_start_fs = (512 >> 8); + uint32_t sq_pgm_resources_fs = 0; + uint32_t sq_pgm_cf_offset_fs = 0; + + uint32_t sq_pgm_start_vs = (512 >> 8); + uint32_t sq_pgm_resources_vs = (1 << NUM_GPRS_shift); + uint32_t sq_pgm_cf_offset_vs = 0; + + uint32_t sq_pgm_start_ps = (1024 >> 8); + uint32_t sq_pgm_resources_ps = (1 << NUM_GPRS_shift); + uint32_t sq_pgm_cf_offset_ps = 0; + uint32_t sq_pgm_exports_ps = (1 << 1); + + r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit); + + /* FS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1); + R600_OUT_BATCH(sq_pgm_start_fs); + R600_OUT_BATCH_RELOC(sq_pgm_start_fs, + pbo, + sq_pgm_start_fs, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(6); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_FS, sq_pgm_resources_fs); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_FS, sq_pgm_cf_offset_fs); + END_BATCH(); + + /* VS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1); + R600_OUT_BATCH(sq_pgm_start_vs); + R600_OUT_BATCH_RELOC(sq_pgm_start_vs, + pbo, + sq_pgm_start_vs, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(6); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_VS, sq_pgm_resources_vs); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_VS, sq_pgm_cf_offset_vs); + END_BATCH(); + + /* PS */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1); + R600_OUT_BATCH(sq_pgm_start_ps); + R600_OUT_BATCH_RELOC(sq_pgm_start_ps, + pbo, + sq_pgm_start_ps, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(9); + R600_OUT_BATCH_REGVAL(SQ_PGM_RESOURCES_PS, sq_pgm_resources_ps); + R600_OUT_BATCH_REGVAL(SQ_PGM_EXPORTS_PS, sq_pgm_exports_ps); + R600_OUT_BATCH_REGVAL(SQ_PGM_CF_OFFSET_PS, sq_pgm_cf_offset_ps); + END_BATCH(); + + BEGIN_BATCH_NO_AUTOSTATE(18); + R600_OUT_BATCH_REGVAL(SPI_VS_OUT_CONFIG, 0); //EXPORT_COUNT is - 1 + R600_OUT_BATCH_REGVAL(SPI_VS_OUT_ID_0, 0); + R600_OUT_BATCH_REGVAL(SPI_PS_INPUT_CNTL_0, SEL_CENTROID_bit); + R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_0, (1 << NUM_INTERP_shift)); + R600_OUT_BATCH_REGVAL(SPI_PS_IN_CONTROL_1, 0); + R600_OUT_BATCH_REGVAL(SPI_INTERP_CONTROL_0, 0); + END_BATCH(); + + COMMIT_BATCH(); + +} + +static inline void +set_vtx_resource(context_t *context) +{ + struct radeon_bo *bo = context->blit_bo; + BATCH_LOCALS(&context->radeon); + + BEGIN_BATCH_NO_AUTOSTATE(6); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1)); + R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); + R600_OUT_BATCH(0); + + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1)); + R600_OUT_BATCH(mmSQ_VTX_START_INST_LOC - ASIC_CTL_CONST_BASE_INDEX); + R600_OUT_BATCH(0); + END_BATCH(); + COMMIT_BATCH(); + + if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710)) + r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit); + else + r700SyncSurf(context, bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit); + + BEGIN_BATCH_NO_AUTOSTATE(9 + 2); + + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + R600_OUT_BATCH(SQ_FETCH_RESOURCE_VS_OFFSET * FETCH_RESOURCE_STRIDE); + R600_OUT_BATCH(0); + R600_OUT_BATCH(48 - 1); + R600_OUT_BATCH(16 << SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift); + R600_OUT_BATCH(1 << MEM_REQUEST_SIZE_shift); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(SQ_TEX_VTX_VALID_BUFFER << SQ_TEX_RESOURCE_WORD6_0__TYPE_shift); + R600_OUT_BATCH_RELOC(SQ_VTX_CONSTANT_WORD0_0, + bo, + SQ_VTX_CONSTANT_WORD0_0, + RADEON_GEM_DOMAIN_GTT, 0, 0); + END_BATCH(); + COMMIT_BATCH(); + +} + +static inline void +set_tex_resource(context_t * context, + gl_format mesa_format, struct radeon_bo *bo, int w, int h, + int TexelPitch, intptr_t src_offset) +{ + uint32_t sq_tex_resource0, sq_tex_resource1, sq_tex_resource2, sq_tex_resource4, sq_tex_resource6; + + sq_tex_resource0 = sq_tex_resource1 = sq_tex_resource2 = sq_tex_resource4 = sq_tex_resource6 = 0; + BATCH_LOCALS(&context->radeon); + + SETfield(sq_tex_resource0, SQ_TEX_DIM_2D, DIM_shift, DIM_mask); + SETfield(sq_tex_resource0, ARRAY_LINEAR_GENERAL, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + + switch (mesa_format) { + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_SIGNED_RGBA8888: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888) { + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + } + break; + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_SIGNED_RGBA8888_REV: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888_REV) { + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask); + SETfield(sq_tex_resource4, SQ_FORMAT_COMP_SIGNED, + FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + } + break; + case MESA_FORMAT_ARGB8888: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_XRGB8888: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB8888_REV: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_XRGB8888_REV: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGB565: + SETfield(sq_tex_resource1, FMT_5_6_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGB565_REV: + SETfield(sq_tex_resource1, FMT_5_6_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB4444: + SETfield(sq_tex_resource1, FMT_4_4_4_4, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB4444_REV: + SETfield(sq_tex_resource1, FMT_4_4_4_4, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB1555: + SETfield(sq_tex_resource1, FMT_1_5_5_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ARGB1555_REV: + SETfield(sq_tex_resource1, FMT_1_5_5_5, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: /* TODO : Check this. */ + SETfield(sq_tex_resource1, FMT_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGB332: + SETfield(sq_tex_resource1, FMT_3_3_2, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_A8: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_L8: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_I8: /* X, X, X, X */ + case MESA_FORMAT_CI8: + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGBA_FLOAT32: + SETfield(sq_tex_resource1, FMT_32_32_32_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_RGBA_FLOAT16: + SETfield(sq_tex_resource1, FMT_16_16_16_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT32: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_ALPHA_FLOAT16: /* ZERO, ZERO, ZERO, X */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT32: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_FLOAT16: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + SETfield(sq_tex_resource1, FMT_32_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + SETfield(sq_tex_resource1, FMT_16_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */ + SETfield(sq_tex_resource1, FMT_32_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */ + SETfield(sq_tex_resource1, FMT_16_FLOAT, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z16: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_16, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_X8_Z24: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8_24, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_S8_Z24: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8_24, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z24_S8: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_24_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_0, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_Z32: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_32, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_S8: + SETbit(sq_tex_resource0, TILE_TYPE_bit); + SETfield(sq_tex_resource0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_SRGBA8: + SETfield(sq_tex_resource1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + SETbit(sq_tex_resource4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); + break; + case MESA_FORMAT_SLA8: + SETfield(sq_tex_resource1, FMT_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + SETbit(sq_tex_resource4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); + break; + case MESA_FORMAT_SL8: /* X, X, X, ONE */ + SETfield(sq_tex_resource1, FMT_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + SETbit(sq_tex_resource4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); + break; + default: + fprintf(stderr,"Invalid format for copy %s\n",_mesa_get_format_name(mesa_format)); + assert("Invalid format for US output\n"); + return; + }; + + SETfield(sq_tex_resource0, (TexelPitch/8)-1, PITCH_shift, PITCH_mask); + SETfield(sq_tex_resource0, w - 1, TEX_WIDTH_shift, TEX_WIDTH_mask); + SETfield(sq_tex_resource1, h - 1, TEX_HEIGHT_shift, TEX_HEIGHT_mask); + + sq_tex_resource2 = src_offset / 256; + + SETfield(sq_tex_resource6, SQ_TEX_VTX_VALID_TEXTURE, + SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, + SQ_TEX_RESOURCE_WORD6_0__TYPE_mask); + + r700SyncSurf(context, bo, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, + 0, TC_ACTION_ENA_bit); + + BEGIN_BATCH_NO_AUTOSTATE(9 + 4); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + R600_OUT_BATCH(0 * 7); + + R600_OUT_BATCH(sq_tex_resource0); + R600_OUT_BATCH(sq_tex_resource1); + R600_OUT_BATCH(sq_tex_resource2); + R600_OUT_BATCH(0); //SQ_TEX_RESOURCE3 + R600_OUT_BATCH(sq_tex_resource4); + R600_OUT_BATCH(0); //SQ_TEX_RESOURCE5 + R600_OUT_BATCH(sq_tex_resource6); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + END_BATCH(); + COMMIT_BATCH(); +} + +static inline void +set_tex_sampler(context_t * context) +{ + uint32_t sq_tex_sampler_word0 = 0, sq_tex_sampler_word1 = 0, sq_tex_sampler_word2 = 0; + int i = 0; + + SETbit(sq_tex_sampler_word2, SQ_TEX_SAMPLER_WORD2_0__TYPE_bit); + + BATCH_LOCALS(&context->radeon); + + BEGIN_BATCH_NO_AUTOSTATE(5); + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3)); + R600_OUT_BATCH(i * 3); + R600_OUT_BATCH(sq_tex_sampler_word0); + R600_OUT_BATCH(sq_tex_sampler_word1); + R600_OUT_BATCH(sq_tex_sampler_word2); + END_BATCH(); + +} + +static inline void +set_scissors(context_t *context, int x1, int y1, int x2, int y2) +{ + BATCH_LOCALS(&context->radeon); + + BEGIN_BATCH_NO_AUTOSTATE(17); + R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2); + R600_OUT_BATCH((x1 << 0) | (y1 << 16)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 3); + R600_OUT_BATCH(0); //PA_SC_WINDOW_OFFSET + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); //PA_SC_WINDOW_SCISSOR_TL + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2); + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + + /* XXX 16 of these PA_SC_VPORT_SCISSOR_0_TL_num ... */ + R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_SCISSOR_0_TL, 2 ); + R600_OUT_BATCH((x1 << 0) | (y1 << 16) | (WINDOW_OFFSET_DISABLE_bit)); + R600_OUT_BATCH((x2 << 0) | (y2 << 16)); + END_BATCH(); + + COMMIT_BATCH(); + +} + +static inline void +set_vb_data(context_t * context, int src_x, int src_y, int dst_x, int dst_y, + int w, int h, int src_h, unsigned flip_y) +{ + float *vb; + radeon_bo_map(context->blit_bo, 1); + vb = context->blit_bo->ptr; + + vb[0] = (float)(dst_x); + vb[1] = (float)(dst_y); + vb[2] = (float)(src_x); + vb[3] = (flip_y) ? (float)(src_h - src_y) : (float)src_y; + + vb[4] = (float)(dst_x); + vb[5] = (float)(dst_y + h); + vb[6] = (float)(src_x); + vb[7] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h); + + vb[8] = (float)(dst_x + w); + vb[9] = (float)(dst_y + h); + vb[10] = (float)(src_x + w); + vb[11] = (flip_y) ? (float)(src_h - (src_y + h)) : (float)(src_y + h); + + radeon_bo_unmap(context->blit_bo); + +} + +static inline void +draw_auto(context_t *context) +{ + BATCH_LOCALS(&context->radeon); + uint32_t vgt_primitive_type = 0, vgt_index_type = 0, vgt_draw_initiator = 0, vgt_num_indices; + + SETfield(vgt_primitive_type, DI_PT_RECTLIST, + VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, + VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask); + SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, + INDEX_TYPE_mask); + SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, + MAJOR_MODE_mask); + SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, + SOURCE_SELECT_mask); + + vgt_num_indices = 3; + + BEGIN_BATCH_NO_AUTOSTATE(10); + // prim + R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1); + R600_OUT_BATCH(vgt_primitive_type); + // index type + R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); + R600_OUT_BATCH(vgt_index_type); + // num instances + R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); + R600_OUT_BATCH(1); + // + R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); + R600_OUT_BATCH(vgt_num_indices); + R600_OUT_BATCH(vgt_draw_initiator); + + END_BATCH(); + COMMIT_BATCH(); +} + +static inline void +set_default_state(context_t *context) +{ + int ps_prio = 0; + int vs_prio = 1; + int gs_prio = 2; + int es_prio = 3; + int num_ps_gprs; + int num_vs_gprs; + int num_gs_gprs; + int num_es_gprs; + int num_temp_gprs; + int num_ps_threads; + int num_vs_threads; + int num_gs_threads; + int num_es_threads; + int num_ps_stack_entries; + int num_vs_stack_entries; + int num_gs_stack_entries; + int num_es_stack_entries; + uint32_t sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; + uint32_t sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; + uint32_t ta_cntl_aux, db_watermarks, sq_dyn_gpr_cntl_ps_flush_req, db_debug; + BATCH_LOCALS(&context->radeon); + + switch (context->radeon.radeonScreen->chip_family) { + case CHIP_FAMILY_R600: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV630: + case CHIP_FAMILY_RV635: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 40; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV610: + case CHIP_FAMILY_RV620: + case CHIP_FAMILY_RS780: + case CHIP_FAMILY_RS880: + default: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV670: + num_ps_gprs = 144; + num_vs_gprs = 40; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_FAMILY_RV770: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 256; + num_vs_stack_entries = 256; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV730: + case CHIP_FAMILY_RV740: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_FAMILY_RV710: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 48; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + } + + sq_config = 0; + if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) || + (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710)) + CLEARbit(sq_config, VC_ENABLE_bit); + else + SETbit(sq_config, VC_ENABLE_bit); + SETbit(sq_config, DX9_CONSTS_bit); + SETbit(sq_config, ALU_INST_PREFER_VECTOR_bit); + SETfield(sq_config, ps_prio, PS_PRIO_shift, PS_PRIO_mask); + SETfield(sq_config, vs_prio, VS_PRIO_shift, VS_PRIO_mask); + SETfield(sq_config, gs_prio, GS_PRIO_shift, GS_PRIO_mask); + SETfield(sq_config, es_prio, ES_PRIO_shift, ES_PRIO_mask); + + sq_gpr_resource_mgmt_1 = 0; + SETfield(sq_gpr_resource_mgmt_1, num_ps_gprs, NUM_PS_GPRS_shift, NUM_PS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_1, num_vs_gprs, NUM_VS_GPRS_shift, NUM_VS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_1, num_temp_gprs, + NUM_CLAUSE_TEMP_GPRS_shift, NUM_CLAUSE_TEMP_GPRS_mask); + + sq_gpr_resource_mgmt_2 = 0; + SETfield(sq_gpr_resource_mgmt_2, num_gs_gprs, NUM_GS_GPRS_shift, NUM_GS_GPRS_mask); + SETfield(sq_gpr_resource_mgmt_2, num_es_gprs, NUM_ES_GPRS_shift, NUM_ES_GPRS_mask); + + sq_thread_resource_mgmt = 0; + SETfield(sq_thread_resource_mgmt, num_ps_threads, + NUM_PS_THREADS_shift, NUM_PS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_vs_threads, + NUM_VS_THREADS_shift, NUM_VS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_gs_threads, + NUM_GS_THREADS_shift, NUM_GS_THREADS_mask); + SETfield(sq_thread_resource_mgmt, num_es_threads, + NUM_ES_THREADS_shift, NUM_ES_THREADS_mask); + + sq_stack_resource_mgmt_1 = 0; + SETfield(sq_stack_resource_mgmt_1, num_ps_stack_entries, + NUM_PS_STACK_ENTRIES_shift, NUM_PS_STACK_ENTRIES_mask); + SETfield(sq_stack_resource_mgmt_1, num_vs_stack_entries, + NUM_VS_STACK_ENTRIES_shift, NUM_VS_STACK_ENTRIES_mask); + + sq_stack_resource_mgmt_2 = 0; + SETfield(sq_stack_resource_mgmt_2, num_gs_stack_entries, + NUM_GS_STACK_ENTRIES_shift, NUM_GS_STACK_ENTRIES_mask); + SETfield(sq_stack_resource_mgmt_2, num_es_stack_entries, + NUM_ES_STACK_ENTRIES_shift, NUM_ES_STACK_ENTRIES_mask); + + ta_cntl_aux = 0; + SETfield(ta_cntl_aux, 28, TD_FIFO_CREDIT_shift, TD_FIFO_CREDIT_mask); + db_watermarks = 0; + SETfield(db_watermarks, 4, DEPTH_FREE_shift, DEPTH_FREE_mask); + SETfield(db_watermarks, 16, DEPTH_FLUSH_shift, DEPTH_FLUSH_mask); + SETfield(db_watermarks, 0, FORCE_SUMMARIZE_shift, FORCE_SUMMARIZE_mask); + SETfield(db_watermarks, 4, DEPTH_PENDING_FREE_shift, DEPTH_PENDING_FREE_mask); + sq_dyn_gpr_cntl_ps_flush_req = 0; + db_debug = 0; + if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) { + SETfield(ta_cntl_aux, 3, GRADIENT_CREDIT_shift, GRADIENT_CREDIT_mask); + db_debug = 0x82000000; + SETfield(db_watermarks, 16, DEPTH_CACHELINE_FREE_shift, DEPTH_CACHELINE_FREE_mask); + } else { + SETfield(ta_cntl_aux, 2, GRADIENT_CREDIT_shift, GRADIENT_CREDIT_mask); + SETfield(db_watermarks, 4, DEPTH_CACHELINE_FREE_shift, DEPTH_CACHELINE_FREE_mask); + SETbit(sq_dyn_gpr_cntl_ps_flush_req, VS_PC_LIMIT_ENABLE_bit); + } + + BEGIN_BATCH_NO_AUTOSTATE(117); + R600_OUT_BATCH_REGSEQ(SQ_CONFIG, 6); + R600_OUT_BATCH(sq_config); + R600_OUT_BATCH(sq_gpr_resource_mgmt_1); + R600_OUT_BATCH(sq_gpr_resource_mgmt_2); + R600_OUT_BATCH(sq_thread_resource_mgmt); + R600_OUT_BATCH(sq_stack_resource_mgmt_1); + R600_OUT_BATCH(sq_stack_resource_mgmt_2); + + R600_OUT_BATCH_REGVAL(TA_CNTL_AUX, ta_cntl_aux); + R600_OUT_BATCH_REGVAL(VC_ENHANCE, 0); + R600_OUT_BATCH_REGVAL(R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, sq_dyn_gpr_cntl_ps_flush_req); + R600_OUT_BATCH_REGVAL(DB_DEBUG, db_debug); + R600_OUT_BATCH_REGVAL(DB_WATERMARKS, db_watermarks); + + R600_OUT_BATCH_REGSEQ(SQ_ESGS_RING_ITEMSIZE, 9); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(CB_CLRCMP_CONTROL, + (CLRCMP_SEL_SRC << CLRCMP_FCN_SEL_shift)); + R600_OUT_BATCH_REGVAL(SQ_VTX_BASE_VTX_LOC, 0); + R600_OUT_BATCH_REGVAL(SQ_VTX_START_INST_LOC, 0); + R600_OUT_BATCH_REGVAL(DB_DEPTH_INFO, 0); + R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, 0); + R600_OUT_BATCH_REGVAL(CB_SHADER_MASK, (OUTPUT0_ENABLE_mask)); + R600_OUT_BATCH_REGVAL(CB_TARGET_MASK, (TARGET0_ENABLE_mask)); + R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, (RT0_ENABLE_bit)); + R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, (0xcc << ROP3_shift)); + + R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, VTX_XY_FMT_bit); + R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, 0); + R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, CLIP_DISABLE_bit); + R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, (FACE_bit) | + (POLYMODE_PTYPE__TRIANGLES << POLYMODE_FRONT_PTYPE_shift) | + (POLYMODE_PTYPE__TRIANGLES << POLYMODE_BACK_PTYPE_shift)); + R600_OUT_BATCH_REGVAL(PA_SU_VTX_CNTL, (PIX_CENTER_bit) | + (X_ROUND_TO_EVEN << PA_SU_VTX_CNTL__ROUND_MODE_shift) | + (X_1_256TH << QUANT_MODE_shift)); + + R600_OUT_BATCH_REGSEQ(VGT_MAX_VTX_INDX, 4); + R600_OUT_BATCH(2048); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGSEQ(VGT_OUTPUT_PATH_CNTL, 13); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(VGT_PRIMITIVEID_EN, 0); + R600_OUT_BATCH_REGVAL(VGT_MULTI_PRIM_IB_RESET_EN, 0); + R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_0, 0); + R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_1, 0); + + R600_OUT_BATCH_REGSEQ(VGT_STRMOUT_EN, 3); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + R600_OUT_BATCH(0); + + R600_OUT_BATCH_REGVAL(VGT_STRMOUT_BUFFER_EN, 0); + + END_BATCH(); + COMMIT_BATCH(); +} + +static GLboolean validate_buffers(context_t *rmesa, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, + rmesa->blit_bo, RADEON_GEM_DOMAIN_GTT, 0); + + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, + rmesa->blit_bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, + first_elem(&rmesa->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +unsigned r600_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x, + unsigned src_y, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x, + unsigned dst_y, + unsigned w, + unsigned h, + unsigned flip_y) +{ + context_t *context = R700_CONTEXT(ctx); + int id = 0; + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 256 || dst_offset % 256) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: width %d, height %d, pitch %d vs %d, format %s\n", + src_width, src_height, src_pitch, + _mesa_format_row_stride(src_mesaformat, src_width), + _mesa_get_format_name(src_mesaformat)); + fprintf(stderr, "dst: width %d, height %d, pitch %d, format %s\n", + dst_width, dst_height, + _mesa_format_row_stride(dst_mesaformat, dst_width), + _mesa_get_format_name(dst_mesaformat)); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(ctx); + + rcommonEnsureCmdBufSpace(&context->radeon, 304, __FUNCTION__); + + /* load shaders */ + load_shaders(context->radeon.glCtx); + + if (!validate_buffers(context, src_bo, dst_bo)) + return GL_FALSE; + + /* set clear state */ + /* 117 */ + set_default_state(context); + + /* shaders */ + /* 72 */ + set_shaders(context); + + /* src */ + /* 20 */ + set_tex_resource(context, src_mesaformat, src_bo, + src_width, src_height, src_pitch, src_offset); + + /* 5 */ + set_tex_sampler(context); + + /* dst */ + /* 27 */ + set_render_target(context, dst_bo, dst_mesaformat, + dst_pitch, dst_width, dst_height, dst_offset); + /* scissors */ + /* 17 */ + set_scissors(context, dst_x, dst_y, dst_x + dst_width, dst_y + dst_height); + + set_vb_data(context, src_x, src_y, dst_x, dst_y, w, h, src_height, flip_y); + /* Vertex buffer setup */ + /* 24 */ + set_vtx_resource(context); + + /* draw */ + /* 10 */ + draw_auto(context); + + /* 7 */ + r700SyncSurf(context, dst_bo, 0, + RADEON_GEM_DOMAIN_VRAM|RADEON_GEM_DOMAIN_GTT, + CB_ACTION_ENA_bit | (1 << (id + 6))); + + /* 5 */ + /* XXX drm should handle this in fence submit */ + r700WaitForIdleClean(context); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/r600/r600_blit.h b/src/mesa/drivers/dri/r600/r600_blit.h new file mode 100644 index 0000000000..f280e23489 --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit.h @@ -0,0 +1,21 @@ +unsigned r600_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned w, + unsigned h, + unsigned flip_y); + diff --git a/src/mesa/drivers/dri/r600/r600_blit_shaders.h b/src/mesa/drivers/dri/r600/r600_blit_shaders.h new file mode 100644 index 0000000000..492dde9636 --- /dev/null +++ b/src/mesa/drivers/dri/r600/r600_blit_shaders.h @@ -0,0 +1,28 @@ +const uint32_t r6xx_vs[] = +{ + 0x00000004, // CF_DWORD0(ADDR(4)) + 0x81000000, // SQ_CF_INST_VTX COUNT(1) + 0x0000203c, // CF_EXP_IMP CF_POS0 SQ_EXPORT_POS RW_GPR(0) ELEM_SIZE(0) + 0x94000b08, // SQ_CF_INST_EXPORT_DONE SWZ XY01 BARRIER(1) + 0x00004000, // CF_EXP_IMP 0 SQ_EXPORT_PARAM RW_GPR(0) ELEM_SIZE(0) + 0x14200b1a, // SQ_CF_INST_EXPORT_DONE SWZ ZW01 EOP(1) BARRIER(0) + 0x00000000, + 0x00000000, + 0x3c000000, // SQ_VTX_INST_FETCH BUFFER_ID(0) MEGA_FETCH_COUNT(16) + 0x68cd1000, // DST_GPR(0) DST_SWZ: XYZW DATA_FORMAT(35) SQ_NUM_FORMAT_SCALED SQ_FORMAT_COMP_SIGNED + 0x00080000, // ENDIAN_SWAP(SQ_ENDIAN_NONE) MEGA_FETCH(1) + 0x00000000, // VTX_DWORD_PAD +}; + +const uint32_t r6xx_ps[] = +{ + 0x00000002, // CF_DWORD0 AADR(2) + 0x80800000, // SQ_CF_INST_TEX COUNT(1) + 0x00000000, // CF_ALLOC_IMP_EXP0 SQ_EXPORT_PIXEL RW_GPR(0) ELEM_SIZE(0) + 0x94200688, // SQ_CF_INST_EXPORT_DONE EOP(1) BARRIER(1) SWZ: XYZW + 0x00000010, // SQ_TEX_INST_SAMPLE SRC_GPR(0) RESOURCE_ID(0) + 0x000d1000, // DST_GPR(0) SWZ: XYZW TEX_UNNORMALIZED + 0xb0800000, // SAMPLER_ID(0) SRC_SWZ XYZW + 0x00000000, // TEX_DWORD_PAD +}; + diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c index 370bb04f93..afe2d55dc7 100644 --- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c +++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "drm.h" #include "radeon_drm.h" @@ -49,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r600_cmdbuf.h" #include "r600_emit.h" #include "radeon_bocs_wrapper.h" -#include "radeon_mipmap_tree.h" #include "radeon_reg.h" #ifdef HAVE_LIBDRM_RADEON diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index cb549497f5..5b7d7c28ec 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -40,9 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/state.h" #include "main/bufferobj.h" #include "main/texobj.h" @@ -52,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "drivers/common/driverfuncs.h" @@ -65,14 +62,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r600_emit.h" #include "radeon_bocs_wrapper.h" #include "radeon_queryobj.h" +#include "r600_blit.h" #include "r700_state.h" #include "r700_ioctl.h" -#include "vblank.h" #include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ #define R600_ENABLE_GLSL_TEST 1 @@ -240,19 +236,23 @@ static void r600_init_vtbl(radeonContextPtr radeon) radeon->vtbl.pre_emit_atoms = r600_vtbl_pre_emit_atoms; radeon->vtbl.fallback = r600_fallback; radeon->vtbl.emit_query_finish = r600_emit_query_finish; + radeon->vtbl.blit = r600_blit; } static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen) { - context_t *r600 = R700_CONTEXT(ctx); - - ctx->Const.MaxTextureImageUnits = - driQueryOptioni(&r600->radeon.optionCache, "texture_image_units"); - ctx->Const.MaxTextureCoordUnits = - driQueryOptioni(&r600->radeon.optionCache, "texture_coord_units"); + ctx->Const.MaxTextureImageUnits = 16; + /* 8 per clause on r6xx, 16 on r7xx + * but I think mesa only supports 8 at the moment + */ + ctx->Const.MaxTextureCoordUnits = 8; ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits); + ctx->Const.MaxCombinedTextureImageUnits = + ctx->Const.MaxVertexTextureImageUnits + + ctx->Const.MaxTextureImageUnits; + ctx->Const.MaxTextureMaxAnisotropy = 16.0; ctx->Const.MaxTextureLodBias = 16.0; @@ -284,9 +284,8 @@ static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen) ctx->Const.FragmentProgram.MaxNativeAttribs = 32; ctx->Const.FragmentProgram.MaxNativeParameters = 256; ctx->Const.FragmentProgram.MaxNativeAluInstructions = 8192; - /* 8 per clause on r6xx, 16 on rv670/r7xx */ - if ((screen->chip_family == CHIP_FAMILY_RV670) || - (screen->chip_family >= CHIP_FAMILY_RV770)) + /* 8 per clause on r6xx, 16 on r7xx */ + if (screen->chip_family >= CHIP_FAMILY_RV770) ctx->Const.FragmentProgram.MaxNativeTexInstructions = 16; else ctx->Const.FragmentProgram.MaxNativeTexInstructions = 8; @@ -378,7 +377,7 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual, _mesa_init_driver_functions(&functions); r700InitStateFuncs(&functions); - r600InitTextureFuncs(&functions); + r600InitTextureFuncs(&r600->radeon, &functions); r700InitShaderFuncs(&functions); radeonInitQueryObjFunctions(&functions); r700InitIoctlFuncs(&functions); diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h index a1b4af715e..72c8c869b7 100644 --- a/src/mesa/drivers/dri/r600/r600_context.h +++ b/src/mesa/drivers/dri/r600/r600_context.h @@ -148,6 +148,8 @@ struct r600_context { GLint nNumActiveAos; StreamDesc stream_desc[VERT_ATTRIB_MAX]; struct r700_index_buffer ind_buf; + struct radeon_bo *blit_bo; + GLboolean blit_bo_loaded; }; #define R700_CONTEXT(ctx) ((context_t *)(ctx->DriverCtx)) @@ -178,6 +180,8 @@ extern GLboolean r700SyncSurf(context_t *context, uint32_t write_domain, uint32_t sync_type); +extern void r700WaitForIdleClean(context_t *context); + extern void r700Start3D(context_t *context); extern void r600InitAtoms(context_t *context); extern void r700InitDraw(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c index 5c250c2418..1eb89a5305 100644 --- a/src/mesa/drivers/dri/r600/r600_emit.c +++ b/src/mesa/drivers/dri/r600/r600_emit.c @@ -37,10 +37,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/colormac.h" #include "main/imports.h" #include "main/macros.h" -#include "main/image.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" diff --git a/src/mesa/drivers/dri/r600/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c index f745fe3e8a..36a6e6e0a1 100644 --- a/src/mesa/drivers/dri/r600/r600_tex.c +++ b/src/mesa/drivers/dri/r600/r600_tex.c @@ -41,18 +41,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/mipmap.h" #include "main/simple_list.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "texmem.h" #include "r600_context.h" -#include "r700_state.h" #include "radeon_mipmap_tree.h" #include "r600_tex.h" -#include "xmlpool.h" - static unsigned int translate_wrap_mode(GLenum wrapmode) { @@ -396,7 +392,7 @@ static struct gl_texture_object *r600NewTextureObject(GLcontext * ctx, return &t->base; } -void r600InitTextureFuncs(struct dd_function_table *functions) +void r600InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions) { /* Note: we only plug in the functions we implement in the driver * since _mesa_init_driver_functions() was already called. @@ -424,6 +420,11 @@ void r600InitTextureFuncs(struct dd_function_table *functions) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; driInitTextureFormats(); diff --git a/src/mesa/drivers/dri/r600/r600_tex.h b/src/mesa/drivers/dri/r600/r600_tex.h index fb0e1a023e..1d75a2ecd6 100644 --- a/src/mesa/drivers/dri/r600/r600_tex.h +++ b/src/mesa/drivers/dri/r600/r600_tex.h @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Texel pitch is 8 alignment. */ #define R700_TEXEL_PITCH_ALIGNMENT_MASK 0x7 -#define R700_MAX_TEXTURE_UNITS 8 /* TODO : should be 16, lets make it work, review later */ +#define R700_MAX_TEXTURE_UNITS 16 extern void r600SetDepthTexMode(struct gl_texture_object *tObj); @@ -58,6 +58,6 @@ extern void r600SetTexOffset(__DRIcontext *pDRICtx, GLint texname, extern GLboolean r600ValidateBuffers(GLcontext * ctx); -extern void r600InitTextureFuncs(struct dd_function_table *functions); +extern void r600InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions); #endif /* __r600_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c index b8466bdd75..8228cd67c8 100644 --- a/src/mesa/drivers/dri/r600/r600_texstate.c +++ b/src/mesa/drivers/dri/r600/r600_texstate.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "r600_context.h" -#include "r700_state.h" #include "radeon_mipmap_tree.h" #include "r600_tex.h" #include "r700_fragprog.h" @@ -85,6 +84,7 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED, FORMAT_COMP_X_shift, FORMAT_COMP_X_mask); @@ -95,6 +95,11 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED, FORMAT_COMP_W_shift, FORMAT_COMP_W_mask); + CLEARbit(t->SQ_TEX_RESOURCE0, TILE_TYPE_bit); + SETfield(t->SQ_TEX_RESOURCE0, ARRAY_LINEAR_GENERAL, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); + switch (mesa_format) /* This is mesa format. */ { case MESA_FORMAT_RGBA8888: @@ -158,6 +163,32 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); break; + case MESA_FORMAT_XRGB8888: + SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; + case MESA_FORMAT_XRGB8888_REV: + SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8, + SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); + + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); + break; case MESA_FORMAT_ARGB8888_REV: SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); @@ -515,6 +546,10 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa case MESA_FORMAT_Z24_S8: case MESA_FORMAT_Z32: case MESA_FORMAT_S8: + SETbit(t->SQ_TEX_RESOURCE0, TILE_TYPE_bit); + SETfield(t->SQ_TEX_RESOURCE0, ARRAY_1D_TILED_THIN1, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, + SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask); switch (mesa_format) { case MESA_FORMAT_Z16: SETfield(t->SQ_TEX_RESOURCE1, FMT_16, @@ -651,6 +686,12 @@ static GLuint r600_translate_shadow_func(GLenum func) } } +static INLINE uint32_t +S_FIXED(float value, uint32_t frac_bits) +{ + return value * (1 << frac_bits); +} + void r600SetDepthTexMode(struct gl_texture_object *tObj) { radeonTexObjPtr t; @@ -670,8 +711,9 @@ void r600SetDepthTexMode(struct gl_texture_object *tObj) * \param rmesa Context pointer * \param t the r300 texture object */ -static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *texObj) +static void setup_hardware_state(GLcontext * ctx, struct gl_texture_object *texObj, int unit) { + context_t *rmesa = R700_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); const struct gl_texture_image *firstImage; GLuint uTexelPitch, row_align; @@ -733,11 +775,21 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex t->SQ_TEX_RESOURCE2 = get_base_teximage_offset(t) / 256; - if ((t->maxLod - t->minLod) > 0) { - t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256; - SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); - SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask); - } + t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256; + + SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); + SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask); + + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(t->base.MinLod - t->minLod, 0, 15), 6), + MIN_LOD_shift, MIN_LOD_mask); + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(t->base.MaxLod - t->minLod, 0, 15), 6), + MAX_LOD_shift, MAX_LOD_mask); + SETfield(t->SQ_TEX_SAMPLER1, + S_FIXED(CLAMP(ctx->Texture.Unit[unit].LodBias + t->base.LodBias, -16, 16), 6), + SQ_TEX_SAMPLER_WORD1_0__LOD_BIAS_shift, SQ_TEX_SAMPLER_WORD1_0__LOD_BIAS_mask); + if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { SETfield(t->SQ_TEX_SAMPLER0, r600_translate_shadow_func(texObj->CompareFunc), DEPTH_COMPARE_FUNCTION_shift, DEPTH_COMPARE_FUNCTION_mask); @@ -754,9 +806,8 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex * * Mostly this means populating the texture object's mipmap tree. */ -static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj) +static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj, int unit) { - context_t *rmesa = R700_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); if (!radeon_validate_texture_miptree(ctx, texObj)) @@ -764,7 +815,7 @@ static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object /* Configure the hardware registers (more precisely, the cached version * of the hardware registers). */ - setup_hardware_state(rmesa, texObj); + setup_hardware_state(ctx, texObj, unit); t->validated = GL_TRUE; return GL_TRUE; @@ -805,7 +856,7 @@ GLboolean r600ValidateBuffers(GLcontext * ctx) if (!ctx->Texture.Unit[i]._ReallyEnabled) continue; - if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { + if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current, i)) { radeon_warning("failed to validate texture for unit %d.\n", i); } t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 0ff16b4ddd..89adb77bf5 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -4469,7 +4469,7 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) } pAsm->D2.dst2.SaturateMode = 1; - pAsm->S[0].src.rtype = pAsm->D.dst.rtype; + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; pAsm->S[0].src.reg = pAsm->D.dst.reg; noswizzle_PVSSRC(&(pAsm->S[0].src)); noneg_PVSSRC(&(pAsm->S[0].src)); @@ -4491,20 +4491,21 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm) GLboolean assemble_XPD(r700_AssemblerBase *pAsm) { - BITS tmp; + BITS tmp1; + BITS tmp2 = 0; if( GL_FALSE == checkop2(pAsm) ) { return GL_FALSE; } - tmp = gethelpr(pAsm); + tmp1 = gethelpr(pAsm); pAsm->D.dst.opcode = SQ_OP2_INST_MUL; setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; - pAsm->D.dst.reg = tmp; + pAsm->D.dst.reg = tmp1; nomask_PVSDST(&(pAsm->D.dst)); if( GL_FALSE == assemble_src(pAsm, 0, -1) ) @@ -4530,11 +4531,11 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask) { - tmp = gethelpr(pAsm); + tmp2 = gethelpr(pAsm); setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; - pAsm->D.dst.reg = tmp; + pAsm->D.dst.reg = tmp2; nomask_PVSDST(&(pAsm->D.dst)); } @@ -4562,7 +4563,7 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) // result1 + (neg) result0 setaddrmode_PVSSRC(&(pAsm->S[2].src),ADDR_ABSOLUTE); pAsm->S[2].src.rtype = SRC_REG_TEMPORARY; - pAsm->S[2].src.reg = tmp; + pAsm->S[2].src.reg = tmp1; neg_PVSSRC(&(pAsm->S[2].src)); noswizzle_PVSSRC(&(pAsm->S[2].src)); @@ -4585,7 +4586,7 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm) // Use tmp as source setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; - pAsm->S[0].src.reg = tmp; + pAsm->S[0].src.reg = tmp2; noneg_PVSSRC(&(pAsm->S[0].src)); noswizzle_PVSSRC(&(pAsm->S[0].src)); @@ -5090,15 +5091,15 @@ void add_return_inst(r700_AssemblerBase *pAsm) { if(GL_FALSE == add_cf_instruction(pAsm) ) { - return GL_FALSE; + return; } //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0; - pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0; + pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0; pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE; pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0; - pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; + pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0; pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_RETURN; pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0; @@ -5302,7 +5303,7 @@ GLboolean assemble_CAL(r700_AssemblerBase *pAsm, GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) { - GLfloat fLiteral[2] = {0.1, 0.0}; + /*GLfloat fLiteral[2] = {0.1, 0.0};*/ pAsm->D.dst.opcode = SQ_OP2_INST_MOV; pAsm->D.dst.op3 = 0; @@ -5353,7 +5354,7 @@ GLboolean setRetInLoopFlag(r700_AssemblerBase *pAsm, GLuint flagValue) GLboolean testFlag(r700_AssemblerBase *pAsm) { - GLfloat fLiteral[2] = {0.1, 0.0}; + /*GLfloat fLiteral[2] = {0.1, 0.0};*/ //Test flag GLuint tmp = gethelpr(pAsm); @@ -6123,7 +6124,7 @@ GLboolean callPreSub(r700_AssemblerBase* pAsm, R700ControlFlowGenericClause* prelude_cf_ptr = NULL; - /* copy srcs to presub inputs */ + /* copy srcs to presub inputs */ pAsm->alu_x_opcode = SQ_CF_INST_ALU; for(i=0; i<uNumValidSrc; i++) { diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h index 56baf5b0d9..0064d0814f 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.h +++ b/src/mesa/drivers/dri/r600/r700_assembler.h @@ -619,6 +619,7 @@ GLboolean assemble_RCP(r700_AssemblerBase *pAsm); GLboolean assemble_RSQ(r700_AssemblerBase *pAsm); GLboolean assemble_SCS(r700_AssemblerBase *pAsm); GLboolean assemble_SGE(r700_AssemblerBase *pAsm); +GLboolean assemble_CONT(r700_AssemblerBase *pAsm); GLboolean assemble_LOGIC(r700_AssemblerBase *pAsm, BITS opcode); GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode); diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index 3bc2d2ba02..e0be74935b 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -32,12 +32,10 @@ #include "r600_context.h" #include "r600_cmdbuf.h" -#include "r700_state.h" #include "r600_tex.h" #include "r700_oglprog.h" #include "r700_fragprog.h" #include "r700_vertprog.h" -#include "r700_ioctl.h" #include "radeon_mipmap_tree.h" @@ -303,14 +301,13 @@ static void r700SetRenderTarget(context_t *context, int id) R600_STATECHANGE(context, cb_target); /* color buffer */ - r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset; + r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset / 256; nPitchInPixel = rrb->pitch/rrb->cpp; SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, (nPitchInPixel/8)-1, PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask); SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1, SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); - r700->render_target[id].CB_COLOR0_BASE.u32All = 0; SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask); SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ARRAY_LINEAR_GENERAL, CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); @@ -453,13 +450,31 @@ static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom * R600_OUT_BATCH((2 << id)); END_BATCH(); } + /* Set CMASK & TILE buffer to the offset of color buffer as + * we don't use those this shouldn't cause any issue and we + * then have a valid cmd stream + */ + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_TILE + (4 * id), 1); + R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_TILE.u32All); + R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All, + rrb->bo, + r700->render_target[id].CB_COLOR0_BASE.u32All, + 0, RADEON_GEM_DOMAIN_VRAM, 0); + END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(CB_COLOR0_FRAG + (4 * id), 1); + R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_FRAG.u32All); + R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All, + rrb->bo, + r700->render_target[id].CB_COLOR0_BASE.u32All, + 0, RADEON_GEM_DOMAIN_VRAM, 0); + END_BATCH(); - BEGIN_BATCH_NO_AUTOSTATE(18); + BEGIN_BATCH_NO_AUTOSTATE(12); R600_OUT_BATCH_REGVAL(CB_COLOR0_SIZE + (4 * id), r700->render_target[id].CB_COLOR0_SIZE.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_VIEW + (4 * id), r700->render_target[id].CB_COLOR0_VIEW.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), r700->render_target[id].CB_COLOR0_INFO.u32All); - R600_OUT_BATCH_REGVAL(CB_COLOR0_TILE + (4 * id), r700->render_target[id].CB_COLOR0_TILE.u32All); - R600_OUT_BATCH_REGVAL(CB_COLOR0_FRAG + (4 * id), r700->render_target[id].CB_COLOR0_FRAG.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), r700->render_target[id].CB_COLOR0_MASK.u32All); END_BATCH(); diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c index 98bfdd0937..09c48565b6 100644 --- a/src/mesa/drivers/dri/r600/r700_clear.c +++ b/src/mesa/drivers/dri/r600/r700_clear.c @@ -37,7 +37,6 @@ #include "r600_context.h" #include "r700_shaderinst.h" -#include "r600_emit.h" #include "r700_clear.h" static GLboolean r700ClearFast(context_t *context, GLbitfield mask) diff --git a/src/mesa/drivers/dri/r600/r700_ioctl.c b/src/mesa/drivers/dri/r600/r700_ioctl.c index 72a8978976..3bc422f394 100644 --- a/src/mesa/drivers/dri/r600/r700_ioctl.c +++ b/src/mesa/drivers/dri/r600/r700_ioctl.c @@ -32,10 +32,8 @@ #include "main/macros.h" #include "main/context.h" #include "main/simple_list.h" -#include "swrast/swrast.h" #include "radeon_common.h" -#include "radeon_lock.h" #include "r600_context.h" #include "r700_ioctl.h" diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c index 0d476fcd86..2a50361199 100644 --- a/src/mesa/drivers/dri/r600/r700_oglprog.c +++ b/src/mesa/drivers/dri/r600/r700_oglprog.c @@ -132,7 +132,7 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog) _mesa_delete_program(ctx, prog); } -static void +static GLboolean r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog; @@ -153,6 +153,8 @@ r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) break; } + /* XXX check if program is legal, within limits */ + return GL_TRUE; } static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index eab27cbd84..8f14af7472 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -42,7 +42,6 @@ #include "tnl/t_vp_build.h" #include "tnl/t_context.h" #include "tnl/t_vertex.h" -#include "tnl/t_pipeline.h" #include "vbo/vbo_context.h" #include "r600_context.h" @@ -116,8 +115,6 @@ void r700Start3D(context_t *context) END_BATCH(); COMMIT_BATCH(); - - r700WaitForIdleClean(context); } GLboolean r700SyncSurf(context_t *context, @@ -422,7 +419,7 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, } /* start 3d, idle, cb/db flush */ -#define PRE_EMIT_STATE_BUFSZ 10 + 5 + 14 +#define PRE_EMIT_STATE_BUFSZ 5 + 5 + 18 static GLuint r700PredictRenderSize(GLcontext* ctx, const struct _mesa_prim *prim, @@ -935,6 +932,7 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx, radeon_debug_remove_indent(); /* Flush render op cached for last several quads. */ + /* XXX drm should handle this in fence submit */ r700WaitForIdleClean(context); rrb = radeon_get_colorbuffer(&context->radeon); diff --git a/src/mesa/drivers/dri/r600/r700_shader.c b/src/mesa/drivers/dri/r600/r700_shader.c index 2eed1acc2f..67b0d40308 100644 --- a/src/mesa/drivers/dri/r600/r700_shader.c +++ b/src/mesa/drivers/dri/r600/r700_shader.c @@ -35,7 +35,6 @@ #include "main/glheader.h" #include "r600_context.h" -#include "r700_debug.h" #include "r700_shader.h" diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c index 3c8cb579f9..0240eefd5c 100644 --- a/src/mesa/drivers/dri/r600/r700_state.c +++ b/src/mesa/drivers/dri/r600/r700_state.c @@ -26,7 +26,6 @@ #include "main/glheader.h" #include "main/mtypes.h" -#include "main/state.h" #include "main/imports.h" #include "main/enums.h" #include "main/macros.h" @@ -36,11 +35,9 @@ #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vp_build.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "main/api_arrayelt.h" -#include "main/state.h" #include "main/framebuffer.h" #include "shader/prog_parameter.h" @@ -59,6 +56,7 @@ static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state); static void r700UpdatePolygonMode(GLcontext * ctx); static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state); static void r700SetStencilState(GLcontext * ctx, GLboolean state); +static void r700UpdateWindow(GLcontext * ctx, int id); void r700UpdateShaders(GLcontext * ctx) { @@ -780,6 +778,9 @@ static void r700Enable(GLcontext * ctx, GLenum cap, GLboolean state) //--------- case GL_LINE_STIPPLE: r700UpdateLineStipple(ctx); break; + case GL_DEPTH_CLAMP: + r700UpdateWindow(ctx, 0); + break; default: break; } @@ -1576,9 +1577,9 @@ static void r700InitSQConfig(GLcontext * ctx) SETbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit); SETbit(r700->sq_config.SQ_CONFIG.u32All, ALU_INST_PREFER_VECTOR_bit); SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, PS_PRIO_shift, PS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, VS_PRIO_shift, VS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, GS_PRIO_shift, GS_PRIO_mask); - SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, ES_PRIO_shift, ES_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, vs_prio, VS_PRIO_shift, VS_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, gs_prio, GS_PRIO_shift, GS_PRIO_mask); + SETfield(r700->sq_config.SQ_CONFIG.u32All, es_prio, ES_PRIO_shift, ES_PRIO_mask); r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All = 0; SETfield(r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All, num_ps_gprs, NUM_PS_GPRS_shift, NUM_PS_GPRS_mask); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index 782f151f5a..618f7e1be1 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -647,7 +647,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx) /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */ /* so, use ctx->VertexProgem._Current */ struct gl_program_parameter_list *paramListOrginal = - paramListOrginal = ctx->VertexProgram._Current->Base.Parameters; + ctx->VertexProgram._Current->Base.Parameters; _mesa_load_state_parameters(ctx, paramList); diff --git a/src/mesa/drivers/dri/r600/radeon_tex_copy.c b/src/mesa/drivers/dri/r600/radeon_tex_copy.c new file mode 120000 index 0000000000..dfa5ba34e6 --- /dev/null +++ b/src/mesa/drivers/dri/r600/radeon_tex_copy.c @@ -0,0 +1 @@ +../radeon/radeon_tex_copy.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/r600/server/radeon_egl.c b/src/mesa/drivers/dri/r600/server/radeon_egl.c deleted file mode 120000 index d7735a7643..0000000000 --- a/src/mesa/drivers/dri/r600/server/radeon_egl.c +++ /dev/null @@ -1 +0,0 @@ -../../radeon/server/radeon_egl.c
\ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 2b2f2c4aa7..a54ea16ec6 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -26,7 +26,8 @@ RADEON_COMMON_SOURCES = \ radeon_mipmap_tree.c \ radeon_queryobj.c \ radeon_span.c \ - radeon_texture.c + radeon_texture.c \ + radeon_tex_copy.c DRIVER_SOURCES = \ radeon_context.c \ @@ -40,6 +41,7 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_maos.c \ radeon_sanity.c \ + radeon_blit.c \ $(RADEON_COMMON_SOURCES) C_SOURCES = \ @@ -47,7 +49,7 @@ C_SOURCES = \ $(DRIVER_SOURCES) \ $(CS_SOURCES) -DRIVER_DEFINES = -DRADEON_R100 -Wall +DRIVER_DEFINES = -DRADEON_R100 DRI_LIB_DEPS += $(RADEON_LDFLAGS) diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c new file mode 100644 index 0000000000..0df4fbb33c --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, 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 (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 COPYRIGHT OWNER(S) 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 "radeon_common.h" +#include "radeon_context.h" +#include "radeon_blit.h" + +static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, + int reg, int count) +{ + if (count) + return CP_PACKET0(reg, count - 1); + return CP_PACKET2; +} + +/* common formats supported as both textures and render targets */ +static unsigned is_blit_supported(gl_format mesa_format) +{ + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_RGB565: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_A8: + break; + default: + return 0; + } + + /* ??? */ + if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) + return 0; + + return 1; +} + +static inline void emit_vtx_state(struct r100_context *r100) +{ + BATCH_LOCALS(&r100->radeon); + + BEGIN_BATCH(8); + if (r100->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, 0); + } else { + OUT_BATCH_REGVAL(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS); + + } + OUT_BATCH_REGVAL(RADEON_SE_COORD_FMT, (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_W0)); + OUT_BATCH_REGVAL(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0); + OUT_BATCH_REGVAL(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_ROUND | + RADEON_ROUND_PREC_4TH_PIX)); + END_BATCH(); +} + +static void inline emit_tx_setup(struct r100_context *r100, + gl_format mesa_format, + struct radeon_bo *bo, + intptr_t offset, + unsigned width, + unsigned height, + unsigned pitch) +{ + uint32_t txformat = RADEON_TXFORMAT_NON_POWER2; + BATCH_LOCALS(&r100->radeon); + + assert(width <= 2047); + assert(height <= 2047); + assert(offset % 32 == 0); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_XRGB8888: + txformat |= RADEON_TXFORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + txformat |= RADEON_TXFORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + txformat |= RADEON_TXFORMAT_ARGB4444 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_ARGB1555: + txformat |= RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + case MESA_FORMAT_A8: + txformat |= RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP; + break; + default: + break; + } + + BEGIN_BATCH(18); + OUT_BATCH_REGVAL(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); + OUT_BATCH_REGVAL(RADEON_PP_TXCBLEND_0, (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXABLEND_0, (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX)); + OUT_BATCH_REGVAL(RADEON_PP_TXFILTER_0, (RADEON_CLAMP_S_CLAMP_LAST | + RADEON_CLAMP_T_CLAMP_LAST | + RADEON_MAG_FILTER_NEAREST | + RADEON_MIN_FILTER_NEAREST)); + OUT_BATCH_REGVAL(RADEON_PP_TXFORMAT_0, txformat); + OUT_BATCH_REGVAL(RADEON_PP_TEX_SIZE_0, ((width - 1) | + ((height - 1) << RADEON_TEX_VSIZE_SHIFT))); + OUT_BATCH_REGVAL(RADEON_PP_TEX_PITCH_0, pitch * _mesa_get_format_bytes(mesa_format) - 32); + + OUT_BATCH_REGSEQ(RADEON_PP_TXOFFSET_0, 1); + OUT_BATCH_RELOC(0, bo, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0); + + END_BATCH(); +} + +static inline void emit_cb_setup(struct r100_context *r100, + struct radeon_bo *bo, + intptr_t offset, + gl_format mesa_format, + unsigned pitch, + unsigned width, + unsigned height) +{ + uint32_t dst_pitch = pitch; + uint32_t dst_format = 0; + BATCH_LOCALS(&r100->radeon); + + /* XXX others? BE/LE? */ + switch (mesa_format) { + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_XRGB8888: + dst_format = RADEON_COLOR_FORMAT_ARGB8888; + break; + case MESA_FORMAT_RGB565: + dst_format = RADEON_COLOR_FORMAT_RGB565; + break; + case MESA_FORMAT_ARGB4444: + dst_format = RADEON_COLOR_FORMAT_ARGB4444; + break; + case MESA_FORMAT_ARGB1555: + dst_format = RADEON_COLOR_FORMAT_ARGB1555; + break; + case MESA_FORMAT_A8: + dst_format = RADEON_COLOR_FORMAT_RGB8; + break; + default: + break; + } + + BEGIN_BATCH_NO_AUTOSTATE(18); + OUT_BATCH_REGVAL(RADEON_RE_TOP_LEFT, 0); + OUT_BATCH_REGVAL(RADEON_RE_WIDTH_HEIGHT, ((width << RADEON_RE_WIDTH_SHIFT) | + (height << RADEON_RE_HEIGHT_SHIFT))); + OUT_BATCH_REGVAL(RADEON_RB3D_PLANEMASK, 0xffffffff); + OUT_BATCH_REGVAL(RADEON_RB3D_BLENDCNTL, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO); + OUT_BATCH_REGVAL(RADEON_RB3D_CNTL, dst_format); + + OUT_BATCH_REGSEQ(RADEON_RB3D_COLOROFFSET, 1); + OUT_BATCH_RELOC(0, bo, 0, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + OUT_BATCH_REGSEQ(RADEON_RB3D_COLORPITCH, 1); + OUT_BATCH_RELOC(dst_pitch, bo, dst_pitch, 0, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); +} + +static GLboolean validate_buffers(struct r100_context *r100, + struct radeon_bo *src_bo, + struct radeon_bo *dst_bo) +{ + int ret; + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + src_bo, RADEON_GEM_DOMAIN_VRAM, 0); + + radeon_cs_space_add_persistent_bo(r100->radeon.cmdbuf.cs, + dst_bo, 0, RADEON_GEM_DOMAIN_VRAM); + + ret = radeon_cs_space_check_with_bo(r100->radeon.cmdbuf.cs, + first_elem(&r100->radeon.dma.reserved)->bo, + RADEON_GEM_DOMAIN_GTT, 0); + if (ret) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Calculate texcoords for given image region. + * Output values are [minx, maxx, miny, maxy] + */ +static inline void calc_tex_coords(float img_width, float img_height, + float x, float y, + float reg_width, float reg_height, + unsigned flip_y, float *buf) +{ + buf[0] = x / img_width; + buf[1] = buf[0] + reg_width / img_width; + buf[2] = y / img_height; + buf[3] = buf[2] + reg_height / img_height; + if (flip_y) + { + buf[2] = 1.0 - buf[2]; + buf[3] = 1.0 - buf[3]; + } +} + +static inline void emit_draw_packet(struct r100_context *r100, + unsigned src_width, unsigned src_height, + unsigned src_x_offset, unsigned src_y_offset, + unsigned dst_x_offset, unsigned dst_y_offset, + unsigned reg_width, unsigned reg_height, + unsigned flip_y) +{ + float texcoords[4]; + float verts[12]; + BATCH_LOCALS(&r100->radeon); + + calc_tex_coords(src_width, src_height, + src_x_offset, src_y_offset, + reg_width, reg_height, + flip_y, texcoords); + + verts[0] = dst_x_offset; + verts[1] = dst_y_offset + reg_height; + verts[2] = texcoords[0]; + verts[3] = texcoords[3]; + + verts[4] = dst_x_offset + reg_width; + verts[5] = dst_y_offset + reg_height; + verts[6] = texcoords[1]; + verts[7] = texcoords[3]; + + verts[8] = dst_x_offset + reg_width; + verts[9] = dst_y_offset; + verts[10] = texcoords[1]; + verts[11] = texcoords[2]; + + BEGIN_BATCH(15); + OUT_BATCH(RADEON_CP_PACKET3_3D_DRAW_IMMD | (13 << 16)); + OUT_BATCH(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0); + OUT_BATCH(RADEON_CP_VC_CNTL_PRIM_WALK_RING | + RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST | + RADEON_CP_VC_CNTL_MAOS_ENABLE | + RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | + (3 << 16)); + OUT_BATCH_TABLE(verts, 12); + END_BATCH(); +} + +/** + * Copy a region of [@a width x @a height] pixels from source buffer + * to destination buffer. + * @param[in] r100 r100 context + * @param[in] src_bo source radeon buffer object + * @param[in] src_offset offset of the source image in the @a src_bo + * @param[in] src_mesaformat source image format + * @param[in] src_pitch aligned source image width + * @param[in] src_width source image width + * @param[in] src_height source image height + * @param[in] src_x_offset x offset in the source image + * @param[in] src_y_offset y offset in the source image + * @param[in] dst_bo destination radeon buffer object + * @param[in] dst_offset offset of the destination image in the @a dst_bo + * @param[in] dst_mesaformat destination image format + * @param[in] dst_pitch aligned destination image width + * @param[in] dst_width destination image width + * @param[in] dst_height destination image height + * @param[in] dst_x_offset x offset in the destination image + * @param[in] dst_y_offset y offset in the destination image + * @param[in] width region width + * @param[in] height region height + * @param[in] flip_y set if y coords of the source image need to be flipped + */ +unsigned r100_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y) +{ + struct r100_context *r100 = R100_CONTEXT(ctx); + + if (!is_blit_supported(dst_mesaformat)) + return GL_FALSE; + + /* Make sure that colorbuffer has even width - hw limitation */ + if (dst_pitch % 2 > 0) + ++dst_pitch; + + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return GL_FALSE; + + /* Need to clamp the region size to make sure + * we don't read outside of the source buffer + * or write outside of the destination buffer. + */ + if (reg_width + src_x_offset > src_width) + reg_width = src_width - src_x_offset; + if (reg_height + src_y_offset > src_height) + reg_height = src_height - src_y_offset; + if (reg_width + dst_x_offset > dst_width) + reg_width = dst_width - dst_x_offset; + if (reg_height + dst_y_offset > dst_height) + reg_height = dst_height - dst_y_offset; + + if (src_bo == dst_bo) { + return GL_FALSE; + } + + if (src_offset % 32 || dst_offset % 32) { + return GL_FALSE; + } + + if (0) { + fprintf(stderr, "src: size [%d x %d], pitch %d, " + "offset [%d x %d], format %s, bo %p\n", + src_width, src_height, src_pitch, + src_x_offset, src_y_offset, + _mesa_get_format_name(src_mesaformat), + src_bo); + fprintf(stderr, "dst: pitch %d, offset[%d x %d], format %s, bo %p\n", + dst_pitch, dst_x_offset, dst_y_offset, + _mesa_get_format_name(dst_mesaformat), dst_bo); + fprintf(stderr, "region: %d x %d\n", reg_width, reg_height); + } + + /* Flush is needed to make sure that source buffer has correct data */ + radeonFlush(ctx); + + rcommonEnsureCmdBufSpace(&r100->radeon, 59, __FUNCTION__); + + if (!validate_buffers(r100, src_bo, dst_bo)) + return GL_FALSE; + + /* 8 */ + emit_vtx_state(r100); + /* 18 */ + emit_tx_setup(r100, src_mesaformat, src_bo, src_offset, src_width, src_height, src_pitch); + /* 18 */ + emit_cb_setup(r100, dst_bo, dst_offset, dst_mesaformat, dst_pitch, dst_width, dst_height); + /* 15 */ + emit_draw_packet(r100, src_width, src_height, + src_x_offset, src_y_offset, + dst_x_offset, dst_y_offset, + reg_width, reg_height, + flip_y); + + radeonFlush(ctx); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h new file mode 100644 index 0000000000..d36366ff79 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_blit.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Advanced Micro Devices, 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 (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 COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef RADEON_BLIT_H +#define RADEON_BLIT_H + +void r100_blit_init(struct r100_context *r100); + +unsigned r100_blit(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned width, + unsigned height, + unsigned flip_y); + +#endif // RADEON_BLIT_H diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index e0b853bc97..79f3ff7da6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -1036,10 +1036,11 @@ static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state OUT_BATCH_TABLE(atom->cmd, dwords); END_BATCH(); } + atom->dirty = GL_FALSE; + } else { radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name); } - atom->dirty = GL_FALSE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index b9c29b937e..94f476617b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -39,7 +39,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" #include "drivers/common/meta.h" #include "main/context.h" -#include "main/framebuffer.h" #include "main/renderbuffer.h" #include "main/state.h" #include "main/simple_list.h" @@ -47,10 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#if defined(RADEON_R600) -#include "r600_context.h" -#endif - #define DRIVER_DATE "20090101" #ifndef RADEON_DEBUG diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index ab79d2dc0f..e397ee8c22 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -518,6 +518,26 @@ struct radeon_context { void (*free_context)(GLcontext *ctx); void (*emit_query_finish)(radeonContextPtr radeon); void (*update_scissor)(GLcontext *ctx); + unsigned (*blit)(GLcontext *ctx, + struct radeon_bo *src_bo, + intptr_t src_offset, + gl_format src_mesaformat, + unsigned src_pitch, + unsigned src_width, + unsigned src_height, + unsigned src_x_offset, + unsigned src_y_offset, + struct radeon_bo *dst_bo, + intptr_t dst_offset, + gl_format dst_mesaformat, + unsigned dst_pitch, + unsigned dst_width, + unsigned dst_height, + unsigned dst_x_offset, + unsigned dst_y_offset, + unsigned reg_width, + unsigned reg_height, + unsigned flip_y); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 3cd305b0a2..475e93bc05 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -39,10 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/context.h" #include "main/simple_list.h" #include "main/imports.h" -#include "main/matrix.h" #include "main/extensions.h" -#include "main/framebuffer.h" -#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -61,8 +58,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_tcl.h" -#include "radeon_maos.h" #include "radeon_queryobj.h" +#include "radeon_blit.h" #define need_GL_ARB_occlusion_query #define need_GL_EXT_blend_minmax @@ -73,7 +70,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRIVER_DATE "20061018" -#include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -202,6 +198,7 @@ static void r100_init_vtbl(radeonContextPtr radeon) radeon->vtbl.fallback = radeonFallback; radeon->vtbl.free_context = r100_vtbl_free_context; radeon->vtbl.emit_query_finish = r100_emit_query_finish; + radeon->vtbl.blit = r100_blit; } /* Create the device specific context. @@ -228,6 +225,7 @@ r100CreateContext( const __GLcontextModes *glVisual, if ( !rmesa ) return GL_FALSE; + rmesa->radeon.radeonScreen = screen; r100_init_vtbl(&rmesa->radeon); /* init exp fog table data */ @@ -257,7 +255,7 @@ r100CreateContext( const __GLcontextModes *glVisual, * (the texture functions are especially important) */ _mesa_init_driver_functions( &functions ); - radeonInitTextureFuncs( &functions ); + radeonInitTextureFuncs( &rmesa->radeon, &functions ); radeonInitQueryObjFunctions(&functions); if (!radeonInitContext(&rmesa->radeon, &functions, @@ -281,6 +279,7 @@ r100CreateContext( const __GLcontextModes *glVisual, "texture_units"); ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits; i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures"); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index dfedc38bfd..d84760bf74 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -453,7 +453,6 @@ struct r100_context { extern GLboolean r100CreateContext( const __GLcontextModes *glVisual, __DRIcontext *driContextPriv, void *sharedContextPrivate); - #endif /* __RADEON_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index bf46eb8aab..cc951a12cb 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -180,7 +180,6 @@ static int cs_begin(struct radeon_cs_int *cs, if (cs->cdw + ndw > cs->ndw) { uint32_t tmp, *ptr; - int num = (ndw > 0x3FF) ? ndw : 0x3FF; tmp = (cs->cdw + ndw + 0x3ff) & (~0x3ff); ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h index 26da31c1c4..ef8b9671ac 100644 --- a/src/mesa/drivers/dri/radeon/radeon_debug.h +++ b/src/mesa/drivers/dri/radeon/radeon_debug.h @@ -47,7 +47,11 @@ typedef enum radeon_debug_levels { * errors. */ #ifndef RADEON_DEBUG_LEVEL -#define RADEON_DEBUG_LEVEL RADEON_VERBOSE +# ifdef DEBUG +# define RADEON_DEBUG_LEVEL RADEON_TRACE +# else +# define RADEON_DEBUG_LEVEL RADEON_VERBOSE +# endif #endif typedef enum radeon_debug_types { diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 7b1f84a715..e780b9eef1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -531,10 +531,9 @@ radeon_render_texture(GLcontext * ctx, att->TextureLevel); if (att->Texture->Target == GL_TEXTURE_3D) { - GLuint offsets[6]; - radeon_miptree_depth_offsets(radeon_image->mt, att->TextureLevel, - offsets); - imageOffset += offsets[att->Zoffset]; + imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride * + radeon_image->mt->levels[att->TextureLevel].height * + att->Zoffset; } /* store that offset in the region, along with the correct pitch for diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index a9d50c5d07..c7ea452156 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -38,18 +38,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <errno.h> #include "main/attrib.h" -#include "main/enable.h" -#include "main/blend.h" #include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/depth.h" -#include "main/shaders.h" -#include "main/texstate.h" -#include "main/varray.h" -#include "glapi/dispatch.h" #include "swrast/swrast.h" -#include "main/stencil.h" -#include "main/matrix.h" #include "main/glheader.h" #include "main/imports.h" @@ -58,15 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_common.h" -#include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_tcl.h" -#include "radeon_sanity.h" #define STANDALONE_MMIO -#include "radeon_macros.h" /* for INREG() */ -#include "drirenderbuffer.h" #include "vblank.h" #define RADEON_TIMEOUT 512 @@ -107,6 +92,8 @@ void radeonSetUpAtomList( r100ContextPtr rmesa ) insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]); for (i = 0; i < 6; ++i) insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]); + if (rmesa->radeon.radeonScreen->kernel_mm) + insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.stp); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd); insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog); diff --git a/src/mesa/drivers/dri/radeon/radeon_lighting.c b/src/mesa/drivers/dri/radeon/radeon_lighting.c deleted file mode 100644 index ba444f2b10..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_lighting.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. - * - * 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 - * VA LINUX SYSTEMS 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. - * - * Authors: - * Gareth Hughes <gareth@valinux.com> - * Keith Whitwell <keith@tungstengraphics.com> - */ - -#include "main/glheader.h" -#include "main/imports.h" -#include "api_arrayelt.h" -/* #include "mmath.h" */ -#include "main/enums.h" -#include "colormac.h" - - -#include "radeon_context.h" -#include "radeon_ioctl.h" -#include "radeon_state.h" -#include "radeon_tcl.h" -#include "radeon_tex.h" -#include "radeon_vtxfmt.h" - - - -/* ============================================================= - * Materials - */ - - -/* Update on colormaterial, material emmissive/ambient, - * lightmodel.globalambient - */ -void update_global_ambient( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - float *fcmd = (float *)RADEON_DB_STATE( glt ); - - /* Need to do more if both emmissive & ambient are PREMULT: - */ - if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] & - ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | - (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) - { - COPY_3V( &fcmd[GLT_RED], - ctx->Light.Material[0].Emission); - ACC_SCALE_3V( &fcmd[GLT_RED], - ctx->Light.Model.Ambient, - ctx->Light.Material[0].Ambient); - } - else - { - COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); - } - - RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt); -} - -/* Update on change to - * - light[p].colors - * - light[p].enabled - * - material, - * - colormaterial enabled - * - colormaterial bitmask - */ -void update_light_colors( GLcontext *ctx, GLuint p ) -{ - struct gl_light *l = &ctx->Light.Light[p]; - -/* fprintf(stderr, "%s\n", __FUNCTION__); */ - - if (l->Enabled) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); - GLuint bitmask = ctx->Light.ColorMaterialBitmask; - struct gl_material *mat = &ctx->Light.Material[0]; - - COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); - COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); - COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); - - if (!ctx->Light.ColorMaterialEnabled) - bitmask = 0; - - if ((bitmask & FRONT_AMBIENT_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient ); - - if ((bitmask & FRONT_DIFFUSE_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse ); - - if ((bitmask & FRONT_SPECULAR_BIT) == 0) - SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular ); - - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); - } -} - -/* Also fallback for asym colormaterial mode in twoside lighting... - */ -void check_twoside_fallback( GLcontext *ctx ) -{ - GLboolean fallback = GL_FALSE; - - if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { - if (memcmp( &ctx->Light.Material[0], - &ctx->Light.Material[1], - sizeof(struct gl_material)) != 0) - fallback = GL_TRUE; - else if (ctx->Light.ColorMaterialEnabled && - (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != - ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) - fallback = GL_TRUE; - } - - TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); -} - -void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) -{ - if (ctx->Light.ColorMaterialEnabled) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; - GLuint mask = ctx->Light.ColorMaterialBitmask; - - /* Default to PREMULT: - */ - light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | - (3 << RADEON_AMBIENT_SOURCE_SHIFT) | - (3 << RADEON_DIFFUSE_SOURCE_SHIFT) | - (3 << RADEON_SPECULAR_SOURCE_SHIFT)); - - if (mask & FRONT_EMISSION_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_EMISSIVE_SOURCE_SHIFT); - } - - if (mask & FRONT_AMBIENT_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_AMBIENT_SOURCE_SHIFT); - } - - if (mask & FRONT_DIFFUSE_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_DIFFUSE_SOURCE_SHIFT); - } - - if (mask & FRONT_SPECULAR_BIT) { - light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << - RADEON_SPECULAR_SOURCE_SHIFT); - } - - if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) { - GLuint p; - - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl; - - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); - update_global_ambient( ctx ); - } - } - - check_twoside_fallback( ctx ); -} - -void radeonUpdateMaterial( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl ); - GLuint p; - GLuint mask = ~0; - - if (ctx->Light.ColorMaterialEnabled) - mask &= ~ctx->Light.ColorMaterialBitmask; - - if (RADEON_DEBUG & RADEON_STATE) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (mask & FRONT_EMISSION_BIT) { - fcmd[MTL_EMMISSIVE_RED] = ctx->Light.Material[0].Emission[0]; - fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1]; - fcmd[MTL_EMMISSIVE_BLUE] = ctx->Light.Material[0].Emission[2]; - fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3]; - } - if (mask & FRONT_AMBIENT_BIT) { - fcmd[MTL_AMBIENT_RED] = ctx->Light.Material[0].Ambient[0]; - fcmd[MTL_AMBIENT_GREEN] = ctx->Light.Material[0].Ambient[1]; - fcmd[MTL_AMBIENT_BLUE] = ctx->Light.Material[0].Ambient[2]; - fcmd[MTL_AMBIENT_ALPHA] = ctx->Light.Material[0].Ambient[3]; - } - if (mask & FRONT_DIFFUSE_BIT) { - fcmd[MTL_DIFFUSE_RED] = ctx->Light.Material[0].Diffuse[0]; - fcmd[MTL_DIFFUSE_GREEN] = ctx->Light.Material[0].Diffuse[1]; - fcmd[MTL_DIFFUSE_BLUE] = ctx->Light.Material[0].Diffuse[2]; - fcmd[MTL_DIFFUSE_ALPHA] = ctx->Light.Material[0].Diffuse[3]; - } - if (mask & FRONT_SPECULAR_BIT) { - fcmd[MTL_SPECULAR_RED] = ctx->Light.Material[0].Specular[0]; - fcmd[MTL_SPECULAR_GREEN] = ctx->Light.Material[0].Specular[1]; - fcmd[MTL_SPECULAR_BLUE] = ctx->Light.Material[0].Specular[2]; - fcmd[MTL_SPECULAR_ALPHA] = ctx->Light.Material[0].Specular[3]; - } - if (mask & FRONT_SHININESS_BIT) { - fcmd[MTL_SHININESS] = ctx->Light.Material[0].Shininess; - } - - if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) { - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); - - check_twoside_fallback( ctx ); - update_global_ambient( ctx ); - } - else if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_STATE)) - fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__); -} - -/* _NEW_LIGHT - * _NEW_MODELVIEW - * _MESA_NEW_NEED_EYE_COORDS - * - * Uses derived state from mesa: - * _VP_inf_norm - * _h_inf_norm - * _Position - * _NormSpotDirection - * _ModelViewInvScale - * _NeedEyeCoords - * _EyeZDir - * - * which are calculated in light.c and are correct for the current - * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW - * and _MESA_NEW_NEED_EYE_COORDS. - */ -void radeonUpdateLighting( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - /* Have to check these, or have an automatic shortcircuit mechanism - * to remove noop statechanges. (Or just do a better job on the - * front end). - */ - { - GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; - - if (ctx->_NeedEyeCoords) - tmp &= ~RADEON_LIGHT_IN_MODELSPACE; - else - tmp |= RADEON_LIGHT_IN_MODELSPACE; - - - /* Leave this test disabled: (unexplained q3 lockup) (even with - new packets) - */ - if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) - { - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp; - } - } - - { - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye ); - fcmd[EYE_X] = ctx->_EyeZDir[0]; - fcmd[EYE_Y] = ctx->_EyeZDir[1]; - fcmd[EYE_Z] = - ctx->_EyeZDir[2]; - fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale; - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye ); - } - - -/* RADEON_STATECHANGE( rmesa, glt ); */ - - if (ctx->Light.Enabled) { - GLint p; - for (p = 0 ; p < MAX_LIGHTS; p++) { - if (ctx->Light.Light[p].Enabled) { - struct gl_light *l = &ctx->Light.Light[p]; - GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] ); - - if (l->EyePosition[3] == 0.0) { - COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); - COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); - fcmd[LIT_POSITION_W] = 0; - fcmd[LIT_DIRECTION_W] = 0; - } else { - COPY_4V( &fcmd[LIT_POSITION_X], l->_Position ); - fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0]; - fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1]; - fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2]; - fcmd[LIT_DIRECTION_W] = 0; - } - - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); - } - } - } -} - - -void radeonLightfv( GLcontext *ctx, GLenum light, - GLenum pname, const GLfloat *params ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLint p = light - GL_LIGHT0; - struct gl_light *l = &ctx->Light.Light[p]; - GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd; - - - switch (pname) { - case GL_AMBIENT: - case GL_DIFFUSE: - case GL_SPECULAR: - update_light_colors( ctx, p ); - break; - - case GL_SPOT_DIRECTION: - /* picked up in update_light */ - break; - - case GL_POSITION: { - /* positions picked up in update_light, but can do flag here */ - GLuint flag = (p&1)? RADEON_LIGHT_1_IS_LOCAL : RADEON_LIGHT_0_IS_LOCAL; - GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; - - RADEON_STATECHANGE(rmesa, tcl); - if (l->EyePosition[3] != 0.0F) - rmesa->hw.tcl.cmd[idx] |= flag; - else - rmesa->hw.tcl.cmd[idx] &= ~flag; - break; - } - - case GL_SPOT_EXPONENT: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_SPOT_EXPONENT] = params[0]; - break; - - case GL_SPOT_CUTOFF: { - GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT; - GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; - - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff; - - RADEON_STATECHANGE(rmesa, tcl); - if (l->SpotCutoff != 180.0F) - rmesa->hw.tcl.cmd[idx] |= flag; - else - rmesa->hw.tcl.cmd[idx] &= ~flag; - break; - } - - case GL_CONSTANT_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_CONST] = params[0]; - break; - case GL_LINEAR_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_LINEAR] = params[0]; - break; - case GL_QUADRATIC_ATTENUATION: - RADEON_STATECHANGE(rmesa, lit[p]); - fcmd[LIT_ATTEN_QUADRATIC] = params[0]; - break; - default: - return; - } - -} - - - - -void radeonLightModelfv( GLcontext *ctx, GLenum pname, - const GLfloat *param ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - switch (pname) { - case GL_LIGHT_MODEL_AMBIENT: - update_global_ambient( ctx ); - break; - - case GL_LIGHT_MODEL_LOCAL_VIEWER: - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.LocalViewer) - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER; - else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER; - break; - - case GL_LIGHT_MODEL_TWO_SIDE: - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.TwoSide) - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE; - else - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE; - - check_twoside_fallback( ctx ); - -#if _HAVE_SWTNL - if (rmesa->TclFallback) { - radeonChooseRenderState( ctx ); - radeonChooseVertexState( ctx ); - } -#endif - break; - - case GL_LIGHT_MODEL_COLOR_CONTROL: - radeonUpdateSpecular(ctx); - - RADEON_STATECHANGE( rmesa, tcl ); - if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= - ~RADEON_DIFFUSE_SPECULAR_COMBINE; - else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= - RADEON_DIFFUSE_SPECULAR_COMBINE; - break; - - default: - break; - } -} - - -/* ============================================================= - * Fog - */ - - -static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - union { int i; float f; } c, d; - GLchan col[4]; - - c.i = rmesa->hw.fog.cmd[FOG_C]; - d.i = rmesa->hw.fog.cmd[FOG_D]; - - switch (pname) { - case GL_FOG_MODE: - if (!ctx->Fog.Enabled) - return; - RADEON_STATECHANGE(rmesa, tcl); - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK; - switch (ctx->Fog.Mode) { - case GL_LINEAR: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR; - if (ctx->Fog.Start == ctx->Fog.End) { - c.f = 1.0F; - d.f = 1.0F; - } - else { - c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); - d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); - } - break; - case GL_EXP: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP; - c.f = 0.0; - d.f = ctx->Fog.Density; - break; - case GL_EXP2: - rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2; - c.f = 0.0; - d.f = -(ctx->Fog.Density * ctx->Fog.Density); - break; - default: - return; - } - break; - case GL_FOG_DENSITY: - switch (ctx->Fog.Mode) { - case GL_EXP: - c.f = 0.0; - d.f = ctx->Fog.Density; - break; - case GL_EXP2: - c.f = 0.0; - d.f = -(ctx->Fog.Density * ctx->Fog.Density); - break; - default: - break; - } - break; - case GL_FOG_START: - case GL_FOG_END: - if (ctx->Fog.Mode == GL_LINEAR) { - if (ctx->Fog.Start == ctx->Fog.End) { - c.f = 1.0F; - d.f = 1.0F; - } else { - c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start); - d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start); - } - } - break; - case GL_FOG_COLOR: - RADEON_STATECHANGE( rmesa, ctx ); - UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color ); - rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = - radeonPackColor( 4, col[0], col[1], col[2], 0 ); - break; - case GL_FOG_COORDINATE_SOURCE_EXT: - /* What to do? - */ - break; - default: - return; - } - - if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) { - RADEON_STATECHANGE( rmesa, fog ); - rmesa->hw.fog.cmd[FOG_C] = c.i; - rmesa->hw.fog.cmd[FOG_D] = d.i; - } -} - -/* Examine lighting and texture state to determine if separate specular - * should be enabled. - */ -void radeonUpdateSpecular( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; - - if (NEED_SECONDARY_COLOR(ctx)) { - p |= RADEON_SPECULAR_ENABLE; - } else { - p &= ~RADEON_SPECULAR_ENABLE; - } - - if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; - } - - /* Bizzare: have to leave lighting enabled to get fog. - */ - RADEON_STATECHANGE( rmesa, tcl ); - if ((ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } - else if (ctx->Fog.Enabled) { - if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } - } - else if (ctx->Light.Enabled) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; - } else if (ctx->Fog.ColorSumEnabled ) { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; - } else { - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; - } - -#if _HAVE_SWTNL - /* Update vertex/render formats - */ - if (rmesa->TclFallback) { - radeonChooseRenderState( ctx ); - radeonChooseVertexState( ctx ); - } -#endif -} - - - -static void radeonLightingSpaceChange( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLboolean tmp; - RADEON_STATECHANGE( rmesa, tcl ); - - if (RADEON_DEBUG & RADEON_STATE) - fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords); - - if (ctx->_NeedEyeCoords) - tmp = ctx->Transform.RescaleNormals; - else - tmp = !ctx->Transform.RescaleNormals; - - if ( tmp ) { - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_RESCALE_NORMALS; - } else { - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS; - } -} - -void radeonInitLightStateFuncs( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - ctx->Driver.LightModelfv = radeonLightModelfv; - ctx->Driver.Lightfv = radeonLightfv; - ctx->Driver.Fogfv = radeonFogfv; - ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange; - - for (i = 0 ; i < 8; i++) { - struct gl_light *l = &ctx->Light.Light[i]; - GLenum p = GL_LIGHT0 + i; - *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; - - ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); - ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); - ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); - ctx->Driver.Lightfv( ctx, p, GL_POSITION, 0 ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, 0 ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); - ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); - ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, - &l->ConstantAttenuation ); - ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION, - &l->LinearAttenuation ); - ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION, - &l->QuadraticAttenuation ); - } - - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT, - ctx->Light.Model.Ambient ); - - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, 0 ); -} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 9dee691938..7b6bd36dcf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_screen.h" #include "radeon_common.h" #include "radeon_lock.h" -#include "drirenderbuffer.h" /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 033f26db2a..cd843d965e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -32,9 +32,9 @@ #include <unistd.h> #include "main/simple_list.h" -#include "main/texcompress.h" #include "main/teximage.h" #include "main/texobj.h" +#include "main/enums.h" #include "radeon_texture.h" static unsigned get_aligned_compressed_row_stride( @@ -42,18 +42,31 @@ static unsigned get_aligned_compressed_row_stride( unsigned width, unsigned minStride) { - const unsigned blockSize = _mesa_get_format_bytes(format); - unsigned blockWidth, blockHeight, numXBlocks; + const unsigned blockBytes = _mesa_get_format_bytes(format); + unsigned blockWidth, blockHeight; + unsigned stride; _mesa_get_format_block_size(format, &blockWidth, &blockHeight); - numXBlocks = (width + blockWidth - 1) / blockWidth; - - while (numXBlocks * blockSize < minStride) - { - ++numXBlocks; - } - return numXBlocks * blockSize; + /* Count number of blocks required to store the given width. + * And then multiple it with bytes required to store a block. + */ + stride = (width + blockWidth - 1) / blockWidth * blockBytes; + + /* Round the given minimum stride to the next full blocksize. + * (minStride + blockBytes - 1) / blockBytes * blockBytes + */ + if ( stride < minStride ) + stride = (minStride + blockBytes - 1) / blockBytes * blockBytes; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s width %u, minStride %u, block(bytes %u, width %u):" + "stride %u\n", + __func__, width, minStride, + blockBytes, blockWidth, + stride); + + return stride; } static unsigned get_compressed_image_size( @@ -68,19 +81,6 @@ static unsigned get_compressed_image_size( return rowStride * ((height + blockHeight - 1) / blockHeight); } -static int find_next_power_of_two(GLuint value) -{ - int i, tmp; - - i = 0; - tmp = value - 1; - while (tmp) { - tmp >>= 1; - i++; - } - return (1 << i); -} - /** * Compute sizes and fill in offset and blit information for the given * image (determined by \p face and \p level). @@ -95,7 +95,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree uint32_t row_align; GLuint height; - height = find_next_power_of_two(lvl->height); + height = _mesa_next_pow_two_32(lvl->height); /* Find image size in bytes */ if (_mesa_is_format_compressed(mt->mesaFormat)) { @@ -123,10 +123,11 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree lvl->faces[face].offset = *curOffset; *curOffset += lvl->size; - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, - "level %d, face %d: rs:%d %dx%d at %d\n", - level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) level %d, face %d: rs:%d %dx%d at %d\n", + __func__, rmesa, + level, face, + lvl->rowstride, lvl->width, height, lvl->faces[face].offset); } static GLuint minify(GLuint size, GLuint levels) @@ -158,6 +159,10 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_ /* Note the required size in memory */ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, %p) total size %d\n", + __func__, rmesa, mt, mt->totalsize); } static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt) @@ -177,10 +182,20 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_ for(face = 0; face < mt->faces; face++) compute_tex_image_offset(rmesa, mt, face, level, &curOffset); + /* r600 cube levels seems to be aligned to 8 faces but + * we have separate register for 1'st level offset so add + * 2 image alignment after 1'st mip level */ + if(rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R600 && + mt->target == GL_TEXTURE_CUBE_MAP && level >= 1) + curOffset += 2 * mt->levels[level].size; } /* Note the required size in memory */ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, %p) total size %d\n", + __func__, rmesa, mt, mt->totalsize); } /** @@ -192,6 +207,10 @@ static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, { radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p) new tree is %p.\n", + __func__, rmesa, mt); + mt->mesaFormat = mesaFormat; mt->refcount = 1; mt->target = target; @@ -282,6 +301,12 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj, return; } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p) target %s, min %d, max %d.\n", + __func__, tObj, + _mesa_lookup_enum_by_nr(tObj->Target), + minLod, maxLod); + /* save these values */ *pminLod = minLod; *pmaxLod = maxLod; @@ -328,7 +353,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g firstImage = texObj->Image[0][texObj->BaseLevel]; numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); - if (RADEON_DEBUG & RADEON_TEXTURE) { + if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target); fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat); @@ -369,8 +394,12 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) assert(!t->mt); - if (!texImg) + if (!texImg) { + radeon_warning("%s(%p) No image in given texture object(%p).\n", + __func__, rmesa, t); return; + } + numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1); @@ -380,25 +409,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) texImg->Depth, t->tile_bits); } -/* Although we use the image_offset[] array to store relative offsets - * to cube faces, Mesa doesn't know anything about this and expects - * each cube face to be treated as a separate image. - * - * These functions present that view to mesa: - */ -void -radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets) -{ - if (mt->target != GL_TEXTURE_3D || mt->faces == 1) { - offsets[0] = 0; - } else { - int i; - for (i = 0; i < 6; i++) { - offsets[i] = mt->levels[level].faces[i].offset; - } - } -} - GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level) @@ -425,6 +435,10 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, assert(dstlvl->height == image->base.Height); assert(dstlvl->depth == image->base.Depth); + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s miptree %p, image %p, face %d, level %d.\n", + __func__, mt, image, face, level); + radeon_bo_map(mt->bo, GL_TRUE); dest = mt->bo->ptr + dstlvl->faces[face].offset; @@ -456,6 +470,9 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, /* This condition should be removed, it's here to workaround * a segfault when mapping textures during software fallbacks. */ + radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, + "%s Trying to map texture in sowftware fallback.\n", + __func__); const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width); uint32_t rows = image->base.Height * image->base.Depth; @@ -562,9 +579,9 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod); - if (RADEON_DEBUG & RADEON_TEXTURE) - fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", - __FUNCTION__, texObj ,t->minLod, t->maxLod); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", + __FUNCTION__, texObj ,t->minLod, t->maxLod); radeon_mipmap_tree *dst_miptree; dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod); @@ -573,11 +590,13 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); dst_miptree = t->mt; - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt); - } - } else if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: No matching miptree found, allocated new one %p\n", + __FUNCTION__, t->mt); + + } else { + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: Using miptree %p\n", __FUNCTION__, t->mt); } const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1; @@ -588,22 +607,21 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t for (level = t->minLod; level <= t->maxLod; ++level) { img = get_radeon_texture_image(texObj->Image[face][level]); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt); - } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "Checking image level %d, face %d, mt %p ... ", + level, face, img->mt); if (img->mt != dst_miptree) { - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "MIGRATING\n"); - } + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "MIGRATING\n"); + struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo; if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) { radeon_firevertices(rmesa); } migrate_image_to_miptree(dst_miptree, img, face, level); - } else if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "OK\n"); - } + } else + radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n"); } } @@ -619,4 +637,4 @@ uint32_t get_base_teximage_offset(radeonTexObj *texObj) } else { return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod); } -}
\ No newline at end of file +} diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index a10649b5ae..c911688c1a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -88,7 +88,5 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); -void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets); - uint32_t get_base_teximage_offset(radeonTexObj *texObj); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c index 98117cdfc1..d0dcf0e431 100644 --- a/src/mesa/drivers/dri/radeon/radeon_queryobj.c +++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c @@ -65,7 +65,7 @@ static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q) } radeon_print(RADEON_STATE, RADEON_TRACE, - "%d start: %lx, end: %lx %ld\n", i, start, end, end - start); + "%d start: %llx, end: %llx %lld\n", i, start, end, end - start); } } else { for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) { diff --git a/src/mesa/drivers/dri/radeon/radeon_sanity.c b/src/mesa/drivers/dri/radeon/radeon_sanity.c index 1ab570f507..3e64be83ed 100644 --- a/src/mesa/drivers/dri/radeon/radeon_sanity.c +++ b/src/mesa/drivers/dri/radeon/radeon_sanity.c @@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/glheader.h" #include "radeon_context.h" -#include "radeon_ioctl.h" #include "radeon_sanity.h" /* Set this '1' to get more verbiage. diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 3080a0fcd0..93b6399a66 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -47,7 +47,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_macros.h" #include "radeon_screen.h" #include "radeon_common.h" -#include "radeon_span.h" #if defined(RADEON_R100) #include "radeon_context.h" #include "radeon_tex.h" @@ -66,7 +65,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "vblank.h" -#include "drirenderbuffer.h" #include "radeon_bocs_wrapper.h" @@ -1481,7 +1479,7 @@ radeonCreateBuffer( __DRIscreen *driScrnPriv, if (!rfb) return GL_FALSE; - _mesa_initialize_framebuffer(&rfb->base, mesaVis); + _mesa_initialize_window_framebuffer(&rfb->base, mesaVis); if (mesaVis->redBits == 5) rgbFormat = _mesa_little_endian() ? MESA_FORMAT_RGB565 : MESA_FORMAT_RGB565_REV; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 1c9ec36dae..7db745a180 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -37,7 +37,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/api_arrayelt.h" #include "main/enums.h" #include "main/light.h" -#include "main/state.h" #include "main/context.h" #include "main/framebuffer.h" #include "main/simple_list.h" @@ -54,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "drirenderbuffer.h" static void radeonUpdateSpecular( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index dd82888254..91718a4777 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -33,7 +33,6 @@ #include "swrast/swrast.h" #include "vbo/vbo.h" -#include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -41,9 +40,6 @@ #include "radeon_mipmap_tree.h" #include "radeon_ioctl.h" #include "radeon_state.h" -#include "radeon_tcl.h" -#include "radeon_tex.h" -#include "radeon_swtcl.h" #include "radeon_queryobj.h" #include "../r200/r200_reg.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index 8bf1bfbc57..5a71b510fa 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -41,7 +41,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/simple_list.h" #include "swrast_setup/swrast_setup.h" -#include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index cd02bfbcf5..ea796e1a45 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_tex.h" #include "radeon_tcl.h" #include "radeon_swtcl.h" #include "radeon_maos.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index 14163f13af..c66e5d17b1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -44,9 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #include "radeon_mipmap_tree.h" -#include "radeon_state.h" #include "radeon_ioctl.h" -#include "radeon_swtcl.h" #include "radeon_tex.h" #include "xmlpool.h" @@ -434,7 +432,7 @@ radeonNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) -void radeonInitTextureFuncs( struct dd_function_table *functions ) +void radeonInitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ) { functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; functions->TexImage1D = radeonTexImage1D; @@ -455,6 +453,11 @@ void radeonInitTextureFuncs( struct dd_function_table *functions ) functions->CompressedTexImage2D = radeonCompressedTexImage2D; functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; + if (radeon->radeonScreen->kernel_mm) { + functions->CopyTexImage2D = radeonCopyTexImage2D; + functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; + } + functions->GenerateMipmap = radeonGenerateMipmap; functions->NewTextureImage = radeonNewTextureImage; diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.h b/src/mesa/drivers/dri/radeon/radeon_tex.h index a4aaddc74f..0113ffd3da 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.h +++ b/src/mesa/drivers/dri/radeon/radeon_tex.h @@ -52,6 +52,6 @@ extern int radeonUploadTexImages( r100ContextPtr rmesa, radeonTexObjPtr t, extern void radeonDestroyTexObj( r100ContextPtr rmesa, radeonTexObjPtr t ); -extern void radeonInitTextureFuncs( struct dd_function_table *functions ); +extern void radeonInitTextureFuncs( radeonContextPtr radeon, struct dd_function_table *functions ); #endif /* __RADEON_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r300/r300_texcopy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index ebc9c05b8a..d6aeb7049f 100644 --- a/src/mesa/drivers/dri/r300/r300_texcopy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -26,7 +26,7 @@ */ #include "radeon_common.h" -#include "r300_context.h" +#include "radeon_texture.h" #include "main/image.h" #include "main/teximage.h" @@ -34,11 +34,7 @@ #include "drivers/common/meta.h" #include "radeon_mipmap_tree.h" -#include "r300_blit.h" -#include <main/debug.h> -// TODO: -// need to pass correct pitch for small dst textures! static GLboolean do_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, @@ -48,13 +44,13 @@ do_copy_texsubimage(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) { - struct r300_context *r300 = R300_CONTEXT(ctx); + radeonContextPtr radeon = RADEON_CONTEXT(ctx); struct radeon_renderbuffer *rrb; if (_mesa_get_format_bits(timg->base.TexFormat, GL_DEPTH_BITS) > 0) { - rrb = radeon_get_depthbuffer(&r300->radeon); + rrb = radeon_get_depthbuffer(radeon); } else { - rrb = radeon_get_colorbuffer(&r300->radeon); + rrb = radeon_get_colorbuffer(radeon); } if (!timg->mt) { @@ -69,10 +65,6 @@ do_copy_texsubimage(GLcontext *ctx, intptr_t src_offset = rrb->draw_offset; intptr_t dst_offset = radeon_miptree_image_offset(timg->mt, _mesa_tex_target_to_face(target), level); - if (src_offset % 32 || dst_offset % 32) { - return GL_FALSE; - } - if (0) { fprintf(stderr, "%s: copying to face %d, level %d\n", __FUNCTION__, _mesa_tex_target_to_face(target), level); @@ -84,18 +76,19 @@ do_copy_texsubimage(GLcontext *ctx, } /* blit from src buffer to texture */ - return r300_blit(r300, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, - rrb->base.Width, rrb->base.Height, x, y, - timg->mt->bo, dst_offset, timg->base.TexFormat, - timg->base.Width, timg->base.Width, timg->base.Height, - dstx, dsty, width, height, 1); + return radeon->vtbl.blit(ctx, rrb->bo, src_offset, rrb->base.Format, rrb->pitch/rrb->cpp, + rrb->base.Width, rrb->base.Height, x, y, + timg->mt->bo, dst_offset, timg->base.TexFormat, + timg->mt->levels[level].rowstride / _mesa_get_format_bytes(timg->base.TexFormat), + timg->base.Width, timg->base.Height, + dstx, dsty, width, height, 1); } -static void -r300CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border) +void +radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) { struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj = @@ -139,11 +132,11 @@ fail: width, height, border); } -static void -r300CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height) +void +radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height) { struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target); @@ -159,10 +152,3 @@ r300CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, xoffset, yoffset, x, y, width, height); } } - - -void r300_init_texcopy_functions(struct dd_function_table *table) -{ - table->CopyTexImage2D = r300CopyTexImage2D; - table->CopyTexSubImage2D = r300CopyTexSubImage2D; -}
\ No newline at end of file diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 03178116c1..86b213c05c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -33,6 +33,7 @@ #include "main/imports.h" #include "main/context.h" #include "main/convolve.h" +#include "main/enums.h" #include "main/mipmap.h" #include "main/texcompress.h" #include "main/texstore.h" @@ -53,6 +54,13 @@ void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, assert(rowsize <= dststride); assert(rowsize <= srcstride); + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s dst %p, stride %u, src %p, stride %u, " + "numrows %u, rowsize %u.\n", + __func__, dst, dststride, + src, srcstride, + numrows, rowsize); + if (rowsize == srcstride && rowsize == dststride) { memcpy(dst, src, numrows*rowsize); } else { @@ -102,8 +110,12 @@ static void teximage_set_map_data(radeon_texture_image *image) { radeon_mipmap_level *lvl; - if (!image->mt) + if (!image->mt) { + radeon_warning("%s(%p) Trying to set map data without miptree.\n", + __func__, image); + return; + } lvl = &image->mt->levels[image->mtlevel]; @@ -162,15 +174,31 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; - if (!radeon_validate_texture_miptree(ctx, texObj)) - return; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + + if (!radeon_validate_texture_miptree(ctx, texObj)) { + radeon_error("%s(%p, tex %p) Failed to validate miptree for " + "sw fallback.\n", + __func__, ctx, texObj); + return; + } + + if (t->image_override && t->bo) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Work around for missing miptree in r100.\n", + __func__, ctx, texObj); - /* for r100 3D sw fallbacks don't have mt */ - if (t->image_override && t->bo) map_override(ctx, t); + } - if (!t->mt) + /* for r100 3D sw fallbacks don't have mt */ + if (!t->mt) { + radeon_warning("%s(%p, tex %p) No miptree in texture.\n", + __func__, ctx, texObj); return; + } radeon_bo_map(t->mt->bo, GL_FALSE); for(face = 0; face < t->mt->faces; ++face) { @@ -184,6 +212,10 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeonTexObj* t = radeon_tex_obj(texObj); int face, level; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p)\n", + __func__, ctx, texObj); + if (t->image_override && t->bo) unmap_override(ctx, t); /* for r100 3D sw fallbacks don't have mt */ @@ -197,21 +229,6 @@ void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) radeon_bo_unmap(t->mt->bo); } -GLuint radeon_face_for_target(GLenum target) -{ - switch (target) { - 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: - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - default: - return 0; - } -} - /** * Wraps Mesa's implementation to ensure that the base level image is mapped. * @@ -225,6 +242,10 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; int i, face; + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s(%p, tex %p) Target type %s.\n", + __func__, ctx, texObj, + _mesa_lookup_enum_by_nr(target)); _mesa_generate_mipmap(ctx, target, texObj); @@ -248,8 +269,19 @@ static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) { - GLuint face = radeon_face_for_target(target); + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_bo *bo; + GLuint face = _mesa_tex_target_to_face(target); radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); + bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo; + + if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p) Trying to generate mipmap for texture " + "in processing by GPU.\n", + __func__, ctx, texObj); + radeon_firevertices(rmesa); + } radeon_teximage_map(baseimage, GL_FALSE); radeon_generate_mipmap(ctx, target, texObj); @@ -312,12 +344,14 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); (void)format; -#if 0 - fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s InternalFormat=%s(%d) type=%s format=%s\n", + __func__, _mesa_lookup_enum_by_nr(internalFormat), internalFormat, _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); -#endif + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s do32bpt=%d force16bpt=%d\n", + __func__, do32bpt, force16bpt); switch (internalFormat) { case 4: @@ -566,11 +600,10 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { radeon_miptree_unreference(&t->mt); radeon_try_alloc_miptree(rmesa, t); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s: texObj %p, texImage %p, face %d, level %d, " "texObj miptree doesn't match, allocated new miptree %p\n", __FUNCTION__, texObj, texImage, face, level, t->mt); - } } /* Miptree alocation may have failed, @@ -579,7 +612,9 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, image->mtface = face; image->mtlevel = level; radeon_miptree_reference(t->mt, &image->mt); - } + } else + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Failed to allocate miptree.\n", __func__); } static GLuint * allocate_image_offsets(GLcontext *ctx, @@ -623,6 +658,10 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, GLuint dstRowStride; GLuint *dstImageOffsets; + radeon_print(RADEON_TEXTURE, RADEON_TRACE, + "%s(%p, tex %p, image %p) compressed %d\n", + __func__, ctx, texObj, texImage, compressed); + if (image->mt) { dstRowStride = image->mt->levels[image->mtlevel].rowstride; } else if (t->bo) { @@ -639,6 +678,7 @@ static void radeon_store_teximage(GLcontext* ctx, int dims, unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); if (!dstImageOffsets) { + radeon_warning("%s Failed to allocate dstImaeOffset.\n", __func__); return; } } else { @@ -710,20 +750,23 @@ static void radeon_teximage( radeon_texture_image* image = get_radeon_texture_image(texImage); GLint postConvWidth = width; GLint postConvHeight = height; - GLuint face = radeon_face_for_target(target); + GLuint face = _mesa_tex_target_to_face(target); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, face, level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling teximage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", - dims, texObj, texImage, face, level); - } t->validated = GL_FALSE; @@ -755,11 +798,10 @@ static void radeon_teximage( texImage->Height, texImage->Depth); texImage->Data = _mesa_alloc_texmemory(size); - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s %dd: texObj %p, texImage %p, " " no miptree assigned, using local memory %p\n", - dims, texObj, texImage, texImage->Data); - } + __func__, dims, texObj, texImage, texImage->Data); } } @@ -853,18 +895,22 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve radeonTexObj* t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s %dd: texObj %p, texImage %p, face %d, level %d\n", + __func__, dims, texObj, texImage, + _mesa_tex_target_to_face(target), level); { struct radeon_bo *bo; bo = !image->mt ? image->bo : image->mt->bo; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { + radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, + "%s Calling texsubimage for texture that is " + "queued for GPU processing.\n", + __func__); radeon_firevertices(rmesa); } } - if (RADEON_DEBUG & RADEON_TEXTURE) { - fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", - dims, texObj, texImage, radeon_face_for_target(target), level); - } t->validated = GL_FALSE; if (compressed) { @@ -953,6 +999,10 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, { radeon_texture_image *image = get_radeon_texture_image(texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, + "%s(%p, tex %p, image %p) compressed %d.\n", + __func__, ctx, texObj, image, compressed); + if (image->mt) { /* Map the texture image read-only */ radeon_teximage_map(image, GL_FALSE); diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index 906daf12d0..f09dd65214 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -44,7 +44,6 @@ void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj); void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj); void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj); int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj); -GLuint radeon_face_for_target(GLenum target); gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx, GLint internalFormat, @@ -126,4 +125,14 @@ void radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +void radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + #endif diff --git a/src/mesa/drivers/dri/radeon/server/radeon_egl.c b/src/mesa/drivers/dri/radeon/server/radeon_egl.c deleted file mode 100644 index c16d66e4ec..0000000000 --- a/src/mesa/drivers/dri/radeon/server/radeon_egl.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * EGL driver for radeon_dri.so - */ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "egllog.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egldri.h" - -#include "mtypes.h" -#include "memops.h" -#include "drm.h" -#include "drm_sarea.h" -#include "radeon_drm.h" -#include "radeon_dri.h" -#include "radeon.h" - -static size_t radeon_drm_page_size; - -/** - * radeon driver-specific driver class derived from _EGLDriver - */ -typedef struct radeon_driver -{ - _EGLDriver Base; /* base class/object */ - GLuint radeonStuff; -} radeonDriver; - -static int -RADEONSetParam(driDisplay *disp, int param, int value) -{ - drm_radeon_setparam_t sp; - int ret; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if ((ret=drmCommandWrite(disp->drmFD, DRM_RADEON_SETPARAM, &sp, sizeof(sp)))) { - fprintf(stderr,"Set param failed\n", ret); - return -1; - } - - return 0; -} - -static int -RADEONCheckDRMVersion(driDisplay *disp, RADEONInfoPtr info) -{ - drmVersionPtr version; - - version = drmGetVersion(disp->drmFD); - if (version) { - int req_minor, req_patch; - - /* Need 1.21.x for card type detection getparam - */ - req_minor = 21; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] RADEONDRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] radeon.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - info->drmMinor = version->version_minor; - drmFreeVersion(version); - } - - return 1; -} - - -/** - * \brief Compute base 2 logarithm. - * - * \param val value. - * - * \return base 2 logarithm of \p val. - */ -static int RADEONMinBits(int val) -{ - int bits; - - if (!val) return 1; - for (bits = 0; val; val >>= 1, ++bits); - return bits; -} - - -/* Initialize the PCI GART state. Request memory for use in PCI space, - * and initialize the Radeon registers to point to that memory. - */ -static int RADEONDRIPciInit(driDisplay *disp, RADEONInfoPtr info) -{ - int ret; - int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; - int s, l; - - ret = drmScatterGatherAlloc(disp->drmFD, info->gartSize*1024*1024, - &info->gartMemHandle); - if (ret < 0) { - fprintf(stderr, "[pci] Out of memory (%d)\n", ret); - return 0; - } - fprintf(stderr, - "[pci] %d kB allocated with handle 0x%04lx\n", - info->gartSize*1024, (long) info->gartMemHandle); - - info->gartOffset = 0; - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(disp->drmFD, info->ringStart, info->ringMapSize, - DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring handle = 0x%08lx\n", info->ringHandle); - - if (drmAddMap(disp->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[pci] Could not add ring read ptr mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(disp->drmFD, info->bufStart, info->bufMapSize, - DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[pci] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(disp->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[pci] Could not add GART texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[pci] GART texture map handle = 0x%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * \brief Initialize the AGP state - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Acquires and enables the AGP device. Reserves memory in the AGP space for - * the ring buffer, vertex buffers and textures. Initialize the Radeon - * registers to point to that memory and add client mappings. - */ -static int RADEONDRIAgpInit( driDisplay *disp, RADEONInfoPtr info) -{ - int mode, ret; - int s, l; - int agpmode = 1; - - if (drmAgpAcquire(disp->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - mode = drmAgpGetMode(disp->drmFD); /* Default mode */ - /* Disable fast write entirely - too many lockups. - */ - mode &= ~RADEON_AGP_MODE_MASK; - switch (agpmode) { - case 4: mode |= RADEON_AGP_4X_MODE; - case 2: mode |= RADEON_AGP_2X_MODE; - case 1: default: mode |= RADEON_AGP_1X_MODE; - } - - if (drmAgpEnable(disp->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(disp->drmFD); - return 0; - } - -#if 0 - /* Workaround for some hardware bugs */ - if (info->ChipFamily < CHIP_FAMILY_R200) - OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000); -#endif - info->gartOffset = 0; - - if ((ret = drmAgpAlloc(disp->drmFD, info->gartSize*1024*1024, 0, NULL, - &info->gartMemHandle)) < 0) { - fprintf(stderr, "[gart] Out of memory (%d)\n", ret); - drmAgpRelease(disp->drmFD); - return 0; - } - fprintf(stderr, - "[gart] %d kB allocated with handle 0x%08x\n", - info->gartSize*1024, (unsigned)info->gartMemHandle); - - if (drmAgpBind(disp->drmFD, - info->gartMemHandle, info->gartOffset) < 0) { - fprintf(stderr, "[gart] Could not bind\n"); - drmAgpFree(disp->drmFD, info->gartMemHandle); - drmAgpRelease(disp->drmFD); - return 0; - } - - /* Initialize the CP ring buffer data */ - info->ringStart = info->gartOffset; - info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size; - - info->ringReadOffset = info->ringStart + info->ringMapSize; - info->ringReadMapSize = radeon_drm_page_size; - - /* Reserve space for vertex/indirect buffers */ - info->bufStart = info->ringReadOffset + info->ringReadMapSize; - info->bufMapSize = info->bufSize*1024*1024; - - /* Reserve the rest for AGP textures */ - info->gartTexStart = info->bufStart + info->bufMapSize; - s = (info->gartSize*1024*1024 - info->gartTexStart); - l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - info->gartTexMapSize = (s >> l) << l; - info->log2GARTTexGran = l; - - if (drmAddMap(disp->drmFD, info->ringStart, info->ringMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) { - fprintf(stderr, "[gart] Could not add ring mapping\n"); - return 0; - } - fprintf(stderr, "[gart] ring handle = 0x%08lx\n", info->ringHandle); - - - if (drmAddMap(disp->drmFD, info->ringReadOffset, info->ringReadMapSize, - DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { - fprintf(stderr, - "[gart] Could not add ring read ptr mapping\n"); - return 0; - } - - fprintf(stderr, - "[gart] ring read ptr handle = 0x%08lx\n", - info->ringReadPtrHandle); - - if (drmAddMap(disp->drmFD, info->bufStart, info->bufMapSize, - DRM_AGP, 0, &info->bufHandle) < 0) { - fprintf(stderr, - "[gart] Could not add vertex/indirect buffers mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] vertex/indirect buffers handle = 0x%08lx\n", - info->bufHandle); - - if (drmAddMap(disp->drmFD, info->gartTexStart, info->gartTexMapSize, - DRM_AGP, 0, &info->gartTexHandle) < 0) { - fprintf(stderr, - "[gart] Could not add AGP texture map mapping\n"); - return 0; - } - fprintf(stderr, - "[gart] AGP texture map handle = 0x%08lx\n", - info->gartTexHandle); - - return 1; -} - - -/** - * Initialize all the memory-related fields of the RADEONInfo object. - * This includes the various 'offset' and 'size' fields. - */ -static int -RADEONMemoryInit(driDisplay *disp, RADEONInfoPtr info) -{ - int width_bytes = disp->virtualWidth * disp->cpp; - int cpp = disp->cpp; - int bufferSize = ((disp->virtualHeight * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int depthSize = ((((disp->virtualHeight+15) & ~15) * width_bytes - + RADEON_BUFFER_ALIGN) - & ~RADEON_BUFFER_ALIGN); - int l; - int pcie_gart_table_size = 0; - - info->frontOffset = 0; - info->frontPitch = disp->virtualWidth; - - if (disp->card_type==RADEON_CARD_PCIE) - pcie_gart_table_size = RADEON_PCIGART_TABLE_SIZE; - - /* Front, back and depth buffers - everything else texture?? - */ - info->textureSize = disp->fbSize - pcie_gart_table_size - 2 * bufferSize - depthSize; - - if (info->textureSize < 0) - return 0; - - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if (info->textureSize < 512 * 1024) { - info->textureOffset = 0; - info->textureSize = 0; - } - - /* Reserve space for textures */ - info->textureOffset = ((disp->fbSize - pcie_gart_table_size - info->textureSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - - /* Reserve space for the shared depth - * buffer. - */ - info->depthOffset = ((info->textureOffset - depthSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->depthPitch = disp->virtualWidth; - - info->backOffset = ((info->depthOffset - bufferSize + - RADEON_BUFFER_ALIGN) & - ~RADEON_BUFFER_ALIGN); - info->backPitch = disp->virtualWidth; - - if (pcie_gart_table_size) - info->pcieGartTableOffset = disp->fbSize - pcie_gart_table_size; - - fprintf(stderr, - "Will use back buffer at offset 0x%x, pitch %d\n", - info->backOffset, info->backPitch); - fprintf(stderr, - "Will use depth buffer at offset 0x%x, pitch %d\n", - info->depthOffset, info->depthPitch); - fprintf(stderr, - "Will use %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - if (pcie_gart_table_size) - { - fprintf(stderr, - "Will use %d kb for PCIE GART Table at offset 0x%x\n", - pcie_gart_table_size/1024, info->pcieGartTableOffset); - } - - /* XXX I don't think these are needed. */ -#if 0 - info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | - (info->frontOffset >> 10)); - - info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | - (info->backOffset >> 10)); - - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | - (info->depthOffset >> 10)); -#endif - - if (pcie_gart_table_size) - RADEONSetParam(disp, RADEON_SETPARAM_PCIGART_LOCATION, info->pcieGartTableOffset); - - return 1; -} - - -/** - * \brief Initialize the kernel data structures and enable the CP engine. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing - * all the parameters in a drm_radeon_init_t structure. - */ -static int RADEONDRIKernelInit( driDisplay *disp, - RADEONInfoPtr info) -{ - int cpp = disp->bpp / 8; - drm_radeon_init_t drmInfo; - int ret; - - memset(&drmInfo, 0, sizeof(drmInfo)); - - if ( (info->ChipFamily >= CHIP_FAMILY_R300) ) - drmInfo.func = RADEON_INIT_R300_CP; - else if ( (info->ChipFamily == CHIP_FAMILY_R200) || - (info->ChipFamily == CHIP_FAMILY_RV250) || - (info->ChipFamily == CHIP_FAMILY_M9) || - (info->ChipFamily == CHIP_FAMILY_RV280) ) - drmInfo.func = RADEON_INIT_R200_CP; - else - drmInfo.func = RADEON_INIT_CP; - - /* This is the struct passed to the kernel module for its initialization */ - /* XXX problem here: - * The front/back/depth_offset/pitch fields may change depending upon - * which drawing surface we're using!!! They can't be set just once - * during initialization. - * Looks like we'll need a new ioctl to update these fields for drawing - * to other surfaces... - */ - drmInfo.sarea_priv_offset = sizeof(drm_sarea_t); - drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE; - drmInfo.gart_size = info->gartSize*1024*1024; - drmInfo.ring_size = info->ringSize*1024*1024; - drmInfo.usec_timeout = 1000; - drmInfo.fb_bpp = disp->bpp; - drmInfo.depth_bpp = disp->bpp; - drmInfo.front_offset = info->frontOffset; - drmInfo.front_pitch = info->frontPitch * cpp; - drmInfo.back_offset = info->backOffset; - drmInfo.back_pitch = info->backPitch * cpp; - drmInfo.depth_offset = info->depthOffset; - drmInfo.depth_pitch = info->depthPitch * cpp; - drmInfo.ring_offset = info->ringHandle; - drmInfo.ring_rptr_offset = info->ringReadPtrHandle; - drmInfo.buffers_offset = info->bufHandle; - drmInfo.gart_textures_offset = info->gartTexHandle; - - ret = drmCommandWrite(disp->drmFD, DRM_RADEON_CP_INIT, &drmInfo, - sizeof(drm_radeon_init_t)); - - return ret >= 0; -} - - -/** - * \brief Add a map for the vertex buffers that will be accessed by any - * DRI-based clients. - * - * \param ctx display handle. - * \param info driver private data. - * - * \return one on success, or zero on failure. - * - * Calls drmAddBufs() with the previously allocated vertex buffers. - */ -static int RADEONDRIBufInit( driDisplay *disp, RADEONInfoPtr info ) -{ - /* Initialize vertex buffers */ - info->bufNumBufs = drmAddBufs(disp->drmFD, - info->bufMapSize / RADEON_BUFFER_SIZE, - RADEON_BUFFER_SIZE, - (disp->card_type!=RADEON_CARD_AGP) ? DRM_SG_BUFFER : DRM_AGP_BUFFER, - info->bufStart); - - if (info->bufNumBufs <= 0) { - fprintf(stderr, - "[drm] Could not create vertex/indirect buffers list\n"); - return 0; - } - fprintf(stderr, - "[drm] Added %d %d byte vertex/indirect buffers\n", - info->bufNumBufs, RADEON_BUFFER_SIZE); - - return 1; -} - - -/** - * \brief Install an IRQ handler. - * - * \param disp display handle. - * \param info driver private data. - * - * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to - * IRQ-free operation on failure. - */ -static void RADEONDRIIrqInit(driDisplay *disp, RADEONInfoPtr info) -{ - if ((drmCtlInstHandler(disp->drmFD, 0)) != 0) - fprintf(stderr, "[drm] failure adding irq handler, " - "there is a device already using that irq\n" - "[drm] falling back to irq-free operation\n"); -} - - -/** - * \brief Initialize the AGP heap. - * - * \param disp display handle. - * \param info driver private data. - * - * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing - * all the parameters in a drm_radeon_mem_init_heap structure. - */ -static void RADEONDRIAgpHeapInit(driDisplay *disp, - RADEONInfoPtr info) -{ - drm_radeon_mem_init_heap_t drmHeap; - - /* Start up the simple memory manager for gart space */ - drmHeap.region = RADEON_MEM_REGION_GART; - drmHeap.start = 0; - drmHeap.size = info->gartTexMapSize; - - if (drmCommandWrite(disp->drmFD, DRM_RADEON_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized gart heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel gart heap manager, %d\n", - info->gartTexMapSize); - } -} - -static int RADEONGetCardType(driDisplay *disp, RADEONInfoPtr info) -{ - drm_radeon_getparam_t gp; - int ret; - - gp.param = RADEON_PARAM_CARD_TYPE; - gp.value = &disp->card_type; - - ret=drmCommandWriteRead(disp->drmFD, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_CARD_TYPE) : %d\n", ret); - return -1; - } - - return disp->card_type; -} - -/** - * Called at the start of each server generation. - * - * \param disp display handle. - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Performs static frame buffer allocation. Opens the DRM device and add maps - * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more - * information. Creates a \e server context to grab the lock for the - * initialization ioctls and calls the other initilization functions in this - * file. Starts the CP engine via the DRM_RADEON_CP_START command. - * - * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its - * initialization. - */ -static int -RADEONScreenInit( driDisplay *disp, RADEONInfoPtr info, - RADEONDRIPtr pRADEONDRI) -{ - int i, err; - - /* XXX this probably isn't needed here */ - { - int width_bytes = (disp->virtualWidth * disp->cpp); - int maxy = disp->fbSize / width_bytes; - - if (maxy <= disp->virtualHeight * 3) { - _eglLog(_EGL_WARNING, - "Static buffer allocation failed -- " - "need at least %d kB video memory (have %d kB)\n", - (disp->virtualWidth * disp->virtualHeight * - disp->cpp * 3 + 1023) / 1024, - disp->fbSize / 1024); - return 0; - } - } - - /* Memory manager setup */ - if (!RADEONMemoryInit(disp, info)) { - return 0; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(disp->drmFD, &disp->serverContext)) != 0) { - _eglLog(_EGL_WARNING, "%s: drmCreateContext failed %d\n", - __FUNCTION__, err); - return 0; - } - - DRM_LOCK(disp->drmFD, disp->pSAREA, disp->serverContext, 0); - - /* Initialize the kernel data structures */ - if (!RADEONDRIKernelInit(disp, info)) { - _eglLog(_EGL_WARNING, "RADEONDRIKernelInit failed\n"); - DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); - return 0; - } - - /* Initialize the vertex buffers list */ - if (!RADEONDRIBufInit(disp, info)) { - fprintf(stderr, "RADEONDRIBufInit failed\n"); - DRM_UNLOCK(disp->drmFD, disp->pSAREA, disp->serverContext); - return 0; - } - - /* Initialize IRQ */ - RADEONDRIIrqInit(disp, info); - - /* Initialize kernel gart memory manager */ - RADEONDRIAgpHeapInit(disp, info); - - /* Initialize the SAREA private data structure */ - { - drm_radeon_sarea_t *pSAREAPriv; - pSAREAPriv = (drm_radeon_sarea_t *)(((char*)disp->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - pSAREAPriv->pfState = info->page_flip_enable; - } - - for ( i = 0;; i++ ) { - drmMapType type; - drmMapFlags flags; - drm_handle_t handle, offset; - drmSize size; - int rc, mtrr; - - if ( ( rc = drmGetMap( disp->drmFD, i, &offset, &size, &type, &flags, &handle, &mtrr ) ) != 0 ) - break; - if ( type == DRM_REGISTERS ) { - pRADEONDRI->registerHandle = offset; - pRADEONDRI->registerSize = size; - break; - } - } - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - drimemsetio((char *)disp->pFB + info->frontOffset, - 0xEE, - info->frontPitch * disp->cpp * disp->virtualHeight ); - - drimemsetio((char *)disp->pFB + info->backOffset, - 0x30, - info->backPitch * disp->cpp * disp->virtualHeight ); - - - /* This is the struct passed to radeon_dri.so for its initialization */ - pRADEONDRI->deviceID = info->Chipset; - pRADEONDRI->width = disp->virtualWidth; - pRADEONDRI->height = disp->virtualHeight; - pRADEONDRI->depth = disp->bpp; /* XXX: depth */ - pRADEONDRI->bpp = disp->bpp; - pRADEONDRI->IsPCI = (disp->card_type != RADEON_CARD_AGP);; - pRADEONDRI->frontOffset = info->frontOffset; - pRADEONDRI->frontPitch = info->frontPitch; - pRADEONDRI->backOffset = info->backOffset; - pRADEONDRI->backPitch = info->backPitch; - pRADEONDRI->depthOffset = info->depthOffset; - pRADEONDRI->depthPitch = info->depthPitch; - pRADEONDRI->textureOffset = info->textureOffset; - pRADEONDRI->textureSize = info->textureSize; - pRADEONDRI->log2TexGran = info->log2TexGran; - pRADEONDRI->statusHandle = info->ringReadPtrHandle; - pRADEONDRI->statusSize = info->ringReadMapSize; - pRADEONDRI->gartTexHandle = info->gartTexHandle; - pRADEONDRI->gartTexMapSize = info->gartTexMapSize; - pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran; - pRADEONDRI->gartTexOffset = info->gartTexStart; - pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t); - - /* Don't release the lock now - let the VT switch handler do it. */ - - return 1; -} - - -/** - * \brief Get Radeon chip family from chipset number. - * - * \param info driver private data. - * - * \return non-zero on success, or zero on failure. - * - * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily - * according to the value of RADEONInfoRec::Chipset. Fails if the - * chipset is unrecognized or not appropriate for this driver (i.e., not - * an r100 style radeon) - */ -static int get_chipfamily_from_chipset( RADEONInfoPtr info ) -{ - switch (info->Chipset) { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: - info->ChipFamily = CHIP_FAMILY_M6; - break; - - case PCI_CHIP_RADEON_QY: - case PCI_CHIP_RADEON_QZ: - info->ChipFamily = CHIP_FAMILY_VE; - break; - - case PCI_CHIP_R200_QL: - case PCI_CHIP_R200_QN: - case PCI_CHIP_R200_QO: - case PCI_CHIP_R200_Ql: - case PCI_CHIP_R200_BB: - info->ChipFamily = CHIP_FAMILY_R200; - break; - - case PCI_CHIP_RV200_QW: /* RV200 desktop */ - case PCI_CHIP_RV200_QX: - info->ChipFamily = CHIP_FAMILY_RV200; - break; - - case PCI_CHIP_RADEON_LW: - case PCI_CHIP_RADEON_LX: - info->ChipFamily = CHIP_FAMILY_M7; - break; - - case PCI_CHIP_RV250_Id: - case PCI_CHIP_RV250_Ie: - case PCI_CHIP_RV250_If: - case PCI_CHIP_RV250_Ig: - info->ChipFamily = CHIP_FAMILY_RV250; - break; - - case PCI_CHIP_RV250_Ld: - case PCI_CHIP_RV250_Le: - case PCI_CHIP_RV250_Lf: - case PCI_CHIP_RV250_Lg: - info->ChipFamily = CHIP_FAMILY_M9; - break; - - case PCI_CHIP_RV280_Y_: - case PCI_CHIP_RV280_Ya: - case PCI_CHIP_RV280_Yb: - case PCI_CHIP_RV280_Yc: - info->ChipFamily = CHIP_FAMILY_RV280; - break; - - case PCI_CHIP_R300_ND: - case PCI_CHIP_R300_NE: - case PCI_CHIP_R300_NF: - case PCI_CHIP_R300_NG: - info->ChipFamily = CHIP_FAMILY_R300; - break; - - case PCI_CHIP_RV370_5460: - info->ChipFamily = CHIP_FAMILY_RV380; - break; - - default: - /* Original Radeon/7200 */ - info->ChipFamily = CHIP_FAMILY_RADEON; - } - - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param disp display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p disp - * and then calls RADEONScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int radeonInitFBDev( driDisplay *disp, RADEONDRIPtr pRADEONDRI ) -{ - int err; - RADEONInfoPtr info = calloc(1, sizeof(*info)); - - disp->driverPrivate = (void *)info; - - info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE; - info->gartSize = RADEON_DEFAULT_AGP_SIZE; - info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; - info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; - info->ringSize = RADEON_DEFAULT_RING_SIZE; - info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP; - - fprintf(stderr, - "Using %d MB AGP aperture\n", info->gartSize); - fprintf(stderr, - "Using %d MB for the ring buffer\n", info->ringSize); - fprintf(stderr, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - fprintf(stderr, - "Using %d MB for AGP textures\n", info->gartTexSize); - fprintf(stderr, - "page flipping %sabled\n", info->page_flip_enable?"en":"dis"); - - info->Chipset = disp->chipset; - - if (!get_chipfamily_from_chipset( info )) { - fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n"); - fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n"); - return 0; - } -#if 0 - if (info->ChipFamily >= CHIP_FAMILY_R300) { - fprintf(stderr, - "Direct rendering not yet supported on " - "Radeon 9700 and newer cards\n"); - return 0; - } -#endif - -#if 00 - /* don't seem to need this here */ - info->frontPitch = disp->virtualWidth; -#endif - - /* Check the radeon DRM version */ - if (!RADEONCheckDRMVersion(disp, info)) { - return 0; - } - - if (RADEONGetCardType(disp, info)<0) - return 0; - - if (disp->card_type!=RADEON_CARD_AGP) { - /* Initialize PCI */ - if (!RADEONDRIPciInit(disp, info)) - return 0; - } - else { - /* Initialize AGP */ - if (!RADEONDRIAgpInit(disp, info)) - return 0; - } - - if (!RADEONScreenInit( disp, info, pRADEONDRI)) - return 0; - - /* Initialize and start the CP if required */ - if ((err = drmCommandNone(disp->drmFD, DRM_RADEON_CP_START)) != 0) { - fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err); - return 0; - } - - return 1; -} - - -/** - * Create list of all supported surface configs, attach list to the display. - */ -static EGLBoolean -radeonFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, - unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - _EGLConfig *configs; - _EGLConfig *c; - unsigned int i, num_configs; - unsigned int depth_buffer_factor; - unsigned int back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy - * enough to add support. Basically, if a context is created with an - * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping - * will never be used. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ - }; - - uint8_t depth_bits_array[2]; - uint8_t stencil_bits_array[2]; - - depth_bits_array[0] = depth_bits; - depth_bits_array[1] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; - back_buffer_factor = (have_back_buffer) ? 2 : 1; - - num_configs = depth_buffer_factor * back_buffer_factor * 2; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_RGBA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = calloc(sizeof(*configs), num_configs); - c = configs; - if (!_eglFillInConfigs(c, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return EGL_FALSE; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (i = 0, c = configs; i < num_configs; i++, c++) { - int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); - if ((stencil != 0) && (stencil != stencil_bits)) { - SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); - } - } - - for (i = 0, c = configs; i < num_configs; i++, c++) - _eglAddConfig(disp, c); - - free(configs); - - return EGL_TRUE; -} - - -/** - * Show the given surface on the named screen. - * If surface is EGL_NO_SURFACE, disable the screen's output. - */ -static EGLBoolean -radeonShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - EGLBoolean b = _eglDRIShowScreenSurfaceMESA(drv, dpy, screen, surface, m); - return b; -} - - -/** - * Called via eglInitialize() by user. - */ -static EGLBoolean -radeonInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - __DRIframebuffer framebuffer; - driDisplay *display; - - /* one-time init */ - radeon_drm_page_size = getpagesize(); - - if (!_eglDRIInitialize(drv, dpy, major, minor)) - return EGL_FALSE; - - display = Lookup_driDisplay(dpy); - - framebuffer.dev_priv_size = sizeof(RADEONDRIRec); - framebuffer.dev_priv = malloc(sizeof(RADEONDRIRec)); - - /* XXX we shouldn't hard-code values here! */ - /* we won't know the screen surface size until the user calls - * eglCreateScreenSurfaceMESA(). - */ -#if 0 - display->virtualWidth = 1024; - display->virtualHeight = 768; -#else - display->virtualWidth = 1280; - display->virtualHeight = 1024; -#endif - display->bpp = 32; - display->cpp = 4; - - if (!_eglDRIGetDisplayInfo(display)) - return EGL_FALSE; - - framebuffer.base = display->pFB; - framebuffer.width = display->virtualWidth; - framebuffer.height = display->virtualHeight; - framebuffer.stride = display->virtualWidth; - framebuffer.size = display->fbSize; - radeonInitFBDev( display, framebuffer.dev_priv ); - - if (!_eglDRICreateDisplay(display, &framebuffer)) - return EGL_FALSE; - - if (!_eglDRICreateScreens(display)) - return EGL_FALSE; - - /* create a variety of both 32 and 16-bit configurations */ - radeonFillInConfigs(&display->Base, 32, 24, 8, GL_TRUE); - radeonFillInConfigs(&display->Base, 16, 16, 0, GL_TRUE); - - drv->Initialized = EGL_TRUE; - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new radeonDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy) -{ - radeonDriver *radeon; - - radeon = (radeonDriver *) calloc(1, sizeof(*radeon)); - if (!radeon) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglDRIInitDriverFallbacks(&radeon->Base); - - /* then plug in our radeon-specific functions */ - radeon->Base.API.Initialize = radeonInitialize; - radeon->Base.API.ShowScreenSurfaceMESA = radeonShowScreenSurfaceMESA; - - return &radeon->Base; -} diff --git a/src/mesa/drivers/dri/radeon/server/radeon_reg.h b/src/mesa/drivers/dri/radeon/server/radeon_reg.h index e81d7fdcd0..1b33de1edf 100644 --- a/src/mesa/drivers/dri/radeon/server/radeon_reg.h +++ b/src/mesa/drivers/dri/radeon/server/radeon_reg.h @@ -1959,7 +1959,30 @@ #define RADEON_SE_ZBIAS_FACTOR 0x1db0 #define RADEON_SE_ZBIAS_CONSTANT 0x1db4 - +#define RADEON_SE_VTX_FMT 0x2080 +# define RADEON_SE_VTX_FMT_XY 0x00000000 +# define RADEON_SE_VTX_FMT_W0 0x00000001 +# define RADEON_SE_VTX_FMT_FPCOLOR 0x00000002 +# define RADEON_SE_VTX_FMT_FPALPHA 0x00000004 +# define RADEON_SE_VTX_FMT_PKCOLOR 0x00000008 +# define RADEON_SE_VTX_FMT_FPSPEC 0x00000010 +# define RADEON_SE_VTX_FMT_FPFOG 0x00000020 +# define RADEON_SE_VTX_FMT_PKSPEC 0x00000040 +# define RADEON_SE_VTX_FMT_ST0 0x00000080 +# define RADEON_SE_VTX_FMT_ST1 0x00000100 +# define RADEON_SE_VTX_FMT_Q1 0x00000200 +# define RADEON_SE_VTX_FMT_ST2 0x00000400 +# define RADEON_SE_VTX_FMT_Q2 0x00000800 +# define RADEON_SE_VTX_FMT_ST3 0x00001000 +# define RADEON_SE_VTX_FMT_Q3 0x00002000 +# define RADEON_SE_VTX_FMT_Q0 0x00004000 +# define RADEON_SE_VTX_FMT_BLND_WEIGHT_CNT_MASK 0x00038000 +# define RADEON_SE_VTX_FMT_N0 0x00040000 +# define RADEON_SE_VTX_FMT_XY1 0x08000000 +# define RADEON_SE_VTX_FMT_Z1 0x10000000 +# define RADEON_SE_VTX_FMT_W1 0x20000000 +# define RADEON_SE_VTX_FMT_N1 0x40000000 +# define RADEON_SE_VTX_FMT_Z 0x80000000 /* Registers for CP and Microcode Engine */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c index 32ca86de8a..bbf49aec27 100644 --- a/src/mesa/drivers/dri/savage/savagedd.c +++ b/src/mesa/drivers/dri/savage/savagedd.c @@ -29,15 +29,11 @@ #include <stdio.h> #include "main/mm.h" -#include "swrast/swrast.h" #include "savagedd.h" #include "savagestate.h" -#include "savagespan.h" #include "savagetex.h" -#include "savagetris.h" #include "savagecontext.h" -#include "main/extensions.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index d0b64e801a..9e181ce3be 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -37,12 +37,10 @@ #include "savagecontext.h" #include "savageioctl.h" -#include "savage_bci.h" #include "savagestate.h" #include "savagespan.h" #include "drm.h" -#include <sys/ioctl.h> #include <sys/timeb.h> #define DEPTH_SCALE_16 ((1<<16)-1) diff --git a/src/mesa/drivers/dri/savage/savagerender.c b/src/mesa/drivers/dri/savage/savagerender.c index 8221edf387..c369bb124c 100644 --- a/src/mesa/drivers/dri/savage/savagerender.c +++ b/src/mesa/drivers/dri/savage/savagerender.c @@ -36,7 +36,6 @@ #include "tnl/t_context.h" #include "savagecontext.h" -#include "savagetris.h" #include "savagestate.h" #include "savageioctl.h" diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c index 792e166d9c..0913dd1278 100644 --- a/src/mesa/drivers/dri/savage/savagespan.c +++ b/src/mesa/drivers/dri/savage/savagespan.c @@ -26,7 +26,6 @@ #include "savagedd.h" #include "savagespan.h" #include "savageioctl.h" -#include "savage_bci.h" #include "savage_3d_reg.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c index 97598f599e..394be44eac 100644 --- a/src/mesa/drivers/dri/savage/savagetex.c +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -33,8 +33,6 @@ #include "main/simple_list.h" #include "main/enums.h" -#include "swrast/swrast.h" - #include "savagecontext.h" #include "savagetex.h" #include "savagetris.h" diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c index 9a92541ef7..a177a7d2b6 100644 --- a/src/mesa/drivers/dri/savage/savagetris.c +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -52,7 +52,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "savagestate.h" #include "savagetex.h" #include "savageioctl.h" -#include "savage_bci.h" static void savageRasterPrimitive( GLcontext *ctx, GLuint prim ); static void savageRenderPrimitive( GLcontext *ctx, GLenum prim ); diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c index 65d4c06466..52008c7ea3 100644 --- a/src/mesa/drivers/dri/sis/sis6326_state.c +++ b/src/mesa/drivers/dri/sis/sis6326_state.c @@ -34,14 +34,12 @@ #include "sis_reg.h" #include "main/context.h" -#include "main/enums.h" #include "main/colormac.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c index 0944f4d8b4..400681a04a 100644 --- a/src/mesa/drivers/dri/sis/sis_context.c +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -43,8 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_alloc.h" #include "main/imports.h" -#include "main/matrix.h" -#include "main/extensions.h" #include "utils.h" #include "main/framebuffer.h" @@ -55,7 +53,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "vbo/vbo.h" #include "tnl/tnl.h" -#include "tnl/t_pipeline.h" #define need_GL_EXT_fog_coord #define need_GL_EXT_secondary_color diff --git a/src/mesa/drivers/dri/sis/sis_dd.c b/src/mesa/drivers/dri/sis/sis_dd.c index 217d77557f..fe4ade8592 100644 --- a/src/mesa/drivers/dri/sis/sis_dd.c +++ b/src/mesa/drivers/dri/sis/sis_dd.c @@ -40,9 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_tris.h" -#include "swrast/swrast.h" #include "main/formats.h" -#include "main/framebuffer.h" #include "main/renderbuffer.h" #include "utils.h" diff --git a/src/mesa/drivers/dri/sis/sis_fog.c b/src/mesa/drivers/dri/sis/sis_fog.c index 517d5722e6..6c774e010e 100644 --- a/src/mesa/drivers/dri/sis/sis_fog.c +++ b/src/mesa/drivers/dri/sis/sis_fog.c @@ -33,7 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" #include "sis_state.h" -#include "swrast/swrast.h" #include "main/macros.h" diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index d38b93ec9b..cb7ed8a08b 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -39,7 +39,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" #include "sis_dri.h" #include "sis_lock.h" -#include "sis_span.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c index 98e8d02fab..a22195ccce 100644 --- a/src/mesa/drivers/dri/sis/sis_state.c +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -35,17 +35,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_tris.h" #include "sis_lock.h" -#include "sis_tex.h" #include "main/context.h" -#include "main/enums.h" -#include "main/colormac.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" /* ============================================================= * Alpha blending diff --git a/src/mesa/drivers/dri/sis/sis_tex.c b/src/mesa/drivers/dri/sis/sis_tex.c index 951c470dad..31709c3af6 100644 --- a/src/mesa/drivers/dri/sis/sis_tex.c +++ b/src/mesa/drivers/dri/sis/sis_tex.c @@ -31,7 +31,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "main/imports.h" #include "main/texstore.h" -#include "main/teximage.h" #include "main/texobj.h" #include "sis_context.h" diff --git a/src/mesa/drivers/dri/sis/sis_texstate.c b/src/mesa/drivers/dri/sis/sis_texstate.c index 4c22a10cf7..7b0eebd066 100644 --- a/src/mesa/drivers/dri/sis/sis_texstate.c +++ b/src/mesa/drivers/dri/sis/sis_texstate.c @@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "sis_context.h" -#include "sis_state.h" #include "sis_tex.h" #include "sis_tris.h" #include "sis_alloc.h" diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c index 4690274c3c..4b41d78d82 100644 --- a/src/mesa/drivers/dri/sis/sis_tris.c +++ b/src/mesa/drivers/dri/sis/sis_tris.c @@ -47,7 +47,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_state.h" #include "sis_lock.h" #include "sis_span.h" -#include "sis_alloc.h" #include "sis_tex.h" /* 6326 and 300-series shared */ diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 8340861aff..4e823669bf 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -368,7 +368,7 @@ driCreateNewDrawable(__DRIscreen *screen, buf->row = _mesa_malloc(MAX_WIDTH * 4); /* basic framebuffer setup */ - _mesa_initialize_framebuffer(&buf->Base, &config->modes); + _mesa_initialize_window_framebuffer(&buf->Base, &config->modes); /* add front renderbuffer */ frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_dd.c b/src/mesa/drivers/dri/tdfx/tdfx_dd.c index ed8a331549..2cbbeb8114 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_dd.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_dd.c @@ -35,17 +35,10 @@ #include "tdfx_context.h" #include "tdfx_dd.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_pixels.h" #include "utils.h" #include "main/context.h" -#include "main/enums.h" -#include "main/framebuffer.h" -#include "swrast/swrast.h" -#if defined(USE_X86_ASM) -#include "x86/common_x86_asm.h" -#endif #define DRIVER_DATE "20061113" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_lock.c b/src/mesa/drivers/dri/tdfx/tdfx_lock.c index 4f84240104..f218e4ee57 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_lock.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_lock.c @@ -38,7 +38,6 @@ #include "tdfx_state.h" #include "tdfx_render.h" #include "tdfx_texman.h" -#include "tdfx_tris.h" #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c index 65f0464f8a..4449627418 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c @@ -38,7 +38,6 @@ #include "tdfx_context.h" #include "tdfx_dd.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_pixels.h" #include "tdfx_render.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 4422b5dec4..9f6b35faa2 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -36,9 +36,7 @@ #include "tdfx_dri.h" #include "tdfx_context.h" #include "tdfx_lock.h" -#include "tdfx_vb.h" #include "tdfx_span.h" -#include "tdfx_tris.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index cdb61a0ce0..dcbc7647f2 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -40,8 +40,6 @@ #include "main/mtypes.h" #include "main/colormac.h" -#include "main/texstore.h" -#include "main/teximage.h" #include "swrast/swrast.h" #include "vbo/vbo.h" @@ -51,11 +49,9 @@ #include "tdfx_context.h" #include "tdfx_state.h" -#include "tdfx_vb.h" #include "tdfx_tex.h" #include "tdfx_texman.h" #include "tdfx_texstate.h" -#include "tdfx_tris.h" #include "tdfx_render.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texman.c b/src/mesa/drivers/dri/tdfx/tdfx_texman.c index 35636ee5ef..726cc58a10 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texman.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texman.c @@ -35,7 +35,6 @@ */ #include "tdfx_context.h" -#include "tdfx_tex.h" #include "tdfx_texman.h" #include "main/texobj.h" #include "main/hash.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c index 3f737878ed..6658b4d0c3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c @@ -38,7 +38,6 @@ */ #include "tdfx_state.h" -#include "tdfx_tex.h" #include "tdfx_texman.h" #include "tdfx_texstate.h" diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vb.c b/src/mesa/drivers/dri/tdfx/tdfx_vb.c index c200ba3255..0f3c877a3e 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_vb.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_vb.c @@ -29,13 +29,8 @@ #include "main/macros.h" #include "main/colormac.h" -#include "math/m_translate.h" -#include "swrast_setup/swrast_setup.h" - #include "tdfx_context.h" #include "tdfx_vb.h" -#include "tdfx_tris.h" -#include "tdfx_state.h" #include "tdfx_render.h" static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index d17a160271..9da96bdd45 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -33,10 +33,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/formats.h" -#include "main/matrix.h" -#include "main/state.h" #include "main/simple_list.h" -#include "main/extensions.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 8d4edfa305..c9a31f3383 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -34,7 +34,6 @@ #include "via_context.h" #include "via_tris.h" #include "via_ioctl.h" -#include "via_state.h" #include "via_fb.h" #include "via_3d_reg.h" diff --git a/src/mesa/drivers/dri/unichrome/via_render.c b/src/mesa/drivers/dri/unichrome/via_render.c index f676cc13c8..896c43db1b 100644 --- a/src/mesa/drivers/dri/unichrome/via_render.c +++ b/src/mesa/drivers/dri/unichrome/via_render.c @@ -37,7 +37,6 @@ #include "via_context.h" #include "via_tris.h" -#include "via_state.h" #include "via_ioctl.h" /* diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index 2cfb98317d..8c91c937c6 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -30,17 +30,13 @@ #include "main/context.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" -#include "main/matrix.h" #include "main/simple_list.h" #include "vblank.h" #include "via_state.h" #include "via_tex.h" #include "via_span.h" -#include "via_tris.h" -#include "via_ioctl.h" #include "via_screen.h" -#include "via_fb.h" #include "via_dri.h" #include "GL/internal/dri_interface.h" diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index e6e5526d34..f7029b9492 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -35,7 +35,6 @@ #include "via_context.h" #include "via_state.h" #include "via_tex.h" -#include "via_tris.h" #include "via_ioctl.h" #include "via_3d_reg.h" @@ -44,8 +43,6 @@ #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" -#include "tnl/t_pipeline.h" - static GLuint ROP[16] = { HC_HROP_BLACK, /* GL_CLEAR 0 */ diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c index 24924d2613..917f975466 100644 --- a/src/mesa/drivers/dri/unichrome/via_tex.c +++ b/src/mesa/drivers/dri/unichrome/via_tex.c @@ -37,14 +37,12 @@ #include "main/mipmap.h" #include "main/mm.h" #include "main/simple_list.h" -#include "main/texcompress.h" #include "main/texobj.h" #include "main/texstore.h" #include "via_context.h" #include "via_fb.h" #include "via_tex.h" -#include "via_state.h" #include "via_ioctl.h" #include "via_3d_reg.h" diff --git a/src/mesa/drivers/dri/unichrome/via_texcombine.c b/src/mesa/drivers/dri/unichrome/via_texcombine.c index b646897848..f87ba071f3 100644 --- a/src/mesa/drivers/dri/unichrome/via_texcombine.c +++ b/src/mesa/drivers/dri/unichrome/via_texcombine.c @@ -38,7 +38,6 @@ #include "main/enums.h" #include "via_context.h" -#include "via_state.h" #include "via_tex.h" #include "via_3d_reg.h" diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c index 531558dc4d..1a56b2395f 100644 --- a/src/mesa/drivers/fbdev/glfbdev.c +++ b/src/mesa/drivers/fbdev/glfbdev.c @@ -626,7 +626,7 @@ glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo, return NULL; /* basic framebuffer setup */ - _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual); + _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual); /* add front renderbuffer */ frontrb = new_glfbdev_renderbuffer(frontBuffer, visual); _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT, diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile index fa8293d039..080fe475c1 100644 --- a/src/mesa/drivers/glslcompiler/Makefile +++ b/src/mesa/drivers/glslcompiler/Makefile @@ -10,6 +10,7 @@ PROGRAM = glslcompiler OBJECTS = \ glslcompiler.o \ ../../glapi/glapi.o \ + ../../glapi/glapi_nop.o \ ../../glapi/glthread.o \ ../../main/dispatch.o \ ../common/driverfuncs.o \ diff --git a/src/mesa/drivers/osmesa/osmesa.def b/src/mesa/drivers/osmesa/osmesa.def index 71e96873d8..06afab72b0 100644 --- a/src/mesa/drivers/osmesa/osmesa.def +++ b/src/mesa/drivers/osmesa/osmesa.def @@ -2,6 +2,7 @@ VERSION 4.1 EXPORTS + OSMesaColorClamp OSMesaCreateContext OSMesaCreateContextExt OSMesaDestroyContext @@ -11,3 +12,4 @@ EXPORTS OSMesaGetIntegerv OSMesaGetDepthBuffer OSMesaGetColorBuffer + OSMesaGetProcAddress diff --git a/src/mesa/drivers/windows/gdi/mesa.def b/src/mesa/drivers/windows/gdi/mesa.def index 62f75d9541..700e333429 100644 --- a/src/mesa/drivers/windows/gdi/mesa.def +++ b/src/mesa/drivers/windows/gdi/mesa.def @@ -870,7 +870,6 @@ EXPORTS _mesa_bzero _mesa_calloc _mesa_choose_tex_format - _mesa_compressed_texture_size _mesa_create_framebuffer _mesa_create_visual _mesa_delete_array_object @@ -932,6 +931,8 @@ EXPORTS _mesa_update_framebuffer_visual _mesa_use_program _mesa_Viewport + _mesa_meta_init + _mesa_meta_free _mesa_meta_CopyColorSubTable _mesa_meta_CopyColorTable _mesa_meta_CopyConvolutionFilter1D @@ -941,7 +942,6 @@ EXPORTS _mesa_meta_CopyTexSubImage1D _mesa_meta_CopyTexSubImage2D _mesa_meta_CopyTexSubImage3D - _mesa_wait_query _swrast_Accum _swrast_Bitmap _swrast_BlitFramebuffer diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 76c825a090..b24b758cfb 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -35,7 +35,7 @@ wmesa_new_framebuffer(HDC hdc, GLvisual *visual) WMesaFramebuffer pwfb = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); if (pwfb) { - _mesa_initialize_framebuffer(&pwfb->Base, visual); + _mesa_initialize_window_framebuffer(&pwfb->Base, visual); pwfb->hDC = hdc; /* insert at head of list */ pwfb->next = FirstFramebuffer; @@ -1286,9 +1286,6 @@ void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, rb->PutMonoValues = write_mono_rgba_pixels_16; rb->GetRow = read_rgba_span_16; rb->GetValues = read_rgba_pixels_16; - rb->RedBits = 5; - rb->GreenBits = 6; - rb->BlueBits = 5; break; case PF_8R8G8B: if (cColorBits == 24) @@ -1300,9 +1297,6 @@ void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, rb->PutMonoValues = write_mono_rgba_pixels_24; rb->GetRow = read_rgba_span_24; rb->GetValues = read_rgba_pixels_24; - rb->RedBits = 8; - rb->GreenBits = 8; - rb->BlueBits = 8; } else { @@ -1313,9 +1307,6 @@ void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, rb->PutMonoValues = write_mono_rgba_pixels_32; rb->GetRow = read_rgba_span_32; rb->GetValues = read_rgba_pixels_32; - rb->RedBits = 8; - rb->GreenBits = 8; - rb->BlueBits = 8; } break; default: @@ -1331,9 +1322,6 @@ void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, rb->PutMonoValues = write_mono_rgba_pixels_front; rb->GetRow = read_rgba_span_front; rb->GetValues = read_rgba_pixels_front; - rb->RedBits = 8; /* XXX fix these (565?) */ - rb->GreenBits = 8; - rb->BlueBits = 8; } } diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c index 02eea25a71..e11aff1a84 100644 --- a/src/mesa/drivers/x11/glxapi.c +++ b/src/mesa/drivers/x11/glxapi.c @@ -50,6 +50,37 @@ struct display_dispatch { struct display_dispatch *Next; }; + +/** + * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in + * libglapi.a. We need to define them here. + */ +#ifdef GLX_INDIRECT_RENDERING + +#include "glapi/glapitable.h" +#include "glapi/glapidispatch.h" + +#define KEYWORD1 PUBLIC + +#if defined(USE_MGL_NAMESPACE) +#define NAME(func) mgl##func +#else +#define NAME(func) gl##func +#endif + +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + CALL_ ## FUNC(GET_DISPATCH(), ARGS); + +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + return CALL_ ## FUNC(GET_DISPATCH(), ARGS); + +/* skip normal ones */ +#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS +#include "glapi/glapitemp.h" + +#endif /* GLX_INDIRECT_RENDERING */ + + static struct display_dispatch *DispatchList = NULL; @@ -1173,6 +1204,9 @@ _glxapi_get_extensions(void) #ifdef GLX_EXT_texture_from_pixmap "GLX_EXT_texture_from_pixmap", #endif +#ifdef GLX_INTEL_swap_event + "GLX_INTEL_swap_event", +#endif NULL }; return extensions; diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index bf767bcedd..1a5456e1be 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -375,7 +375,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->type = type; b->cmap = cmap; - _mesa_initialize_framebuffer(&b->mesa_buffer, &vis->mesa_visual); + _mesa_initialize_window_framebuffer(&b->mesa_buffer, &vis->mesa_visual); b->mesa_buffer.Delete = xmesa_delete_framebuffer; /* diff --git a/src/mesa/es/.gitignore b/src/mesa/es/.gitignore new file mode 100644 index 0000000000..7643e9f0db --- /dev/null +++ b/src/mesa/es/.gitignore @@ -0,0 +1,5 @@ +glapi/glapi-es* +glapi/glapi-stamp +main/get_es*.c +main/api_exec_es*.c +objs-es* diff --git a/src/mesa/es/Makefile b/src/mesa/es/Makefile new file mode 100644 index 0000000000..fbe67445c9 --- /dev/null +++ b/src/mesa/es/Makefile @@ -0,0 +1,141 @@ +# src/mesa/es/Makefile +# +TOP := ../../.. +MESA := .. + +include $(TOP)/configs/current +include sources.mak + +ES1_LIBS := libes1gallium.a libes1api.a +ES2_LIBS := libes2gallium.a libes2api.a + +# Default rule: create ES1 and ES2 libs +.PHONY: default es1 es2 +default: depend es1 es2 + +es1: $(ES1_LIBS) + @rm -f subdirs-stamp-tmp + +es2: $(ES2_LIBS) + @rm -f subdirs-stamp-tmp + +# force the inclusion of es's mfeatures.h +ES1_CPPFLAGS := -include main/mfeatures_es1.h -D__GL_EXPORTS +ES2_CPPFLAGS := -include main/mfeatures_es2.h -D__GL_EXPORTS + +ES1_OBJ_DIR := objs-es1 +ES2_OBJ_DIR := objs-es2 + +# adjust output dirs +ES1_OBJECTS := $(addprefix $(ES1_OBJ_DIR)/, $(ES1_OBJECTS)) +ES1_GALLIUM_OBJECTS := $(addprefix $(ES1_OBJ_DIR)/, $(ES1_GALLIUM_OBJECTS)) +ES1_API_OBJECTS := $(addprefix $(ES1_OBJ_DIR)/, $(ES1_API_OBJECTS)) + +ES2_OBJECTS := $(addprefix $(ES2_OBJ_DIR)/, $(ES2_OBJECTS)) +ES2_GALLIUM_OBJECTS := $(addprefix $(ES2_OBJ_DIR)/, $(ES2_GALLIUM_OBJECTS)) +ES2_API_OBJECTS := $(addprefix $(ES2_OBJ_DIR)/, $(ES2_API_OBJECTS)) + +# compile either ES1 or ES2 sources +define es-compile + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) $(ES$(1)_CPPFLAGS) $(ES$(1)_INCLUDES) -o $@ $< +endef + +$(ES1_OBJ_DIR)/%.o: %.c + $(call es-compile,1) + +$(ES1_OBJ_DIR)/%.o: %.S + $(call es-compile,1) + +$(ES1_OBJ_DIR)/%.o: $(MESA)/%.c + $(call es-compile,1) + +$(ES1_OBJ_DIR)/%.o: $(MESA)/%.S + $(call es-compile,1) + +$(ES2_OBJ_DIR)/%.o: %.c + $(call es-compile,2) + +$(ES2_OBJ_DIR)/%.o: %.S + $(call es-compile,2) + +$(ES2_OBJ_DIR)/%.o: $(MESA)/%.c + $(call es-compile,2) + +$(ES2_OBJ_DIR)/%.o: $(MESA)/%.S + $(call es-compile,2) + +libes1.a: $(ES1_OBJECTS) $(GLSL_LIBS) + @$(MKLIB) -o es1 -static $(ES1_OBJECTS) $(GLSL_LIBS) + +libes2.a: $(ES2_OBJECTS) $(GLSL_LIBS) + @$(MKLIB) -o es2 -static $(ES1_OBJECTS) $(GLSL_LIBS) + +libes1gallium.a: $(ES1_GALLIUM_OBJECTS) $(GLSL_LIBS) + @$(MKLIB) -o es1gallium -static $(ES1_GALLIUM_OBJECTS) $(GLSL_LIBS) + +libes2gallium.a: $(ES2_GALLIUM_OBJECTS) $(GLSL_LIBS) + @$(MKLIB) -o es2gallium -static $(ES2_GALLIUM_OBJECTS) $(GLSL_LIBS) + +libes1api.a: $(ES1_API_OBJECTS) + @$(MKLIB) -o es1api -static $(ES1_API_OBJECTS) + +libes2api.a: $(ES2_API_OBJECTS) + @$(MKLIB) -o es2api -static $(ES2_API_OBJECTS) + +GENERATED_SOURCES := \ + main/api_exec_es1.c \ + main/api_exec_es2.c \ + main/get_es1.c \ + main/get_es2.c + +main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@ + +main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@ + +main/get_es1.c: main/get_gen.py + $(PYTHON2) $(PYTHON_FLAGS) $< 1 > $@ + +main/get_es2.c: main/get_gen.py + $(PYTHON2) $(PYTHON_FLAGS) $< 2 > $@ + +.PHONY: clean +clean: + -rm -f $(ES1_LIBS) $(ES2_LIBS) + -rm -rf $(ES1_OBJ_DIR) $(ES2_OBJ_DIR) + -rm -f $(GENERATED_SOURCES) + -rm -f depend depend.bak + -rm -f subdirs-stamp-tmp + @$(MAKE) -C glapi clean + +# nothing to install +install: + +subdirs-stamp-tmp: + @$(MAKE) -C $(MESA) asm_subdirs + @$(MAKE) -C $(MESA) glsl_builtin + @$(MAKE) -C glapi + @touch subdirs-stamp-tmp + +# sort to avoid duplicates +ALL_SOURCES := $(sort $(ES1_ALL_SOURCES) $(ES2_ALL_SOURCES)) + +# need to make sure the subdirs are processed first +$(ALL_SOURCES): | subdirs-stamp-tmp + +depend: $(ALL_SOURCES) + @echo "running $(MKDEP)" + @touch depend + @# MESA is "..", but luckily, directories are longer than 2 characters + @$(MKDEP) -f- -p$(ES1_OBJ_DIR)/ $(DEFINES) $(ES1_CFLAGS) \ + $(ES1_INCLUDES) $(ES1_ALL_SOURCES) 2>/dev/null | \ + sed -e 's,^$(ES1_OBJ_DIR)/$(MESA)/,$(ES1_OBJ_DIR)/,' > depend + @$(MKDEP) -f- -p$(ES2_OBJ_DIR)/ $(DEFINES) $(ES2_CFLAGS) \ + $(ES2_INCLUDES) $(ES2_ALL_SOURCES) 2>/dev/null | \ + sed -e 's,^$(ES2_OBJ_DIR)/$(MESA)/,$(ES2_OBJ_DIR)/,' >> depend + +ifneq ($(MAKECMDGOALS),clean) +-include depend +endif diff --git a/src/mesa/es/glapi/Makefile b/src/mesa/es/glapi/Makefile new file mode 100644 index 0000000000..1e32af867d --- /dev/null +++ b/src/mesa/es/glapi/Makefile @@ -0,0 +1,90 @@ +TOP = ../../../.. +GLAPI = ../../glapi +include $(TOP)/configs/current + +OUTPUTS := \ + glapi/glapidispatch.h \ + glapi/glapioffsets.h \ + glapi/glapitable.h \ + glapi/glapitemp.h \ + glapi/glprocs.h \ + sparc/glapi_sparc.S \ + x86-64/glapi_x86-64.S \ + x86/glapi_x86.S \ + main/enums.c \ + main/remap_helper.h + +COMMON = gl_XML.py glX_XML.py license.py typeexpr.py +COMMON := $(addprefix $(GLAPI)/, $(COMMON)) + +ES1_APIXML := es1_API.xml +ES2_APIXML := es2_API.xml +ES1_OUTPUT_DIR := glapi-es1 +ES2_OUTPUT_DIR := glapi-es2 + +ES1_DEPS = $(ES1_APIXML) base1_API.xml es1_EXT.xml es_EXT.xml \ + es1_COMPAT.xml es_COMPAT.xml +ES2_DEPS = $(ES2_APIXML) base2_API.xml es2_EXT.xml es_EXT.xml \ + es2_COMPAT.xml es_COMPAT.xml + +ES1_OUTPUTS := $(addprefix $(ES1_OUTPUT_DIR)/, $(OUTPUTS)) +ES2_OUTPUTS := $(addprefix $(ES2_OUTPUT_DIR)/, $(OUTPUTS)) + +all: $(ES1_OUTPUTS) $(ES2_OUTPUTS) + +$(ES1_OUTPUTS): APIXML := $(ES1_APIXML) +$(ES2_OUTPUTS): APIXML := $(ES2_APIXML) +$(ES1_OUTPUTS): $(ES1_DEPS) +$(ES2_OUTPUTS): $(ES2_DEPS) + +define gen-glapi + @mkdir -p $(dir $@) + $(PYTHON2) $(PYTHON_FLAGS) $< -f $(APIXML) $(1) > $@ +endef + +%/glapidispatch.h: $(GLAPI)/gl_table.py $(COMMON) + $(call gen-glapi,-c -m remap_table) + +%/glapioffsets.h: $(GLAPI)/gl_offsets.py $(COMMON) + $(call gen-glapi,-c) + +%/glapitable.h: $(GLAPI)/gl_table.py $(COMMON) + $(call gen-glapi,-c) + +%/glapitemp.h: $(GLAPI)/gl_apitemp.py $(COMMON) + $(call gen-glapi,-c) + +%/glprocs.h: $(GLAPI)/gl_procs.py $(COMMON) + $(call gen-glapi,-c) + +%/sparc/glapi_sparc.S: $(GLAPI)/gl_SPARC_asm.py $(COMMON) + $(call gen-glapi) + +%/x86-64/glapi_x86-64.S: $(GLAPI)/gl_x86-64_asm.py $(COMMON) + $(call gen-glapi) + +%/x86/glapi_x86.S: $(GLAPI)/gl_x86_asm.py $(COMMON) + $(call gen-glapi) + +%/main/enums.c: $(GLAPI)/gl_enums.py $(COMMON) + $(call gen-glapi) + +%/main/remap_helper.h: $(GLAPI)/remap_helper.py $(COMMON) + $(call gen-glapi) + +verify_xml: + @if [ ! -f gl.h ]; then \ + echo "Please copy gl.h and gl2.h to this directory"; \ + exit 1; \ + fi + @echo "Verifying that es1_API.xml covers OpenGL ES 1.1..." + @$(PYTHON2) $(PYTHON_FLAGS) gl_parse_header.py gl.h > tmp.xml + @$(PYTHON2) $(PYTHON_FLAGS) gl_compare.py difference tmp.xml es1_API.xml + @echo "Verifying that es2_API.xml covers OpenGL ES 2.0..." + @$(PYTHON2) $(PYTHON_FLAGS) gl_parse_header.py gl2.h > tmp.xml + @$(PYTHON2) $(PYTHON_FLAGS) gl_compare.py difference tmp.xml es2_API.xml + @rm -f tmp.xml + +clean: + -rm -rf $(ES1_OUTPUT_DIR) $(ES2_OUTPUT_DIR) + -rm -f *~ *.pyc *.pyo diff --git a/src/mesa/es/glapi/base1_API.xml b/src/mesa/es/glapi/base1_API.xml new file mode 100644 index 0000000000..f5d136ccef --- /dev/null +++ b/src/mesa/es/glapi/base1_API.xml @@ -0,0 +1,744 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL and OpenGL ES 1.x APIs + This file defines the base categories that can be shared by all APIs. + They are defined in an incremental fashion. +--> + +<OpenGLAPI> + +<!-- base subset of OpenGL 1.0 --> +<category name="base1.0"> + <enum name="FALSE" value="0x0"/> + <enum name="TRUE" value="0x1"/> + <enum name="ZERO" value="0x0"/> + <enum name="ONE" value="0x1"/> + <enum name="NO_ERROR" value="0x0"/> + + <enum name="POINTS" value="0x0000"/> + <enum name="LINES" value="0x0001"/> + <enum name="LINE_LOOP" value="0x0002"/> + <enum name="LINE_STRIP" value="0x0003"/> + <enum name="TRIANGLES" value="0x0004"/> + <enum name="TRIANGLE_STRIP" value="0x0005"/> + <enum name="TRIANGLE_FAN" value="0x0006"/> + <enum name="NEVER" value="0x0200"/> + <enum name="LESS" value="0x0201"/> + <enum name="EQUAL" value="0x0202"/> + <enum name="LEQUAL" value="0x0203"/> + <enum name="GREATER" value="0x0204"/> + <enum name="NOTEQUAL" value="0x0205"/> + <enum name="GEQUAL" value="0x0206"/> + <enum name="ALWAYS" value="0x0207"/> + <enum name="SRC_COLOR" value="0x0300"/> + <enum name="ONE_MINUS_SRC_COLOR" value="0x0301"/> + <enum name="SRC_ALPHA" value="0x0302"/> + <enum name="ONE_MINUS_SRC_ALPHA" value="0x0303"/> + <enum name="DST_ALPHA" value="0x0304"/> + <enum name="ONE_MINUS_DST_ALPHA" value="0x0305"/> + <enum name="DST_COLOR" value="0x0306"/> + <enum name="ONE_MINUS_DST_COLOR" value="0x0307"/> + <enum name="SRC_ALPHA_SATURATE" value="0x0308"/> + <enum name="FRONT" value="0x0404"/> + <enum name="BACK" value="0x0405"/> + <enum name="FRONT_AND_BACK" value="0x0408"/> + <enum name="INVALID_ENUM" value="0x0500"/> + <enum name="INVALID_VALUE" value="0x0501"/> + <enum name="INVALID_OPERATION" value="0x0502"/> + <enum name="OUT_OF_MEMORY" value="0x0505"/> + <enum name="CW" value="0x0900"/> + <enum name="CCW" value="0x0901"/> + <enum name="CULL_FACE" count="1" value="0x0B44"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_TEST" count="1" value="0x0B71"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_TEST" count="1" value="0x0B90"> + <size name="Get" mode="get"/> + </enum> + <enum name="DITHER" count="1" value="0x0BD0"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND" count="1" value="0x0BE2"> + <size name="Get" mode="get"/> + </enum> + <enum name="SCISSOR_TEST" count="1" value="0x0C11"> + <size name="Get" mode="get"/> + </enum> + <enum name="UNPACK_ALIGNMENT" count="1" value="0x0CF5"> + <size name="Get" mode="get"/> + </enum> + <enum name="PACK_ALIGNMENT" count="1" value="0x0D05"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_TEXTURE_SIZE" count="1" value="0x0D33"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_VIEWPORT_DIMS" count="2" value="0x0D3A"> + <size name="Get" mode="get"/> + </enum> + <enum name="SUBPIXEL_BITS" count="1" value="0x0D50"> + <size name="Get" mode="get"/> + </enum> + <enum name="RED_BITS" count="1" value="0x0D52"> + <size name="Get" mode="get"/> + </enum> + <enum name="GREEN_BITS" count="1" value="0x0D53"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLUE_BITS" count="1" value="0x0D54"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALPHA_BITS" count="1" value="0x0D55"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_BITS" count="1" value="0x0D56"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_BITS" count="1" value="0x0D57"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_2D" count="1" value="0x0DE1"> + <size name="Get" mode="get"/> + </enum> + <enum name="DONT_CARE" value="0x1100"/> + <enum name="FASTEST" value="0x1101"/> + <enum name="NICEST" value="0x1102"/> + <enum name="BYTE" count="1" value="0x1400"> + <size name="CallLists"/> + </enum> + <enum name="UNSIGNED_BYTE" count="1" value="0x1401"> + <size name="CallLists"/> + </enum> + <enum name="SHORT" count="2" value="0x1402"> + <size name="CallLists"/> + </enum> + <enum name="UNSIGNED_SHORT" count="2" value="0x1403"> + <size name="CallLists"/> + </enum> + <enum name="FLOAT" count="4" value="0x1406"> + <size name="CallLists"/> + </enum> + <enum name="INVERT" value="0x150A"/> + <enum name="TEXTURE" value="0x1702"/> + <enum name="ALPHA" value="0x1906"/> + <enum name="RGB" value="0x1907"/> + <enum name="RGBA" value="0x1908"/> + <enum name="LUMINANCE" value="0x1909"/> + <enum name="LUMINANCE_ALPHA" value="0x190A"/> + <enum name="KEEP" value="0x1E00"/> + <enum name="REPLACE" value="0x1E01"/> + <enum name="INCR" value="0x1E02"/> + <enum name="DECR" value="0x1E03"/> + <enum name="VENDOR" value="0x1F00"/> + <enum name="RENDERER" value="0x1F01"/> + <enum name="VERSION" value="0x1F02"/> + <enum name="EXTENSIONS" value="0x1F03"/> + <enum name="NEAREST" value="0x2600"/> + <enum name="LINEAR" value="0x2601"/> + <enum name="NEAREST_MIPMAP_NEAREST" value="0x2700"/> + <enum name="LINEAR_MIPMAP_NEAREST" value="0x2701"/> + <enum name="NEAREST_MIPMAP_LINEAR" value="0x2702"/> + <enum name="LINEAR_MIPMAP_LINEAR" value="0x2703"/> + <enum name="TEXTURE_MAG_FILTER" count="1" value="0x2800"> + <size name="TexParameterfv"/> + <size name="TexParameteriv"/> + <size name="GetTexParameterfv" mode="get"/> + <size name="GetTexParameteriv" mode="get"/> + </enum> + <enum name="TEXTURE_MIN_FILTER" count="1" value="0x2801"> + <size name="TexParameterfv"/> + <size name="TexParameteriv"/> + <size name="GetTexParameterfv" mode="get"/> + <size name="GetTexParameteriv" mode="get"/> + </enum> + <enum name="TEXTURE_WRAP_S" count="1" value="0x2802"> + <size name="TexParameterfv"/> + <size name="TexParameteriv"/> + <size name="GetTexParameterfv" mode="get"/> + <size name="GetTexParameteriv" mode="get"/> + </enum> + <enum name="TEXTURE_WRAP_T" count="1" value="0x2803"> + <size name="TexParameterfv"/> + <size name="TexParameteriv"/> + <size name="GetTexParameterfv" mode="get"/> + <size name="GetTexParameteriv" mode="get"/> + </enum> + <enum name="REPEAT" value="0x2901"/> + + <enum name="DEPTH_BUFFER_BIT" value="0x00000100"/> + <enum name="STENCIL_BUFFER_BIT" value="0x00000400"/> + <enum name="COLOR_BUFFER_BIT" value="0x00004000"/> + + <type name="float" size="4" float="true" glx_name="FLOAT32"/> + <type name="clampf" size="4" float="true" glx_name="FLOAT32"/> + + <type name="int" size="4" glx_name="CARD32"/> + <type name="uint" size="4" unsigned="true" glx_name="CARD32"/> + <type name="sizei" size="4" glx_name="CARD32"/> + <type name="enum" size="4" unsigned="true" glx_name="ENUM"/> + <type name="bitfield" size="4" unsigned="true" glx_name="CARD32"/> + + <type name="short" size="2" glx_name="CARD16"/> + <type name="ushort" size="2" unsigned="true" glx_name="CARD16"/> + + <type name="byte" size="1" glx_name="CARD8"/> + <type name="ubyte" size="1" unsigned="true" glx_name="CARD8"/> + <type name="boolean" size="1" unsigned="true" glx_name="CARD8"/> + + <type name="void" size="1"/> + + <function name="BlendFunc" offset="241"> + <param name="sfactor" type="GLenum"/> + <param name="dfactor" type="GLenum"/> + <glx rop="160"/> + </function> + + <function name="Clear" offset="203"> + <param name="mask" type="GLbitfield"/> + <glx rop="127"/> + </function> + + <function name="ClearColor" offset="206"> + <param name="red" type="GLclampf"/> + <param name="green" type="GLclampf"/> + <param name="blue" type="GLclampf"/> + <param name="alpha" type="GLclampf"/> + <glx rop="130"/> + </function> + + <function name="ClearStencil" offset="207"> + <param name="s" type="GLint"/> + <glx rop="131"/> + </function> + + <function name="ColorMask" offset="210"> + <param name="red" type="GLboolean"/> + <param name="green" type="GLboolean"/> + <param name="blue" type="GLboolean"/> + <param name="alpha" type="GLboolean"/> + <glx rop="134"/> + </function> + + <function name="CullFace" offset="152"> + <param name="mode" type="GLenum"/> + <glx rop="79"/> + </function> + + <function name="DepthFunc" offset="245"> + <param name="func" type="GLenum"/> + <glx rop="164"/> + </function> + + <function name="DepthMask" offset="211"> + <param name="flag" type="GLboolean"/> + <glx rop="135"/> + </function> + + <function name="Disable" offset="214"> + <param name="cap" type="GLenum"/> + <glx rop="138" handcode="client"/> + </function> + + <function name="Enable" offset="215"> + <param name="cap" type="GLenum"/> + <glx rop="139" handcode="client"/> + </function> + + <function name="Finish" offset="216"> + <glx sop="108" handcode="true"/> + </function> + + <function name="Flush" offset="217"> + <glx sop="142" handcode="true"/> + </function> + + <function name="FrontFace" offset="157"> + <param name="mode" type="GLenum"/> + <glx rop="84"/> + </function> + + <function name="GetError" offset="261"> + <return type="GLenum"/> + <glx sop="115" handcode="client"/> + </function> + + <function name="GetIntegerv" offset="263"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="117" handcode="client"/> + </function> + + <function name="GetString" offset="275"> + <param name="name" type="GLenum"/> + <return type="const GLubyte *"/> + <glx sop="129" handcode="true"/> + </function> + + <function name="Hint" offset="158"> + <param name="target" type="GLenum"/> + <param name="mode" type="GLenum"/> + <glx rop="85"/> + </function> + + <function name="LineWidth" offset="168"> + <param name="width" type="GLfloat"/> + <glx rop="95"/> + </function> + + <function name="PixelStorei" offset="250"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx sop="110" handcode="client"/> + </function> + + <function name="ReadPixels" offset="256"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="GLvoid *" output="true" img_width="width" img_height="height" img_format="format" img_type="type" img_target="0"/> + <glx sop="111"/> + </function> + + <function name="Scissor" offset="176"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="103"/> + </function> + + <function name="StencilFunc" offset="243"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLint"/> + <param name="mask" type="GLuint"/> + <glx rop="162"/> + </function> + + <function name="StencilMask" offset="209"> + <param name="mask" type="GLuint"/> + <glx rop="133"/> + </function> + + <function name="StencilOp" offset="244"> + <param name="fail" type="GLenum"/> + <param name="zfail" type="GLenum"/> + <param name="zpass" type="GLenum"/> + <glx rop="163"/> + </function> + + <function name="TexParameterf" offset="178"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="105"/> + </function> + + <function name="Viewport" offset="305"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="191"/> + </function> + + <!-- these are not in OpenGL ES 1.0 --> + <enum name="LINE_WIDTH" count="1" value="0x0B21"> + <size name="Get" mode="get"/> + </enum> + <enum name="CULL_FACE_MODE" count="1" value="0x0B45"> + <size name="Get" mode="get"/> + </enum> + <enum name="FRONT_FACE" count="1" value="0x0B46"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_RANGE" count="2" value="0x0B70"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_WRITEMASK" count="1" value="0x0B72"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_CLEAR_VALUE" count="1" value="0x0B73"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_FUNC" count="1" value="0x0B74"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_CLEAR_VALUE" count="1" value="0x0B91"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_FUNC" count="1" value="0x0B92"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_VALUE_MASK" count="1" value="0x0B93"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_FAIL" count="1" value="0x0B94"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_PASS_DEPTH_FAIL" count="1" value="0x0B95"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_PASS_DEPTH_PASS" count="1" value="0x0B96"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_REF" count="1" value="0x0B97"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_WRITEMASK" count="1" value="0x0B98"> + <size name="Get" mode="get"/> + </enum> + <enum name="VIEWPORT" count="4" value="0x0BA2"> + <size name="Get" mode="get"/> + </enum> + <enum name="SCISSOR_BOX" count="4" value="0x0C10"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_CLEAR_VALUE" count="4" value="0x0C22"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_WRITEMASK" count="4" value="0x0C23"> + <size name="Get" mode="get"/> + </enum> + + <function name="TexParameterfv" offset="179"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="106"/> + </function> + + <function name="TexParameteri" offset="180"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="107"/> + </function> + + <function name="TexParameteriv" offset="181"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="108"/> + </function> + + <function name="GetBooleanv" offset="258"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLboolean *" output="true" variable_param="pname"/> + <glx sop="112" handcode="client"/> + </function> + + <function name="GetFloatv" offset="262"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="116" handcode="client"/> + </function> + + <function name="GetTexParameterfv" offset="282"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="136"/> + </function> + + <function name="GetTexParameteriv" offset="283"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="137"/> + </function> + + <function name="IsEnabled" offset="286"> + <param name="cap" type="GLenum"/> + <return type="GLboolean"/> + <glx sop="140" handcode="client"/> + </function> +</category> + +<!-- base subset of OpenGL 1.1 --> +<category name="base1.1"> + <enum name="POLYGON_OFFSET_FILL" value="0x8037"/> + + <function name="BindTexture" offset="307"> + <param name="target" type="GLenum"/> + <param name="texture" type="GLuint"/> + <glx rop="4117"/> + </function> + + <function name="CopyTexImage2D" offset="324"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <glx rop="4120"/> + </function> + + <function name="CopyTexSubImage2D" offset="326"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4122"/> + </function> + + <function name="DeleteTextures" offset="327"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="const GLuint *" count="n"/> + <glx sop="144"/> + </function> + + <function name="DrawArrays" offset="310"> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint"/> + <param name="count" type="GLsizei"/> + <glx rop="193" handcode="true"/> + </function> + + <function name="DrawElements" offset="311"> + <param name="mode" type="GLenum"/> + <param name="count" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="GenTextures" offset="328"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="GLuint *" output="true" count="n"/> + <glx sop="145" always_array="true"/> + </function> + + <function name="PolygonOffset" offset="319"> + <param name="factor" type="GLfloat"/> + <param name="units" type="GLfloat"/> + <glx rop="192"/> + </function> + + <function name="TexSubImage2D" offset="333"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_xoff="xoffset" img_yoff="yoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4100" large="true"/> + </function> + + <!-- these are not in OpenGL ES 1.0 --> + <enum name="POLYGON_OFFSET_UNITS" count="1" value="0x2A00"> + <size name="Get" mode="get"/> + </enum> + <enum name="POLYGON_OFFSET_FACTOR" count="1" value="0x8038"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_BINDING_2D" count="1" value="0x8069"> + <size name="Get" mode="get"/> + </enum> + + <function name="IsTexture" offset="330"> + <param name="texture" type="GLuint"/> + <return type="GLboolean"/> + <glx sop="146"/> + </function> +</category> + +<!-- base subset of OpenGL 1.2 --> +<category name="base1.2"> + <enum name="UNSIGNED_SHORT_4_4_4_4" value="0x8033"/> + <enum name="UNSIGNED_SHORT_5_5_5_1" value="0x8034"/> + <enum name="CLAMP_TO_EDGE" value="0x812F"/> + <enum name="UNSIGNED_SHORT_5_6_5" value="0x8363"/> + <enum name="ALIASED_POINT_SIZE_RANGE" count="2" value="0x846D"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALIASED_LINE_WIDTH_RANGE" count="2" value="0x846E"> + <size name="Get" mode="get"/> + </enum> +</category> + +<!-- base subset of OpenGL 1.3 --> +<category name="base1.3"> + <enum name="SAMPLE_ALPHA_TO_COVERAGE" count="1" value="0x809E"> + <size name="Get" mode="get"/> + </enum> + <enum name="SAMPLE_COVERAGE" count="1" value="0x80A0"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE0" value="0x84C0"/> + <enum name="TEXTURE1" value="0x84C1"/> + <enum name="TEXTURE2" value="0x84C2"/> + <enum name="TEXTURE3" value="0x84C3"/> + <enum name="TEXTURE4" value="0x84C4"/> + <enum name="TEXTURE5" value="0x84C5"/> + <enum name="TEXTURE6" value="0x84C6"/> + <enum name="TEXTURE7" value="0x84C7"/> + <enum name="TEXTURE8" value="0x84C8"/> + <enum name="TEXTURE9" value="0x84C9"/> + <enum name="TEXTURE10" value="0x84CA"/> + <enum name="TEXTURE11" value="0x84CB"/> + <enum name="TEXTURE12" value="0x84CC"/> + <enum name="TEXTURE13" value="0x84CD"/> + <enum name="TEXTURE14" value="0x84CE"/> + <enum name="TEXTURE15" value="0x84CF"/> + <enum name="TEXTURE16" value="0x84D0"/> + <enum name="TEXTURE17" value="0x84D1"/> + <enum name="TEXTURE18" value="0x84D2"/> + <enum name="TEXTURE19" value="0x84D3"/> + <enum name="TEXTURE20" value="0x84D4"/> + <enum name="TEXTURE21" value="0x84D5"/> + <enum name="TEXTURE22" value="0x84D6"/> + <enum name="TEXTURE23" value="0x84D7"/> + <enum name="TEXTURE24" value="0x84D8"/> + <enum name="TEXTURE25" value="0x84D9"/> + <enum name="TEXTURE26" value="0x84DA"/> + <enum name="TEXTURE27" value="0x84DB"/> + <enum name="TEXTURE28" value="0x84DC"/> + <enum name="TEXTURE29" value="0x84DD"/> + <enum name="TEXTURE30" value="0x84DE"/> + <enum name="TEXTURE31" value="0x84DF"/> + <enum name="NUM_COMPRESSED_TEXTURE_FORMATS" count="1" value="0x86A2"> + <size name="Get" mode="get"/> + </enum> + <enum name="COMPRESSED_TEXTURE_FORMATS" count="-1" value="0x86A3"> + <size name="Get" mode="get"/> + </enum> + + <function name="ActiveTexture" offset="374"> + <param name="texture" type="GLenum"/> + <glx rop="197"/> + </function> + + <function name="CompressedTexImage2D" offset="assign"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="imageSize" type="GLsizei" counter="true"/> + <param name="data" type="const GLvoid *" count="imageSize"/> + <glx rop="215" handcode="client"/> + </function> + + <function name="CompressedTexSubImage2D" offset="assign"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="imageSize" type="GLsizei" counter="true"/> + <param name="data" type="const GLvoid *" count="imageSize"/> + <glx rop="218" handcode="client"/> + </function> + + <function name="SampleCoverage" offset="assign"> + <param name="value" type="GLclampf"/> + <param name="invert" type="GLboolean"/> + <glx rop="229"/> + </function> + + <!-- these are not in OpenGL ES 1.0 --> + <enum name="SAMPLE_BUFFERS" count="1" value="0x80A8"> + <size name="Get" mode="get"/> + </enum> + <enum name="SAMPLES" count="1" value="0x80A9"> + <size name="Get" mode="get"/> + </enum> + <enum name="SAMPLE_COVERAGE_VALUE" count="1" value="0x80AA"> + <size name="Get" mode="get"/> + </enum> + <enum name="SAMPLE_COVERAGE_INVERT" count="1" value="0x80AB"> + <size name="Get" mode="get"/> + </enum> + <enum name="ACTIVE_TEXTURE" count="1" value="0x84E0"> + <size name="Get" mode="get"/> + </enum> +</category> + +<!-- base subset of OpenGL 1.4 --> +<category name="base1.4"> + <enum name="GENERATE_MIPMAP_HINT" value="0x8192"/> +</category> + +<!-- base subset of OpenGL 1.5 --> +<category name="base1.5"> + <enum name="BUFFER_SIZE" value="0x8764"/> + <enum name="BUFFER_USAGE" value="0x8765"/> + <enum name="ARRAY_BUFFER" value="0x8892"/> + <enum name="ELEMENT_ARRAY_BUFFER" value="0x8893"/> + <enum name="ARRAY_BUFFER_BINDING" value="0x8894"/> + <enum name="ELEMENT_ARRAY_BUFFER_BINDING" value="0x8895"/> + <enum name="STATIC_DRAW" value="0x88E4"/> + <enum name="DYNAMIC_DRAW" value="0x88E8"/> + + <type name="intptr" size="4" glx_name="CARD32"/> + <type name="sizeiptr" size="4" glx_name="CARD32"/> + + <function name="BindBuffer" offset="assign"> + <param name="target" type="GLenum"/> + <param name="buffer" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="BufferData" offset="assign"> + <param name="target" type="GLenum"/> + <param name="size" type="GLsizeiptr" counter="true"/> + <param name="data" type="const GLvoid *" count="size" img_null_flag="true"/> + <param name="usage" type="GLenum"/> + <glx ignore="true"/> + </function> + + <function name="BufferSubData" offset="assign"> + <param name="target" type="GLenum"/> + <param name="offset" type="GLintptr"/> + <param name="size" type="GLsizeiptr" counter="true"/> + <param name="data" type="const GLvoid *" count="size"/> + <glx ignore="true"/> + </function> + + <function name="DeleteBuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="buffer" type="const GLuint *" count="n"/> + <glx ignore="true"/> + </function> + + <function name="GenBuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="buffer" type="GLuint *" output="true" count="n"/> + <glx ignore="true"/> + </function> + + <function name="GetBufferParameteriv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx ignore="true"/> + </function> + + <function name="IsBuffer" offset="assign"> + <param name="buffer" type="GLuint"/> + <return type="GLboolean"/> + <glx ignore="true"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/base2_API.xml b/src/mesa/es/glapi/base2_API.xml new file mode 100644 index 0000000000..6aa43b728a --- /dev/null +++ b/src/mesa/es/glapi/base2_API.xml @@ -0,0 +1,533 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL and OpenGL ES 2.x APIs --> + +<OpenGLAPI> + +<xi:include href="base1_API.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- base subset of OpenGL 2.0 --> +<category name="base2.0"> + <enum name="BLEND_EQUATION_RGB" count="1" value="0x8009"> <!-- same as BLEND_EQUATION --> + <size name="Get" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_ENABLED" count="1" value="0x8622"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_SIZE" count="1" value="0x8623"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_STRIDE" count="1" value="0x8624"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_TYPE" count="1" value="0x8625"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="CURRENT_VERTEX_ATTRIB" count="1" value="0x8626"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_POINTER" value="0x8645"/> + <enum name="STENCIL_BACK_FUNC" count="1" value="0x8800"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_BACK_FAIL" count="1" value="0x8801"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_BACK_PASS_DEPTH_FAIL" count="1" value="0x8802"> + <size name="Get" mode="get"/> + </enum> + <enum name="STENCIL_BACK_PASS_DEPTH_PASS" count="1" value="0x8803"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_EQUATION_ALPHA" count="1" value="0x883D"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_VERTEX_ATTRIBS" count="1" value="0x8869"> + <size name="Get" mode="get"/> + </enum> + <enum name="VERTEX_ATTRIB_ARRAY_NORMALIZED" value="0x886A"/> + <enum name="MAX_TEXTURE_IMAGE_UNITS" count="1" value="0x8872"> + <size name="Get" mode="get"/> + </enum> + <enum name="FRAGMENT_SHADER" value="0x8B30"/> + <enum name="VERTEX_SHADER" value="0x8B31"/> + <enum name="MAX_VERTEX_TEXTURE_IMAGE_UNITS" value="0x8B4C"/> + <enum name="MAX_COMBINED_TEXTURE_IMAGE_UNITS" value="0x8B4D"/> + <enum name="SHADER_TYPE" value="0x8B4F"/> + <enum name="FLOAT_VEC2" value="0x8B50"/> + <enum name="FLOAT_VEC3" value="0x8B51"/> + <enum name="FLOAT_VEC4" value="0x8B52"/> + <enum name="INT_VEC2" value="0x8B53"/> + <enum name="INT_VEC3" value="0x8B54"/> + <enum name="INT_VEC4" value="0x8B55"/> + <enum name="BOOL" value="0x8B56"/> + <enum name="BOOL_VEC2" value="0x8B57"/> + <enum name="BOOL_VEC3" value="0x8B58"/> + <enum name="BOOL_VEC4" value="0x8B59"/> + <enum name="FLOAT_MAT2" value="0x8B5A"/> + <enum name="FLOAT_MAT3" value="0x8B5B"/> + <enum name="FLOAT_MAT4" value="0x8B5C"/> + <enum name="SAMPLER_2D" value="0x8B5E"/> + <enum name="SAMPLER_CUBE" value="0x8B60"/> + <enum name="DELETE_STATUS" value="0x8B80"/> + <enum name="COMPILE_STATUS" value="0x8B81"/> + <enum name="LINK_STATUS" value="0x8B82"/> + <enum name="VALIDATE_STATUS" value="0x8B83"/> + <enum name="INFO_LOG_LENGTH" value="0x8B84"/> + <enum name="ATTACHED_SHADERS" value="0x8B85"/> + <enum name="ACTIVE_UNIFORMS" value="0x8B86"/> + <enum name="ACTIVE_UNIFORM_MAX_LENGTH" value="0x8B87"/> + <enum name="SHADER_SOURCE_LENGTH" value="0x8B88"/> + <enum name="ACTIVE_ATTRIBUTES" value="0x8B89"/> + <enum name="ACTIVE_ATTRIBUTE_MAX_LENGTH" value="0x8B8A"/> + <enum name="SHADING_LANGUAGE_VERSION" value="0x8B8C"/> + <enum name="CURRENT_PROGRAM" value="0x8B8D"/> + <enum name="STENCIL_BACK_REF" value="0x8CA3"/> + <enum name="STENCIL_BACK_VALUE_MASK" value="0x8CA4"/> + <enum name="STENCIL_BACK_WRITEMASK" value="0x8CA5"/> + + <type name="char" size="1" glx_name="CARD8"/> + + <function name="AttachShader" offset="assign"> + <param name="program" type="GLuint"/> + <param name="shader" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="BindAttribLocation" offset="assign"> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="name" type="const GLchar *"/> + <glx ignore="true"/> + </function> + + <function name="BlendEquationSeparate" offset="assign"> + <param name="modeRGB" type="GLenum"/> + <param name="modeA" type="GLenum"/> + <glx rop="4228"/> + </function> + + <function name="CompileShader" offset="assign"> + <param name="shader" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="CreateProgram" offset="assign"> + <return type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="CreateShader" offset="assign"> + <param name="type" type="GLenum"/> + <return type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="DeleteProgram" offset="assign"> + <param name="program" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="DeleteShader" offset="assign"> + <param name="program" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="DetachShader" offset="assign"> + <param name="program" type="GLuint"/> + <param name="shader" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="DisableVertexAttribArray" offset="assign"> + <param name="index" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="EnableVertexAttribArray" offset="assign"> + <param name="index" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="GetActiveAttrib" offset="assign"> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="bufSize" type="GLsizei "/> + <param name="length" type="GLsizei *" output="true"/> + <param name="size" type="GLint *" output="true"/> + <param name="type" type="GLenum *" output="true"/> + <param name="name" type="GLchar *" output="true"/> + <glx ignore="true"/> + </function> + + <function name="GetActiveUniform" offset="assign"> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *" output="true"/> + <param name="size" type="GLint *" output="true"/> + <param name="type" type="GLenum *" output="true"/> + <param name="name" type="GLchar *" output="true"/> + <glx ignore="true"/> + </function> + + <function name="GetAttachedShaders" offset="assign"> + <param name="program" type="GLuint"/> + <param name="maxCount" type="GLsizei"/> + <param name="count" type="GLsizei *" output="true"/> + <param name="obj" type="GLuint *" output="true"/> + <glx ignore="true"/> + </function> + + <function name="GetAttribLocation" offset="assign"> + <param name="program" type="GLuint"/> + <param name="name" type="const GLchar *"/> + <return type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="GetProgramiv" offset="assign"> + <param name="program" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *"/> + <glx ignore="true"/> + </function> + + <function name="GetProgramInfoLog" offset="assign"> + <param name="program" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="infoLog" type="GLchar *"/> + <glx ignore="true"/> + </function> + + <function name="GetShaderiv" offset="assign"> + <param name="shader" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *"/> + <glx ignore="true"/> + </function> + + <function name="GetShaderInfoLog" offset="assign"> + <param name="shader" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="infoLog" type="GLchar *"/> + <glx ignore="true"/> + </function> + + <function name="GetShaderSource" offset="assign"> + <param name="shader" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *" output="true"/> + <param name="source" type="GLchar *" output="true"/> + <glx ignore="true"/> + </function> + + <function name="GetUniformfv" offset="assign"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="params" type="GLfloat *" output="true"/> + <glx ignore="true"/> + </function> + + <function name="GetUniformiv" offset="assign"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="params" type="GLint *"/> + <glx ignore="true"/> + </function> + + <function name="GetUniformLocation" offset="assign"> + <param name="program" type="GLuint"/> + <param name="name" type="const GLchar *"/> + <return type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="GetVertexAttribfv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx ignore="true"/> + </function> + + <function name="GetVertexAttribiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx ignore="true"/> + </function> + + <function name="GetVertexAttribPointerv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="pointer" type="GLvoid **" output="true"/> + <glx ignore="true"/> + </function> + + <function name="IsProgram" offset="assign"> + <param name="program" type="GLuint"/> + <return type="GLboolean"/> + <glx ignore="true"/> + </function> + + <function name="IsShader" offset="assign"> + <param name="shader" type="GLuint"/> + <return type="GLboolean"/> + <glx ignore="true"/> + </function> + + <function name="LinkProgram" offset="assign"> + <param name="program" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="ShaderSource" offset="assign"> + <param name="shader" type="GLuint"/> + <param name="count" type="GLsizei"/> + <param name="string" type="const GLchar **"/> + <param name="length" type="const GLint *"/> + <glx ignore="true"/> + </function> + + <function name="StencilFuncSeparate" offset="assign"> + <param name="face" type="GLenum"/> + <param name="func" type="GLenum"/> + <param name="ref" type="GLint"/> + <param name="mask" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="StencilOpSeparate" offset="assign"> + <param name="face" type="GLenum"/> + <param name="sfail" type="GLenum"/> + <param name="zfail" type="GLenum"/> + <param name="zpass" type="GLenum"/> + <glx ignore="true"/> + </function> + + <function name="StencilMaskSeparate" offset="assign"> + <param name="face" type="GLenum"/> + <param name="mask" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="Uniform1f" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLfloat"/> + <glx ignore="true"/> + </function> + + <function name="Uniform1fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform1i" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="Uniform1iv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform2f" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLfloat"/> + <param name="v1" type="GLfloat"/> + <glx ignore="true"/> + </function> + + <function name="Uniform2fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform2i" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLint"/> + <param name="v1" type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="Uniform2iv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform3f" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLfloat"/> + <param name="v1" type="GLfloat"/> + <param name="v2" type="GLfloat"/> + <glx ignore="true"/> + </function> + + <function name="Uniform3fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform3i" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLint"/> + <param name="v1" type="GLint"/> + <param name="v2" type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="Uniform3iv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform4f" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLfloat"/> + <param name="v1" type="GLfloat"/> + <param name="v2" type="GLfloat"/> + <param name="v3" type="GLfloat"/> + <glx ignore="true"/> + </function> + + <function name="Uniform4fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="Uniform4i" offset="assign"> + <param name="location" type="GLint"/> + <param name="v0" type="GLint"/> + <param name="v1" type="GLint"/> + <param name="v2" type="GLint"/> + <param name="v3" type="GLint"/> + <glx ignore="true"/> + </function> + + <function name="Uniform4iv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLint *"/> + <glx ignore="true"/> + </function> + + <function name="UniformMatrix2fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="transpose" type="GLboolean"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="UniformMatrix3fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="transpose" type="GLboolean"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="UniformMatrix4fv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="transpose" type="GLboolean"/> + <param name="value" type="const GLfloat *"/> + <glx ignore="true"/> + </function> + + <function name="UseProgram" offset="assign"> + <param name="program" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="ValidateProgram" offset="assign"> + <param name="program" type="GLuint"/> + <glx ignore="true"/> + </function> + + <function name="VertexAttrib1f" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLfloat"/> + </function> + + <function name="VertexAttrib1fv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLfloat *"/> + </function> + + <function name="VertexAttrib2f" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + </function> + + <function name="VertexAttrib2fv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLfloat *"/> + </function> + + <function name="VertexAttrib3f" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + </function> + + <function name="VertexAttrib3fv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLfloat *"/> + </function> + + <function name="VertexAttrib4f" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <param name="w" type="GLfloat"/> + </function> + + <function name="VertexAttrib4fv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLfloat *"/> + </function> + + <function name="VertexAttribPointer" offset="assign"> + <param name="index" type="GLuint"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="normalized" type="GLboolean"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es1_API.xml b/src/mesa/es/glapi/es1_API.xml new file mode 100644 index 0000000000..7ee5515f19 --- /dev/null +++ b/src/mesa/es/glapi/es1_API.xml @@ -0,0 +1,1100 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL ES 1.x API --> + +<OpenGLAPI> + +<xi:include href="base1_API.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- core subset of OpenGL 1.3 defined in OpenGL ES 1.0 --> +<category name="core1.0"> + <!-- addition to base1.0 --> + <enum name="ADD" value="0x0104"/> + <enum name="STACK_OVERFLOW" value="0x0503"/> + <enum name="STACK_UNDERFLOW" value="0x0504"/> + <enum name="EXP" value="0x0800"/> + <enum name="EXP2" value="0x0801"/> + <enum name="POINT_SMOOTH" count="1" value="0x0B10"> + <size name="Get" mode="get"/> + </enum> + <enum name="LINE_SMOOTH" count="1" value="0x0B20"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHTING" count="1" value="0x0B50"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT_MODEL_TWO_SIDE" count="1" value="0x0B52"> + <size name="LightModelfv"/> + <size name="LightModeliv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT_MODEL_AMBIENT" count="4" value="0x0B53"> + <size name="LightModelfv"/> + <size name="LightModeliv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_MATERIAL" count="1" value="0x0B57"> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG" count="1" value="0x0B60"> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_DENSITY" count="1" value="0x0B62"> + <size name="Fogfv"/> + <size name="Fogiv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_START" count="1" value="0x0B63"> + <size name="Fogfv"/> + <size name="Fogiv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_END" count="1" value="0x0B64"> + <size name="Fogfv"/> + <size name="Fogiv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_MODE" count="1" value="0x0B65"> + <size name="Fogfv"/> + <size name="Fogiv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_COLOR" count="4" value="0x0B66"> + <size name="Fogfv"/> + <size name="Fogiv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="NORMALIZE" count="1" value="0x0BA1"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALPHA_TEST" count="1" value="0x0BC0"> + <size name="Get" mode="get"/> + </enum> + <enum name="PERSPECTIVE_CORRECTION_HINT" count="1" value="0x0C50"> + <size name="Get" mode="get"/> + </enum> + <enum name="POINT_SMOOTH_HINT" count="1" value="0x0C51"> + <size name="Get" mode="get"/> + </enum> + <enum name="LINE_SMOOTH_HINT" count="1" value="0x0C52"> + <size name="Get" mode="get"/> + </enum> + <enum name="POLYGON_SMOOTH_HINT" count="1" value="0x0C53"> + <size name="Get" mode="get"/> + </enum> + <enum name="FOG_HINT" count="1" value="0x0C54"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_LIGHTS" count="1" value="0x0D31"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_MODELVIEW_STACK_DEPTH" count="1" value="0x0D36"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_PROJECTION_STACK_DEPTH" count="1" value="0x0D38"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_TEXTURE_STACK_DEPTH" count="1" value="0x0D39"> + <size name="Get" mode="get"/> + </enum> + <enum name="AMBIENT" count="4" value="0x1200"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="DIFFUSE" count="4" value="0x1201"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="SPECULAR" count="4" value="0x1202"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="POSITION" count="4" value="0x1203"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="SPOT_DIRECTION" count="3" value="0x1204"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="SPOT_EXPONENT" count="1" value="0x1205"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="SPOT_CUTOFF" count="1" value="0x1206"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="CONSTANT_ATTENUATION" count="1" value="0x1207"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="LINEAR_ATTENUATION" count="1" value="0x1208"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="QUADRATIC_ATTENUATION" count="1" value="0x1209"> + <size name="Lightfv"/> + <size name="Lightiv"/> + <size name="GetLightfv" mode="get"/> + <size name="GetLightiv" mode="get"/> + </enum> + <enum name="CLEAR" value="0x1500"/> + <enum name="AND" value="0x1501"/> + <enum name="AND_REVERSE" value="0x1502"/> + <enum name="COPY" value="0x1503"/> + <enum name="AND_INVERTED" value="0x1504"/> + <enum name="NOOP" value="0x1505"/> + <enum name="XOR" value="0x1506"/> + <enum name="OR" value="0x1507"/> + <enum name="NOR" value="0x1508"/> + <enum name="EQUIV" value="0x1509"/> + <enum name="OR_REVERSE" value="0x150B"/> + <enum name="COPY_INVERTED" value="0x150C"/> + <enum name="OR_INVERTED" value="0x150D"/> + <enum name="NAND" value="0x150E"/> + <enum name="SET" value="0x150F"/> + <enum name="EMISSION" count="4" value="0x1600"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + </enum> + <enum name="SHININESS" count="1" value="0x1601"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + </enum> + <enum name="AMBIENT_AND_DIFFUSE" count="4" value="0x1602"> + <size name="Materialfv"/> + <size name="Materialiv"/> + <size name="GetMaterialfv" mode="get"/> + <size name="GetMaterialiv" mode="get"/> + </enum> + <enum name="MODELVIEW" value="0x1700"/> + <enum name="PROJECTION" value="0x1701"/> + <enum name="FLAT" value="0x1D00"/> + <enum name="SMOOTH" value="0x1D01"/> + <enum name="MODULATE" value="0x2100"/> + <enum name="DECAL" value="0x2101"/> + <enum name="TEXTURE_ENV_MODE" count="1" value="0x2200"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="TEXTURE_ENV_COLOR" count="4" value="0x2201"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="TEXTURE_ENV" value="0x2300"/> + <enum name="LIGHT0" count="1" value="0x4000"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT1" count="1" value="0x4001"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT2" count="1" value="0x4002"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT3" count="1" value="0x4003"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT4" count="1" value="0x4004"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT5" count="1" value="0x4005"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT6" count="1" value="0x4006"> + <size name="Get" mode="get"/> + </enum> + <enum name="LIGHT7" count="1" value="0x4007"> + <size name="Get" mode="get"/> + </enum> + + <function name="AlphaFunc" offset="240"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLclampf"/> + <glx rop="159"/> + </function> + + <function name="Color4f" offset="29" vectorequiv="Color4fv"> + <param name="red" type="GLfloat"/> + <param name="green" type="GLfloat"/> + <param name="blue" type="GLfloat"/> + <param name="alpha" type="GLfloat"/> + </function> + + <function name="Fogf" offset="153"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="80"/> + </function> + + <function name="Fogfv" offset="154"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="81"/> + </function> + + <function name="Lightf" offset="159"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="86"/> + </function> + + <function name="Lightfv" offset="160"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="87"/> + </function> + + <function name="LightModelf" offset="163"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="90"/> + </function> + + <function name="LightModelfv" offset="164"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="91"/> + </function> + + <function name="LoadIdentity" offset="290"> + <glx rop="176"/> + </function> + + <function name="LoadMatrixf" offset="291"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="177"/> + </function> + + <function name="LogicOp" offset="242"> + <param name="opcode" type="GLenum"/> + <glx rop="161"/> + </function> + + <function name="Materialf" offset="169"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="96"/> + </function> + + <function name="Materialfv" offset="170"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="97"/> + </function> + + <function name="MatrixMode" offset="293"> + <param name="mode" type="GLenum"/> + <glx rop="179"/> + </function> + + <function name="MultMatrixf" offset="294"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="180"/> + </function> + + <function name="Normal3f" offset="56" vectorequiv="Normal3fv"> + <param name="nx" type="GLfloat"/> + <param name="ny" type="GLfloat"/> + <param name="nz" type="GLfloat"/> + </function> + + <function name="PointSize" offset="173"> + <param name="size" type="GLfloat"/> + <glx rop="100"/> + </function> + + <function name="PopMatrix" offset="297"> + <glx rop="183"/> + </function> + + <function name="PushMatrix" offset="298"> + <glx rop="184"/> + </function> + + <function name="Rotatef" offset="300"> + <param name="angle" type="GLfloat"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="186"/> + </function> + + <function name="Scalef" offset="302"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="188"/> + </function> + + <function name="ShadeModel" offset="177"> + <param name="mode" type="GLenum"/> + <glx rop="104"/> + </function> + + <function name="TexEnvf" offset="184"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="111"/> + </function> + + <function name="TexEnvfv" offset="185"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="112"/> + </function> + + <function name="TexImage2D" offset="183"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/> + <glx rop="110" large="true"/> + </function> + + <function name="Translatef" offset="304"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="190"/> + </function> + + <!-- addition to base1.1 --> + <enum name="COLOR_LOGIC_OP" value="0x0BF2"/> + <enum name="VERTEX_ARRAY" count="1" value="0x8074"> + <size name="Get" mode="get"/> + </enum> + <enum name="NORMAL_ARRAY" count="1" value="0x8075"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_ARRAY" count="1" value="0x8076"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_COORD_ARRAY" count="1" value="0x8078"> + <size name="Get" mode="get"/> + </enum> + + <function name="ColorPointer" offset="308"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="DisableClientState" offset="309"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="EnableClientState" offset="313"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="NormalPointer" offset="318"> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="TexCoordPointer" offset="320"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="VertexPointer" offset="321"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <!-- addition to base1.2 --> + <enum name="SMOOTH_POINT_SIZE_RANGE" count="2" value="0x0B12"> + <size name="Get" mode="get"/> + </enum> + <enum name="SMOOTH_LINE_WIDTH_RANGE" count="2" value="0x0B22"> + <size name="Get" mode="get"/> + </enum> + <enum name="RESCALE_NORMAL" count="1" value="0x803A"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_ELEMENTS_VERTICES" count="1" value="0x80E8"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_ELEMENTS_INDICES" count="1" value="0x80E9"> + <size name="Get" mode="get"/> + </enum> + + <!-- addition to base1.3 --> + <enum name="MULTISAMPLE" count="1" value="0x809D"> + <size name="Get" mode="get"/> + </enum> + <enum name="SAMPLE_ALPHA_TO_ONE" count="1" value="0x809F"> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_TEXTURE_UNITS" count="1" value="0x84E2"> + <size name="Get" mode="get"/> + </enum> + + <function name="ClientActiveTexture" offset="375"> + <param name="texture" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="MultiTexCoord4f" offset="402" vectorequiv="MultiTexCoord4fv"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + <param name="q" type="GLfloat"/> + </function> +</category> + +<!-- core subset of OpenGL 1.5 defined in OpenGL ES 1.1 --> +<category name="core1.1"> + <!-- addition to base1.0 --> + <enum name="CURRENT_COLOR" count="4" value="0x0B00"> + <size name="Get" mode="get"/> + </enum> + <enum name="CURRENT_NORMAL" count="3" value="0x0B02"> + <size name="Get" mode="get"/> + </enum> + <enum name="CURRENT_TEXTURE_COORDS" count="4" value="0x0B03"> + <size name="Get" mode="get"/> + </enum> + <enum name="POINT_SIZE" count="1" value="0x0B11"> + <size name="Get" mode="get"/> + </enum> + <enum name="SHADE_MODEL" count="1" value="0x0B54"> + <size name="Get" mode="get"/> + </enum> + <enum name="MATRIX_MODE" count="1" value="0x0BA0"> + <size name="Get" mode="get"/> + </enum> + <enum name="MODELVIEW_STACK_DEPTH" count="1" value="0x0BA3"> + <size name="Get" mode="get"/> + </enum> + <enum name="PROJECTION_STACK_DEPTH" count="1" value="0x0BA4"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_STACK_DEPTH" count="1" value="0x0BA5"> + <size name="Get" mode="get"/> + </enum> + <enum name="MODELVIEW_MATRIX" count="16" value="0x0BA6"> + <size name="Get" mode="get"/> + </enum> + <enum name="PROJECTION_MATRIX" count="16" value="0x0BA7"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_MATRIX" count="16" value="0x0BA8"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALPHA_TEST_FUNC" count="1" value="0x0BC1"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALPHA_TEST_REF" count="1" value="0x0BC2"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_DST" count="1" value="0x0BE0"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_SRC" count="1" value="0x0BE1"> + <size name="Get" mode="get"/> + </enum> + <enum name="LOGIC_OP_MODE" count="1" value="0x0BF0"> + <size name="Get" mode="get"/> + </enum> + <enum name="ALPHA_SCALE" count="1" value="0x0D1C"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + <size name="Get" mode="get"/> + </enum> + <enum name="MAX_CLIP_PLANES" count="1" value="0x0D32"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE0" count="1" value="0x3000"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE1" count="1" value="0x3001"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE2" count="1" value="0x3002"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE3" count="1" value="0x3003"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE4" count="1" value="0x3004"> + <size name="Get" mode="get"/> + </enum> + <enum name="CLIP_PLANE5" count="1" value="0x3005"> + <size name="Get" mode="get"/> + </enum> + + <function name="Color4ub" offset="35" vectorequiv="Color4ubv"> + <param name="red" type="GLubyte"/> + <param name="green" type="GLubyte"/> + <param name="blue" type="GLubyte"/> + <param name="alpha" type="GLubyte"/> + </function> + + <function name="GetLightfv" offset="264"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="118"/> + </function> + + <function name="GetMaterialfv" offset="269"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="123"/> + </function> + + <function name="GetTexEnvfv" offset="276"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="130"/> + </function> + + <function name="GetTexEnviv" offset="277"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="131"/> + </function> + + <function name="TexEnvi" offset="186"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="113"/> + </function> + + <function name="TexEnviv" offset="187"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="114"/> + </function> + + <!-- addition to base1.1 --> + <enum name="VERTEX_ARRAY_SIZE" count="1" value="0x807A"> + <size name="Get" mode="get"/> + </enum> + <enum name="VERTEX_ARRAY_TYPE" count="1" value="0x807B"> + <size name="Get" mode="get"/> + </enum> + <enum name="VERTEX_ARRAY_STRIDE" count="1" value="0x807C"> + <size name="Get" mode="get"/> + </enum> + <enum name="NORMAL_ARRAY_TYPE" count="1" value="0x807E"> + <size name="Get" mode="get"/> + </enum> + <enum name="NORMAL_ARRAY_STRIDE" count="1" value="0x807F"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_ARRAY_SIZE" count="1" value="0x8081"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_ARRAY_TYPE" count="1" value="0x8082"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_ARRAY_STRIDE" count="1" value="0x8083"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_COORD_ARRAY_SIZE" count="1" value="0x8088"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_COORD_ARRAY_TYPE" count="1" value="0x8089"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_COORD_ARRAY_STRIDE" count="1" value="0x808A"> + <size name="Get" mode="get"/> + </enum> + <enum name="VERTEX_ARRAY_POINTER" value="0x808E"/> + <enum name="NORMAL_ARRAY_POINTER" value="0x808F"/> + <enum name="COLOR_ARRAY_POINTER" value="0x8090"/> + <enum name="TEXTURE_COORD_ARRAY_POINTER" value="0x8092"/> + + <function name="GetPointerv" offset="329"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLvoid **" output="true"/> + <glx handcode="true"/> + </function> + + <!-- addition to base1.2 --> + + <!-- addition to base1.3 --> + <enum name="CLIENT_ACTIVE_TEXTURE" count="1" value="0x84E1"> + <size name="Get" mode="get"/> + </enum> + <enum name="SUBTRACT" value="0x84E7"/> + <enum name="COMBINE" value="0x8570"/> + <enum name="COMBINE_RGB" count="1" value="0x8571"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="COMBINE_ALPHA" count="1" value="0x8572"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="RGB_SCALE" count="1" value="0x8573"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="ADD_SIGNED" value="0x8574"/> + <enum name="INTERPOLATE" value="0x8575"/> + <enum name="CONSTANT" value="0x8576"/> + <enum name="PRIMARY_COLOR" value="0x8577"/> + <enum name="PREVIOUS" value="0x8578"/> + <enum name="OPERAND0_RGB" count="1" value="0x8590"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="OPERAND1_RGB" count="1" value="0x8591"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="OPERAND2_RGB" count="1" value="0x8592"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="OPERAND0_ALPHA" count="1" value="0x8598"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="OPERAND1_ALPHA" count="1" value="0x8599"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="OPERAND2_ALPHA" count="1" value="0x859A"> + <size name="TexEnvfv"/> + <size name="TexEnviv"/> + <size name="GetTexEnvfv" mode="get"/> + <size name="GetTexEnviv" mode="get"/> + </enum> + <enum name="DOT3_RGB" value="0x86AE"/> + <enum name="DOT3_RGBA" value="0x86AF"/> + + <!-- addition to base1.4 --> + <enum name="POINT_SIZE_MIN" count="1" value="0x8126"> + <size name="PointParameterfv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="POINT_SIZE_MAX" count="1" value="0x8127"> + <size name="PointParameterfv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="POINT_FADE_THRESHOLD_SIZE" count="1" value="0x8128"> + <size name="PointParameterfv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="POINT_DISTANCE_ATTENUATION" count="3" value="0x8129"> + <size name="PointParameterfv"/> + <size name="Get" mode="get"/> + </enum> + <enum name="GENERATE_MIPMAP" count="1" value="0x8191"> + <size name="TexParameterfv"/> + <size name="TexParameteriv"/> + <size name="GetTexParameterfv" mode="get"/> + <size name="GetTexParameteriv" mode="get"/> + </enum> + + <function name="PointParameterf" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="2065"/> + </function> + + <function name="PointParameterfv" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="2066"/> + </function> + + <!-- addition to base1.5 --> + <enum name="SRC0_RGB" value="0x8580"/> + <enum name="SRC1_RGB" value="0x8581"/> + <enum name="SRC2_RGB" value="0x8582"/> + <enum name="SRC0_ALPHA" value="0x8588"/> + <enum name="SRC1_ALPHA" value="0x8589"/> + <enum name="SRC2_ALPHA" value="0x858A"/> + <enum name="VERTEX_ARRAY_BUFFER_BINDING" count="1" value="0x8896"> + <size name="Get" mode="get"/> + </enum> + <enum name="NORMAL_ARRAY_BUFFER_BINDING" count="1" value="0x8897"> + <size name="Get" mode="get"/> + </enum> + <enum name="COLOR_ARRAY_BUFFER_BINDING" count="1" value="0x8898"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_COORD_ARRAY_BUFFER_BINDING" count="1" value="0x889A"> + <size name="Get" mode="get"/> + </enum> +</category> + +<!-- OpenGL ES 1.0 --> +<category name="es1.0"> + <!-- addition to core1.0 --> + + <!-- from GL_OES_fixed_point --> + <enum name="FIXED" value="0x140C"/> + + <type name="fixed" size="4" /> + <type name="clampx" size="4" /> + + <function name="AlphaFuncx" offset="assign"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLclampx"/> + </function> + + <function name="ClearColorx" offset="assign"> + <param name="red" type="GLclampx"/> + <param name="green" type="GLclampx"/> + <param name="blue" type="GLclampx"/> + <param name="alpha" type="GLclampx"/> + </function> + + <function name="ClearDepthx" offset="assign"> + <param name="depth" type="GLclampx"/> + </function> + + <function name="Color4x" offset="assign"> + <param name="red" type="GLfixed"/> + <param name="green" type="GLfixed"/> + <param name="blue" type="GLfixed"/> + <param name="alpha" type="GLfixed"/> + </function> + + <function name="DepthRangex" offset="assign"> + <param name="zNear" type="GLclampx"/> + <param name="zFar" type="GLclampx"/> + </function> + + <function name="Fogx" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="Fogxv" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="Frustumx" offset="assign"> + <param name="left" type="GLfixed"/> + <param name="right" type="GLfixed"/> + <param name="bottom" type="GLfixed"/> + <param name="top" type="GLfixed"/> + <param name="zNear" type="GLfixed"/> + <param name="zFar" type="GLfixed"/> + </function> + + <function name="LightModelx" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="LightModelxv" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="Lightx" offset="assign"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="Lightxv" offset="assign"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="LineWidthx" offset="assign"> + <param name="width" type="GLfixed"/> + </function> + + <function name="LoadMatrixx" offset="assign"> + <param name="m" type="const GLfixed *" count="16"/> + </function> + + <function name="Materialx" offset="assign"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="Materialxv" offset="assign"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="MultMatrixx" offset="assign"> + <param name="m" type="const GLfixed *" count="16"/> + </function> + + <function name="MultiTexCoord4x" offset="assign"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfixed"/> + <param name="t" type="GLfixed"/> + <param name="r" type="GLfixed"/> + <param name="q" type="GLfixed"/> + </function> + + <function name="Normal3x" offset="assign"> + <param name="nx" type="GLfixed"/> + <param name="ny" type="GLfixed"/> + <param name="nz" type="GLfixed"/> + </function> + + <function name="Orthox" offset="assign"> + <param name="left" type="GLfixed"/> + <param name="right" type="GLfixed"/> + <param name="bottom" type="GLfixed"/> + <param name="top" type="GLfixed"/> + <param name="zNear" type="GLfixed"/> + <param name="zFar" type="GLfixed"/> + </function> + + <function name="PointSizex" offset="assign"> + <param name="size" type="GLfixed"/> + </function> + + <function name="PolygonOffsetx" offset="assign"> + <param name="factor" type="GLfixed"/> + <param name="units" type="GLfixed"/> + </function> + + <function name="Rotatex" offset="assign"> + <param name="angle" type="GLfixed"/> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <function name="SampleCoveragex" offset="assign"> + <param name="value" type="GLclampx"/> + <param name="invert" type="GLboolean"/> + </function> + + <function name="Scalex" offset="assign"> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <function name="TexEnvx" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="TexEnvxv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="TexParameterx" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="Translatex" offset="assign"> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <!-- from GL_OES_single_precision --> + <function name="ClearDepthf" offset="assign"> + <param name="depth" type="GLclampf"/> + </function> + + <function name="DepthRangef" offset="assign"> + <param name="zNear" type="GLclampf"/> + <param name="zFar" type="GLclampf"/> + </function> + + <function name="Frustumf" offset="assign"> + <param name="left" type="GLfloat"/> + <param name="right" type="GLfloat"/> + <param name="bottom" type="GLfloat"/> + <param name="top" type="GLfloat"/> + <param name="zNear" type="GLfloat"/> + <param name="zFar" type="GLfloat"/> + </function> + + <function name="Orthof" offset="assign"> + <param name="left" type="GLfloat"/> + <param name="right" type="GLfloat"/> + <param name="bottom" type="GLfloat"/> + <param name="top" type="GLfloat"/> + <param name="zNear" type="GLfloat"/> + <param name="zFar" type="GLfloat"/> + </function> +</category> + +<!-- OpenGL ES 1.1 --> +<category name="es1.1"> + <!-- addition to core1.1 --> + + <!-- from GL_OES_fixed_point --> + <function name="ClipPlanex" offset="assign"> + <param name="plane" type="GLenum"/> + <param name="equation" type="const GLfixed *" count="4"/> + </function> + + <function name="GetClipPlanex" offset="assign"> + <param name="plane" type="GLenum"/> + <param name="equation" type="GLfixed *" output="true" count="4"/> + </function> + + <function name="GetFixedv" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetLightxv" offset="assign"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetMaterialxv" offset="assign"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetTexEnvxv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetTexParameterxv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="PointParameterx" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="PointParameterxv" offset="assign"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *"/> + </function> + + <function name="TexParameterxv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <!-- from GL_OES_matrix_get --> + <enum name="MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898D"/> + <enum name="PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898E"/> + <enum name="TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898F"/> + + <!-- from GL_OES_single_precision --> + <function name="ClipPlanef" offset="assign"> + <param name="plane" type="GLenum"/> + <param name="equation" type="const GLfloat *" count="4"/> + </function> + + <function name="GetClipPlanef" offset="assign"> + <param name="plane" type="GLenum"/> + <param name="equation" type="GLfloat *" output="true" count="4"/> + </function> +</category> + +<xi:include href="es1_EXT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<xi:include href="es1_COMPAT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es1_COMPAT.xml b/src/mesa/es/glapi/es1_COMPAT.xml new file mode 100644 index 0000000000..4fc9223cc0 --- /dev/null +++ b/src/mesa/es/glapi/es1_COMPAT.xml @@ -0,0 +1,135 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<OpenGLAPI> + +<!-- This file defines the functions that are needed by Mesa. It + makes sure the generated glapi headers are compatible with Mesa. + It mainly consists of missing functions and aliases in OpenGL ES. +--> + +<xi:include href="es_COMPAT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- except for those defined by es_COMPAT.xml, these are also needed --> +<category name="compat"> + <!-- OpenGL 1.0 --> + <function name="TexGenf" alias="TexGenfOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="117"/> + </function> + + <function name="TexGenfv" alias="TexGenfvOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="118"/> + </function> + + <function name="TexGeni" alias="TexGeniOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="119"/> + </function> + + <function name="TexGeniv" alias="TexGenivOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="120"/> + </function> + + <function name="GetTexGenfv" alias="GetTexGenfvOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="133"/> + </function> + + <function name="GetTexGeniv" alias="GetTexGenivOES" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="134"/> + </function> + + <!-- OpenGL 1.2 --> + <function name="BlendColor" offset="336" static_dispatch="false"> + <param name="red" type="GLclampf"/> + <param name="green" type="GLclampf"/> + <param name="blue" type="GLclampf"/> + <param name="alpha" type="GLclampf"/> + <glx rop="4096"/> + </function> + + <function name="BlendEquation" alias="BlendEquationOES" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="4097"/> + </function> + + <function name="TexImage3D" offset="371" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/> + <glx rop="4114" large="true"/> + </function> + + <function name="TexSubImage3D" offset="372" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_xoff="xoffset" img_yoff="yoffset" img_zoff="zoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4115" large="true"/> + </function> + + <function name="CopyTexSubImage3D" offset="373" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4123"/> + </function> + + <!-- GL_ARB_multitexture --> + <function name="ActiveTextureARB" alias="ActiveTexture" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx rop="197"/> + </function> + + <function name="ClientActiveTextureARB" alias="ClientActiveTexture" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="MultiTexCoord4fARB" alias="MultiTexCoord4f" vectorequiv="MultiTexCoord4fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + <param name="q" type="GLfloat"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es1_EXT.xml b/src/mesa/es/glapi/es1_EXT.xml new file mode 100644 index 0000000000..de4868cfd4 --- /dev/null +++ b/src/mesa/es/glapi/es1_EXT.xml @@ -0,0 +1,699 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL ES 1.x extensions --> + +<OpenGLAPI> + +<xi:include href="es_EXT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- part of es1.1 extension pack --> +<category name="GL_OES_blend_equation_separate" number="1"> + <enum name="BLEND_EQUATION_RGB_OES" count="1" value="0x8009"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_EQUATION_ALPHA_OES" count="1" value="0x883D"> + <size name="Get" mode="get"/> + </enum> + + <function name="BlendEquationSeparateOES" offset="assign"> + <param name="modeRGB" type="GLenum"/> + <param name="modeA" type="GLenum"/> + <glx rop="4228"/> + </function> +</category> + +<!-- part of es1.1 extension pack --> +<category name="GL_OES_blend_func_separate" number="2"> + <enum name="BLEND_DST_RGB_OES" count="1" value="0x80C8"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_SRC_RGB_OES" count="1" value="0x80C9"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_DST_ALPHA_OES" count="1" value="0x80CA"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_SRC_ALPHA_OES" count="1" value="0x80CB"> + <size name="Get" mode="get"/> + </enum> + + <function name="BlendFuncSeparateOES" offset="assign"> + <param name="sfactorRGB" type="GLenum"/> + <param name="dfactorRGB" type="GLenum"/> + <param name="sfactorAlpha" type="GLenum"/> + <param name="dfactorAlpha" type="GLenum"/> + <glx rop="4134"/> + </function> +</category> + +<!-- part of es1.1 extension pack --> +<category name="GL_OES_blend_subtract" number="3"> + <enum name="FUNC_ADD_OES" value="0x8006"/> + <enum name="BLEND_EQUATION_OES" count="1" value="0x8009"> + <size name="Get" mode="get"/> + </enum> + <enum name="FUNC_SUBTRACT_OES" value="0x800A"/> + <enum name="FUNC_REVERSE_SUBTRACT_OES" value="0x800B"/> + + <function name="BlendEquationOES" offset="337"> + <param name="mode" type="GLenum"/> + <glx rop="4097"/> + </function> +</category> + +<!-- core addition to es1.0 and later --> +<category name="GL_OES_byte_coordinates" number="4"> + <enum name="BYTE" value="0x1400"/> +</category> + +<!-- optional for es1.1 --> +<category name="GL_OES_draw_texture" number="7"> + <enum name="TEXTURE_CROP_RECT_OES" value="0x8B9D"/> + + <function name="DrawTexiOES" offset="assign"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + <param name="width" type="GLint"/> + <param name="height" type="GLint"/> + </function> + + <function name="DrawTexivOES" offset="assign"> + <param name="coords" type="const GLint *" count="5"/> + </function> + + <function name="DrawTexfOES" offset="assign"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <param name="width" type="GLfloat"/> + <param name="height" type="GLfloat"/> + </function> + + <function name="DrawTexfvOES" offset="assign"> + <param name="coords" type="const GLfloat *" count="5"/> + </function> + + <function name="DrawTexsOES" offset="assign"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + <param name="z" type="GLshort"/> + <param name="width" type="GLshort"/> + <param name="height" type="GLshort"/> + </function> + + <function name="DrawTexsvOES" offset="assign"> + <param name="coords" type="const GLshort *" count="5"/> + </function> + + <function name="DrawTexxOES" offset="assign"> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + <param name="width" type="GLfixed"/> + <param name="height" type="GLfixed"/> + </function> + + <function name="DrawTexxvOES" offset="assign"> + <param name="coords" type="const GLfixed *" count="5"/> + </function> + + <!-- TexParameter{ifx}v is skipped here --> +</category> + +<!-- core addition to es1.0 and later --> +<category name="GL_OES_fixed_point" number="9"> + <enum name="FIXED_OES" value="0x140C"/> + + <!-- additon to es1.0 --> + <function name="AlphaFuncxOES" alias="AlphaFuncx"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLclampx"/> + </function> + + <function name="ClearColorxOES" alias="ClearColorx"> + <param name="red" type="GLclampx"/> + <param name="green" type="GLclampx"/> + <param name="blue" type="GLclampx"/> + <param name="alpha" type="GLclampx"/> + </function> + + <function name="ClearDepthxOES" alias="ClearDepthx"> + <param name="depth" type="GLclampx"/> + </function> + + <function name="Color4xOES" alias="Color4x"> + <param name="red" type="GLfixed"/> + <param name="green" type="GLfixed"/> + <param name="blue" type="GLfixed"/> + <param name="alpha" type="GLfixed"/> + </function> + + <function name="DepthRangexOES" alias="DepthRangex"> + <param name="zNear" type="GLclampx"/> + <param name="zFar" type="GLclampx"/> + </function> + + <function name="FogxOES" alias="Fogx"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="FogxvOES" alias="Fogxv"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="FrustumxOES" alias="Frustumx"> + <param name="left" type="GLfixed"/> + <param name="right" type="GLfixed"/> + <param name="bottom" type="GLfixed"/> + <param name="top" type="GLfixed"/> + <param name="zNear" type="GLfixed"/> + <param name="zFar" type="GLfixed"/> + </function> + + <function name="LightModelxOES" alias="LightModelx"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="LightModelxvOES" alias="LightModelxv"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="LightxOES" alias="Lightx"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="LightxvOES" alias="Lightxv"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="LineWidthxOES" alias="LineWidthx"> + <param name="width" type="GLfixed"/> + </function> + + <function name="LoadMatrixxOES" alias="LoadMatrixx"> + <param name="m" type="const GLfixed *" count="16"/> + </function> + + <function name="MaterialxOES" alias="Materialx"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="MaterialxvOES" alias="Materialxv"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="MultiTexCoord4xOES" alias="MultiTexCoord4x"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfixed"/> + <param name="t" type="GLfixed"/> + <param name="r" type="GLfixed"/> + <param name="q" type="GLfixed"/> + </function> + + <function name="MultMatrixxOES" alias="MultMatrixx"> + <param name="m" type="const GLfixed *" count="16"/> + </function> + + <function name="Normal3xOES" alias="Normal3x"> + <param name="nx" type="GLfixed"/> + <param name="ny" type="GLfixed"/> + <param name="nz" type="GLfixed"/> + </function> + + <function name="OrthoxOES" alias="Orthox"> + <param name="left" type="GLfixed"/> + <param name="right" type="GLfixed"/> + <param name="bottom" type="GLfixed"/> + <param name="top" type="GLfixed"/> + <param name="zNear" type="GLfixed"/> + <param name="zFar" type="GLfixed"/> + </function> + + <function name="PointSizexOES" alias="PointSizex"> + <param name="size" type="GLfixed"/> + </function> + + <function name="PolygonOffsetxOES" alias="PolygonOffsetx"> + <param name="factor" type="GLfixed"/> + <param name="units" type="GLfixed"/> + </function> + + <function name="RotatexOES" alias="Rotatex"> + <param name="angle" type="GLfixed"/> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <function name="SampleCoveragexOES" alias="SampleCoveragex"> + <param name="value" type="GLclampx"/> + <param name="invert" type="GLboolean"/> + </function> + + <function name="ScalexOES" alias="Scalex"> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <function name="TexEnvxOES" alias="TexEnvx"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="TexEnvxvOES" alias="TexEnvxv"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> + + <function name="TexParameterxOES" alias="TexParameterx"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="TranslatexOES" alias="Translatex"> + <param name="x" type="GLfixed"/> + <param name="y" type="GLfixed"/> + <param name="z" type="GLfixed"/> + </function> + + <!-- additon to es1.1 --> + <function name="ClipPlanexOES" alias="ClipPlanex"> + <param name="plane" type="GLenum"/> + <param name="equation" type="const GLfixed *" count="4"/> + </function> + + <function name="GetClipPlanexOES" alias="GetClipPlanex"> + <param name="plane" type="GLenum"/> + <param name="equation" type="GLfixed *" output="true" count="4"/> + </function> + + <function name="GetFixedvOES" alias="GetFixedv"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetLightxvOES" alias="GetLightxv"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetMaterialxvOES" alias="GetMaterialxv"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetTexEnvxvOES" alias="GetTexEnvxv"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="GetTexParameterxvOES" alias="GetTexParameterxv"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="PointParameterxOES" alias="PointParameterx"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfixed"/> + </function> + + <function name="PointParameterxvOES" alias="PointParameterxv"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *"/> + </function> + + <function name="TexParameterxvOES" alias="TexParameterxv"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> +</category> + +<!-- part of es1.1 extension pack --> +<category name="GL_OES_framebuffer_object" number="10"> + <enum name="NONE_OES" value="0"/> + <enum name="INVALID_FRAMEBUFFER_OPERATION_OES" value="0x0506"/> + <enum name="RGBA4_OES" value="0x8056"/> + <enum name="RGB5_A1_OES" value="0x8057"/> + <enum name="DEPTH_COMPONENT16_OES" value="0x81A5"/> + + <enum name="MAX_RENDERBUFFER_SIZE_OES" value="0x84E8"/> + <enum name="FRAMEBUFFER_BINDING_OES" value="0x8CA6"/> + <enum name="RENDERBUFFER_BINDING_OES" value="0x8CA7"/> + <enum name="FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES" value="0x8CD0"/> + <enum name="FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES" value="0x8CD1"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES" value="0x8CD2"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES" value="0x8CD3"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES" value="0x8CD4"/> + <enum name="FRAMEBUFFER_COMPLETE_OES" value="0x8CD5"/> + <enum name="FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES" value="0x8CD6"/> + <enum name="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES" value="0x8CD7"/> + <enum name="FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES" value="0x8CD9"/> + <enum name="FRAMEBUFFER_INCOMPLETE_FORMATS_OES" value="0x8CDA"/> + <enum name="FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES" value="0x8CDB"/> + <enum name="FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES" value="0x8CDC"/> + <enum name="FRAMEBUFFER_UNSUPPORTED_OES" value="0x8CDD"/> + <enum name="COLOR_ATTACHMENT0_OES" value="0x8CE0"/> + <enum name="DEPTH_ATTACHMENT_OES" value="0x8D00"/> + <enum name="STENCIL_ATTACHMENT_OES" value="0x8D20"/> + <enum name="FRAMEBUFFER_OES" value="0x8D40"/> + <enum name="RENDERBUFFER_OES" value="0x8D41"/> + <enum name="RENDERBUFFER_WIDTH_OES" value="0x8D42"/> + <enum name="RENDERBUFFER_HEIGHT_OES" value="0x8D43"/> + <enum name="RENDERBUFFER_INTERNAL_FORMAT_OES" value="0x8D44"/> + <enum name="STENCIL_INDEX1_OES" value="0x8D46"/> + <enum name="STENCIL_INDEX4_OES" value="0x8D47"/> + <enum name="STENCIL_INDEX8_OES" value="0x8D48"/> + <enum name="RENDERBUFFER_RED_SIZE_OES" value="0x8D50"/> + <enum name="RENDERBUFFER_GREEN_SIZE_OES" value="0x8D51"/> + <enum name="RENDERBUFFER_BLUE_SIZE_OES" value="0x8D52"/> + <enum name="RENDERBUFFER_ALPHA_SIZE_OES" value="0x8D53"/> + <enum name="RENDERBUFFER_DEPTH_SIZE_OES" value="0x8D54"/> + <enum name="RENDERBUFFER_STENCIL_SIZE_OES" value="0x8D55"/> + <enum name="RGB565_OES" value="0x8D62"/> + + <function name="BindFramebufferOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="framebuffer" type="GLuint"/> + </function> + + <function name="BindRenderbufferOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </function> + + <function name="CheckFramebufferStatusOES" offset="assign"> + <param name="target" type="GLenum"/> + <return type="GLenum"/> + </function> + + <function name="DeleteFramebuffersOES" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="framebuffers" type="const GLuint *" count="n"/> + </function> + + <function name="DeleteRenderbuffersOES" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="renderbuffers" type="const GLuint *" count="n"/> + </function> + + <function name="FramebufferRenderbufferOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="renderbuffertarget" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </function> + + <function name="FramebufferTexture2DOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="textarget" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + </function> + + <function name="GenerateMipmapOES" offset="assign"> + <param name="target" type="GLenum"/> + </function> + + <function name="GenFramebuffersOES" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="framebuffers" type="GLuint *" count="n" output="true"/> + </function> + + <function name="GenRenderbuffersOES" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="renderbuffers" type="GLuint *" count="n" output="true"/> + </function> + + <function name="GetFramebufferAttachmentParameterivOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true"/> + </function> + + <function name="GetRenderbufferParameterivOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true"/> + </function> + + <function name="IsFramebufferOES" offset="assign"> + <param name="framebuffer" type="GLuint"/> + <return type="GLboolean"/> + </function> + + <function name="IsRenderbufferOES" offset="assign"> + <param name="renderbuffer" type="GLuint"/> + <return type="GLboolean"/> + </function> + + <function name="RenderbufferStorageOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </function> +</category> + +<!-- core addition to es1.1 --> +<category name="GL_OES_matrix_get" number="11"> + <enum name="MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898D"/> + <enum name="PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898E"/> + <enum name="TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES" value="0x898F"/> +</category> + +<!-- optional for es1.1 --> +<category name="GL_OES_matrix_palette" number="12"> + <enum name="MAX_VERTEX_UNITS_OES" value="0x86A4"/> + <enum name="WEIGHT_ARRAY_TYPE_OES" value="0x86A9"/> + <enum name="WEIGHT_ARRAY_STRIDE_OES" value="0x86AA"/> + <enum name="WEIGHT_ARRAY_SIZE_OES" value="0x86AB"/> + <enum name="WEIGHT_ARRAY_POINTER_OES" value="0x86AC"/> + <enum name="WEIGHT_ARRAY_OES" value="0x86AD"/> + <enum name="MATRIX_PALETTE_OES" value="0x8840"/> + <enum name="MAX_PALETTE_MATRICES_OES" value="0x8842"/> + <enum name="CURRENT_PALETTE_MATRIX_OES" value="0x8843"/> + <enum name="MATRIX_INDEX_ARRAY_OES" value="0x8844"/> + <enum name="MATRIX_INDEX_ARRAY_SIZE_OES" value="0x8846"/> + <enum name="MATRIX_INDEX_ARRAY_TYPE_OES" value="0x8847"/> + <enum name="MATRIX_INDEX_ARRAY_STRIDE_OES" value="0x8848"/> + <enum name="MATRIX_INDEX_ARRAY_POINTER_OES" value="0x8849"/> + <enum name="WEIGHT_ARRAY_BUFFER_BINDING_OES" value="0x889E"/> + <enum name="MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES" value="0x8B9E"/> + + <function name="CurrentPaletteMatrixOES"> + <param name="matrixpaletteindex" type="GLuint"/> + </function> + + <function name="LoadPaletteFromModelViewMatrixOES"> + </function> + + <function name="MatrixIndexPointerOES"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> + + <function name="WeightPointerOES"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> +</category> + +<!-- required for es1.1 --> +<category name="GL_OES_point_size_array" number="14"> + <enum name="POINT_SIZE_ARRAY_TYPE_OES" value="0x898A"/> + <enum name="POINT_SIZE_ARRAY_STRIDE_OES" value="0x898B"/> + <enum name="POINT_SIZE_ARRAY_POINTER_OES" value="0x898C"/> + <enum name="POINT_SIZE_ARRAY_OES" value="0x8B9C"/> + <enum name="POINT_SIZE_ARRAY_BUFFER_BINDING_OES" value="0x8B9F"/> + + <function name="PointSizePointerOES" offset="assign"> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> +</category> + +<!-- required for es1.1 --> +<category name="GL_OES_point_sprite" number="15"> + <enum name="POINT_SPRITE_OES" value="0x8861"/> + <enum name="COORD_REPLACE_OES" value="0x8862"/> +</category> + +<!-- optional for es1.0 --> +<category name="GL_OES_query_matrix" number="16"> + <function name="QueryMatrixxOES" offset="assign"> + <param name="mantissa" type="GLfixed *" count="16" /> + <param name="exponent" type="GLint *" count="16" /> + <return type="GLbitfield"/> + </function> +</category> + +<!-- required for es1.0 and later --> +<category name="GL_OES_read_format" number="17"> + <enum name="IMPLEMENTATION_COLOR_READ_TYPE_OES" value="0x8B9A"/> + <enum name="IMPLEMENTATION_COLOR_READ_FORMAT_OES" value="0x8B9B"/> +</category> + +<!-- core addition to es1.0 and later --> +<category name="GL_OES_single_precision" number="18"> + <!-- additon to es1.0 --> + <function name="ClearDepthfOES" alias="ClearDepthf"> + <param name="depth" type="GLclampf"/> + </function> + + <function name="DepthRangefOES" alias="DepthRangef"> + <param name="zNear" type="GLclampf"/> + <param name="zFar" type="GLclampf"/> + </function> + + <function name="FrustumfOES" alias="Frustumf"> + <param name="left" type="GLfloat"/> + <param name="right" type="GLfloat"/> + <param name="bottom" type="GLfloat"/> + <param name="top" type="GLfloat"/> + <param name="zNear" type="GLfloat"/> + <param name="zFar" type="GLfloat"/> + </function> + + <function name="OrthofOES" alias="Orthof"> + <param name="left" type="GLfloat"/> + <param name="right" type="GLfloat"/> + <param name="bottom" type="GLfloat"/> + <param name="top" type="GLfloat"/> + <param name="zNear" type="GLfloat"/> + <param name="zFar" type="GLfloat"/> + </function> + + <!-- additon to es1.1 --> + <function name="ClipPlanefOES" alias="ClipPlanef"> + <param name="plane" type="GLenum"/> + <param name="equation" type="const GLfloat *" count="4"/> + </function> + + <function name="GetClipPlanefOES" alias="GetClipPlanef"> + <param name="plane" type="GLenum"/> + <param name="equation" type="GLfloat *" output="true" count="4"/> + </function> +</category> + +<!-- part of es1.1 extension pack --> +<category name="GL_OES_texture_cube_map" number="20"> + <enum name="TEXTURE_GEN_MODE_OES" value="0x2500"/> + <enum name="NORMAL_MAP_OES" value="0x8511"/> + <enum name="REFLECTION_MAP_OES" value="0x8512"/> + <enum name="TEXTURE_CUBE_MAP_OES" value="0x8513"/> + <enum name="TEXTURE_BINDING_CUBE_MAP_OES" value="0x8514"/> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_X_OES" value="0x8515"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_X_OES" value="0x8516"/> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_Y_OES" value="0x8517"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" value="0x8518"/> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_Z_OES" value="0x8519"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" value="0x851A"/> + <enum name="MAX_CUBE_MAP_TEXTURE_SIZE_OES" value="0x851C"/> + <enum name="TEXTURE_GEN_STR_OES" value="0x8D60"/> + + <function name="GetTexGenfvOES" offset="279"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="133"/> + </function> + + <function name="GetTexGenivOES" offset="280"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="134"/> + </function> + + <function name="GetTexGenxvOES" offset="assign"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfixed *" output="true" variable_param="pname"/> + </function> + + <function name="TexGenfOES" offset="190"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="117"/> + </function> + + <function name="TexGenfvOES" offset="191"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="118"/> + </function> + + <function name="TexGeniOES" offset="192"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="119"/> + </function> + + <function name="TexGenivOES" offset="193"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="120"/> + </function> + + <function name="TexGenxOES" offset="assign"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + </function> + + <function name="TexGenxvOES" offset="assign"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfixed *" variable_param="pname"/> + </function> +</category> + +<category name="GL_OES_texture_env_crossbar" number="21"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_OES_texture_mirrored_repeat" number="22"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_EXT_texture_lod_bias" number="60"> + <enum name="TEXTURE_FILTER_CONTROL_EXT" value="0x8500"/> + <enum name="TEXTURE_LOD_BIAS_EXT" value="0x8501"/> + <enum name="MAX_TEXTURE_LOD_BIAS_EXT" value="0x84FD"/> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es2_API.xml b/src/mesa/es/glapi/es2_API.xml new file mode 100644 index 0000000000..266c07613c --- /dev/null +++ b/src/mesa/es/glapi/es2_API.xml @@ -0,0 +1,294 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL ES 2.x API --> + +<OpenGLAPI> + +<xi:include href="base2_API.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- core subset of OpenGL 2.0 defined in OpenGL ES 2.0 --> +<category name="core2.0"> + <!-- addition to base1.0 --> + <enum name="NONE" value="0x0"/> + <enum name="INT" count="4" value="0x1404"> + <size name="CallLists"/> + </enum> + <enum name="UNSIGNED_INT" count="4" value="0x1405"> + <size name="CallLists"/> + </enum> + <enum name="STENCIL_INDEX" value="0x1901"/> + <enum name="DEPTH_COMPONENT" value="0x1902"/> + + <function name="TexImage2D" offset="183"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> <!-- XXX the actual type is GLenum... --> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/> + <glx rop="110" large="true"/> + </function> + + <!-- addition to base1.1 --> + <enum name="RGBA4" value="0x8056"/> + <enum name="RGB5_A1" value="0x8057"/> + + <!-- addition to base1.2 --> + <enum name="CONSTANT_COLOR" value="0x8001"/> + <enum name="ONE_MINUS_CONSTANT_COLOR" value="0x8002"/> + <enum name="CONSTANT_ALPHA" value="0x8003"/> + <enum name="ONE_MINUS_CONSTANT_ALPHA" value="0x8004"/> + <enum name="BLEND_COLOR" count="4" value="0x8005"> + <size name="Get" mode="get"/> + </enum> + <enum name="FUNC_ADD" value="0x8006"/> + <enum name="BLEND_EQUATION" count="1" value="0x8009"> + <size name="Get" mode="get"/> + </enum> + <enum name="FUNC_SUBTRACT" value="0x800A"/> + <enum name="FUNC_REVERSE_SUBTRACT" value="0x800B"/> + + <function name="BlendColor" offset="336"> + <param name="red" type="GLclampf"/> + <param name="green" type="GLclampf"/> + <param name="blue" type="GLclampf"/> + <param name="alpha" type="GLclampf"/> + <glx rop="4096"/> + </function> + + <function name="BlendEquation" offset="337"> + <param name="mode" type="GLenum"/> + <glx rop="4097"/> + </function> + + <!-- addition to base1.3 --> + <enum name="TEXTURE_CUBE_MAP" count="1" value="0x8513"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_BINDING_CUBE_MAP" count="1" value="0x8514"> + <size name="Get" mode="get"/> + </enum> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_X" value="0x8515"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_X" value="0x8516"/> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_Y" value="0x8517"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_Y" value="0x8518"/> + <enum name="TEXTURE_CUBE_MAP_POSITIVE_Z" value="0x8519"/> + <enum name="TEXTURE_CUBE_MAP_NEGATIVE_Z" value="0x851A"/> + <enum name="MAX_CUBE_MAP_TEXTURE_SIZE" count="1" value="0x851C"> + <size name="Get" mode="get"/> + </enum> + + <!-- addition to base1.4 --> + <enum name="BLEND_DST_RGB" count="1" value="0x80C8"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_SRC_RGB" count="1" value="0x80C9"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_DST_ALPHA" count="1" value="0x80CA"> + <size name="Get" mode="get"/> + </enum> + <enum name="BLEND_SRC_ALPHA" count="1" value="0x80CB"> + <size name="Get" mode="get"/> + </enum> + <enum name="DEPTH_COMPONENT16" value="0x81A5"/> + <enum name="MIRRORED_REPEAT" value="0x8370"/> + <enum name="INCR_WRAP" value="0x8507"/> + <enum name="DECR_WRAP" value="0x8508"/> + + <function name="BlendFuncSeparate" offset="assign"> + <param name="sfactorRGB" type="GLenum"/> + <param name="dfactorRGB" type="GLenum"/> + <param name="sfactorAlpha" type="GLenum"/> + <param name="dfactorAlpha" type="GLenum"/> + <glx rop="4134"/> + </function> + + <!-- addition to base1.5 --> + <enum name="VERTEX_ATTRIB_ARRAY_BUFFER_BINDING" count="1" value="0x889F"> + <size name="GetVertexAttribdv" mode="get"/> + <size name="GetVertexAttribfv" mode="get"/> + <size name="GetVertexAttribiv" mode="get"/> + </enum> + <enum name="STREAM_DRAW" value="0x88E0"/> + + <!-- addition to base2.0 --> + <!-- base2.0 should have everything defined --> +</category> + +<!-- OpenGL ES 2.0 --> +<category name="es2.0"> + <!-- addition to core2.0 --> + <enum name="LOW_FLOAT" value="0x8DF0"/> + <enum name="MEDIUM_FLOAT" value="0x8DF1"/> + <enum name="HIGH_FLOAT" value="0x8DF2"/> + <enum name="LOW_INT" value="0x8DF3"/> + <enum name="MEDIUM_INT" value="0x8DF4"/> + <enum name="HIGH_INT" value="0x8DF5"/> + <enum name="SHADER_BINARY_FORMATS" value="0x8DF8"/> + <enum name="NUM_SHADER_BINARY_FORMATS" value="0x8DF9"/> + <enum name="SHADER_COMPILER" value="0x8DFA"/> + <enum name="MAX_VERTEX_UNIFORM_VECTORS" value="0x8DFB"/> + <enum name="MAX_VARYING_VECTORS" value="0x8DFC"/> + <enum name="MAX_FRAGMENT_UNIFORM_VECTORS" value="0x8DFD"/> + + <function name="GetShaderPrecisionFormat" offset="assign"> + <param name="shadertype" type="GLenum"/> + <param name="precisiontype" type="GLenum"/> + <param name="range" type="GLint *"/> + <param name="precision" type="GLint *"/> + </function> + + <function name="ReleaseShaderCompiler" offset="assign"> + </function> + + <function name="ShaderBinary" offset="assign"> + <param name="n" type="GLsizei"/> + <param name="shaders" type="const GLuint *"/> + <param name="binaryformat" type="GLenum"/> + <param name="binary" type="const GLvoid *"/> + <param name="length" type="GLsizei"/> + </function> + + <!-- from GL_OES_fixed_point --> + <enum name="FIXED" value="0x140C"/> + <type name="fixed" size="4" /> + + <!-- from GL_OES_framebuffer_object --> + <enum name="INVALID_FRAMEBUFFER_OPERATION" value="0x0506"/> + <enum name="MAX_RENDERBUFFER_SIZE" value="0x84E8"/> + <enum name="FRAMEBUFFER_BINDING" value="0x8CA6"/> + <enum name="RENDERBUFFER_BINDING" value="0x8CA7"/> + <enum name="FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE" value="0x8CD0"/> + <enum name="FRAMEBUFFER_ATTACHMENT_OBJECT_NAME" value="0x8CD1"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL" value="0x8CD2"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE" value="0x8CD3"/> + <enum name="FRAMEBUFFER_COMPLETE" value="0x8CD5"/> + <enum name="FRAMEBUFFER_INCOMPLETE_ATTACHMENT" value="0x8CD6"/> + <enum name="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" value="0x8CD7"/> + <enum name="FRAMEBUFFER_INCOMPLETE_DIMENSIONS" value="0x8CD9"/> + <enum name="FRAMEBUFFER_UNSUPPORTED" value="0x8CDD"/> + <enum name="COLOR_ATTACHMENT0" value="0x8CE0"/> + <enum name="DEPTH_ATTACHMENT" value="0x8D00"/> + <enum name="STENCIL_ATTACHMENT" value="0x8D20"/> + <enum name="FRAMEBUFFER" value="0x8D40"/> + <enum name="RENDERBUFFER" value="0x8D41"/> + <enum name="RENDERBUFFER_WIDTH" value="0x8D42"/> + <enum name="RENDERBUFFER_HEIGHT" value="0x8D43"/> + <enum name="RENDERBUFFER_INTERNAL_FORMAT" value="0x8D44"/> + <enum name="STENCIL_INDEX8" value="0x8D48"/> + <enum name="RENDERBUFFER_RED_SIZE" value="0x8D50"/> + <enum name="RENDERBUFFER_GREEN_SIZE" value="0x8D51"/> + <enum name="RENDERBUFFER_BLUE_SIZE" value="0x8D52"/> + <enum name="RENDERBUFFER_ALPHA_SIZE" value="0x8D53"/> + <enum name="RENDERBUFFER_DEPTH_SIZE" value="0x8D54"/> + <enum name="RENDERBUFFER_STENCIL_SIZE" value="0x8D55"/> + <enum name="RGB565" value="0x8D62"/> + + <function name="BindFramebuffer" offset="assign"> + <param name="target" type="GLenum"/> + <param name="framebuffer" type="GLuint"/> + </function> + + <function name="BindRenderbuffer" offset="assign"> + <param name="target" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </function> + + <function name="CheckFramebufferStatus" offset="assign"> + <param name="target" type="GLenum"/> + <return type="GLenum"/> + </function> + + <function name="DeleteFramebuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="framebuffers" type="const GLuint *" count="n"/> + </function> + + <function name="DeleteRenderbuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="renderbuffers" type="const GLuint *" count="n"/> + </function> + + <function name="FramebufferRenderbuffer" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="renderbuffertarget" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </function> + + <function name="FramebufferTexture2D" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="textarget" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + </function> + + <function name="GenerateMipmap" offset="assign"> + <param name="target" type="GLenum"/> + </function> + + <function name="GenFramebuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="framebuffers" type="GLuint *" count="n" output="true"/> + </function> + + <function name="GenRenderbuffers" offset="assign"> + <param name="n" type="GLsizei" counter="true"/> + <param name="renderbuffers" type="GLuint *" count="n" output="true"/> + </function> + + <function name="GetFramebufferAttachmentParameteriv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true"/> + </function> + + <function name="GetRenderbufferParameteriv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true"/> + </function> + + <function name="IsFramebuffer" offset="assign"> + <param name="framebuffer" type="GLuint"/> + <return type="GLboolean"/> + </function> + + <function name="IsRenderbuffer" offset="assign"> + <param name="renderbuffer" type="GLuint"/> + <return type="GLboolean"/> + </function> + + <function name="RenderbufferStorage" offset="assign"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </function> + + <!-- from GL_OES_read_format --> + <enum name="IMPLEMENTATION_COLOR_READ_TYPE" value="0x8B9A"/> + <enum name="IMPLEMENTATION_COLOR_READ_FORMAT" value="0x8B9B"/> + + <!-- from GL_OES_single_precision --> + <function name="ClearDepthf" offset="assign"> + <param name="depth" type="GLclampf"/> + </function> + + <function name="DepthRangef" offset="assign"> + <param name="zNear" type="GLclampf"/> + <param name="zFar" type="GLclampf"/> + </function> +</category> + +<xi:include href="es2_EXT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> +<xi:include href="es2_COMPAT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es2_COMPAT.xml b/src/mesa/es/glapi/es2_COMPAT.xml new file mode 100644 index 0000000000..61f11a604e --- /dev/null +++ b/src/mesa/es/glapi/es2_COMPAT.xml @@ -0,0 +1,368 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<OpenGLAPI> + +<!-- This file defines the functions that are needed by Mesa. It + makes sure the generated glapi headers are compatible with Mesa. + It mainly consists of missing functions and aliases in OpenGL ES. +--> + +<xi:include href="es_COMPAT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<!-- except for those defined by es_COMPAT.xml, these are also needed --> +<category name="compat"> + <!-- OpenGL 1.0 --> + <function name="Color4f" offset="29" vectorequiv="Color4fv" static_dispatch="false"> + <param name="red" type="GLfloat"/> + <param name="green" type="GLfloat"/> + <param name="blue" type="GLfloat"/> + <param name="alpha" type="GLfloat"/> + </function> + + <function name="Color4ub" offset="35" vectorequiv="Color4ubv" static_dispatch="false"> + <param name="red" type="GLubyte"/> + <param name="green" type="GLubyte"/> + <param name="blue" type="GLubyte"/> + <param name="alpha" type="GLubyte"/> + </function> + + <function name="Normal3f" offset="56" vectorequiv="Normal3fv" static_dispatch="false"> + <param name="nx" type="GLfloat"/> + <param name="ny" type="GLfloat"/> + <param name="nz" type="GLfloat"/> + </function> + + <function name="Fogf" offset="153" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="80"/> + </function> + + <function name="Fogfv" offset="154" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="81"/> + </function> + + <function name="Lightf" offset="159" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="86"/> + </function> + + <function name="Lightfv" offset="160" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="87"/> + </function> + + <function name="LightModelf" offset="163" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="90"/> + </function> + + <function name="LightModelfv" offset="164" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="91"/> + </function> + + <function name="Materialf" offset="169" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="96"/> + </function> + + <function name="Materialfv" offset="170" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="97"/> + </function> + + <function name="PointSize" offset="173" static_dispatch="false"> + <param name="size" type="GLfloat"/> + <glx rop="100"/> + </function> + + <function name="ShadeModel" offset="177" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="104"/> + </function> + + <function name="TexEnvf" offset="184" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="111"/> + </function> + + <function name="TexEnvfv" offset="185" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="112"/> + </function> + + <function name="TexEnvi" offset="186" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="113"/> + </function> + + <function name="TexEnviv" offset="187" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="114"/> + </function> + + <function name="TexGenf" offset="190" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="117"/> + </function> + + <function name="TexGenfv" offset="191" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="118"/> + </function> + + <function name="TexGeni" offset="192" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="119"/> + </function> + + <function name="TexGeniv" offset="193" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="120"/> + </function> + + <function name="AlphaFunc" offset="240" static_dispatch="false"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLclampf"/> + <glx rop="159"/> + </function> + + <function name="LogicOp" offset="242" static_dispatch="false"> + <param name="opcode" type="GLenum"/> + <glx rop="161"/> + </function> + + <function name="GetLightfv" offset="264" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="118"/> + </function> + + <function name="GetMaterialfv" offset="269" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="123"/> + </function> + + <function name="GetTexEnvfv" offset="276" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="130"/> + </function> + + <function name="GetTexEnviv" offset="277" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="131"/> + </function> + + <function name="GetTexGenfv" offset="279" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="133"/> + </function> + + <function name="GetTexGeniv" offset="280" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="134"/> + </function> + + <function name="LoadIdentity" offset="290" static_dispatch="false"> + <glx rop="176"/> + </function> + + <function name="LoadMatrixf" offset="291" static_dispatch="false"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="177"/> + </function> + + <function name="MatrixMode" offset="293" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="179"/> + </function> + + <function name="MultMatrixf" offset="294" static_dispatch="false"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="180"/> + </function> + + <function name="PopMatrix" offset="297" static_dispatch="false"> + <glx rop="183"/> + </function> + + <function name="PushMatrix" offset="298" static_dispatch="false"> + <glx rop="184"/> + </function> + + <function name="Rotatef" offset="300" static_dispatch="false"> + <param name="angle" type="GLfloat"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="186"/> + </function> + + <function name="Scalef" offset="302" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="188"/> + </function> + + <function name="Translatef" offset="304" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="190"/> + </function> + + <!-- OpenGL 1.1 --> + <function name="ColorPointer" offset="308" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="DisableClientState" offset="309" static_dispatch="false"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="EnableClientState" offset="313" static_dispatch="false"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="NormalPointer" offset="318" static_dispatch="false"> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="TexCoordPointer" offset="320" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="VertexPointer" offset="321" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="GetPointerv" offset="329" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLvoid **" output="true"/> + <glx handcode="true"/> + </function> + + <!-- OpenGL 1.2 --> + <function name="TexImage3D" alias="TexImage3DOES" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/> + <glx rop="4114" large="true"/> + </function> + + <function name="TexSubImage3D" alias="TexSubImage3DOES" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_xoff="xoffset" img_yoff="yoffset" img_zoff="zoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4115" large="true"/> + </function> + + <function name="CopyTexSubImage3D" alias="CopyTexSubImage3DOES" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4123"/> + </function> + + <!-- GL_ARB_multitexture --> + <function name="ActiveTextureARB" alias="ActiveTexture" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx rop="197"/> + </function> + + <function name="ClientActiveTextureARB" offset="375" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="MultiTexCoord4fARB" offset="402" vectorequiv="MultiTexCoord4fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + <param name="q" type="GLfloat"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es2_EXT.xml b/src/mesa/es/glapi/es2_EXT.xml new file mode 100644 index 0000000000..3615772b56 --- /dev/null +++ b/src/mesa/es/glapi/es2_EXT.xml @@ -0,0 +1,162 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL ES 2.x extensions --> + +<OpenGLAPI> + +<xi:include href="es_EXT.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +<category name="GL_OES_texture_3D" number="34"> + <enum name="TEXTURE_BINDING_3D_OES" value="0x806A"/> + <enum name="TEXTURE_3D_OES" value="0x806F"/> + <enum name="TEXTURE_WRAP_R_OES" value="0x8072"/> + <enum name="MAX_3D_TEXTURE_SIZE_OES" value="0x8073"/> + <enum name="SAMPLER_3D_OES" value="0x8B5F"/> + <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES" value="0x8CD4"/> + + <function name="CompressedTexImage3DOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="imageSize" type="GLsizei" counter="true"/> + <param name="data" type="const GLvoid *" count="imageSize"/> + <glx rop="216" handcode="client"/> + </function> + + <function name="CompressedTexSubImage3DOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="imageSize" type="GLsizei" counter="true"/> + <param name="data" type="const GLvoid *" count="imageSize"/> + <glx rop="219" handcode="client"/> + </function> + + <function name="CopyTexSubImage3DOES" offset="373"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4123"/> + </function> + + <function name="FramebufferTexture3DOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="textarget" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + <param name="zoffset" type="GLint"/> + <glx rop="4323"/> + </function> + + <function name="TexImage3DOES" offset="371"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/> + <glx rop="4114" large="true"/> + </function> + + <function name="TexSubImage3DOES" offset="372"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_xoff="xoffset" img_yoff="yoffset" img_zoff="zoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4115" large="true"/> + </function> +</category> + +<!-- the other name is OES_texture_float_linear --> +<category name="OES_texture_half_float_linear" number="35"> + <!-- No new functions, types, enums. --> +</category> + +<!-- the other name is OES_texture_float --> +<category name="OES_texture_half_float" number="36"> + <enum name="HALF_FLOAT_OES" value="0x8D61"/> +</category> + +<category name="GL_OES_texture_npot" number="37"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_OES_vertex_half_float" number="38"> + <enum name="HALF_FLOAT_OES" value="0x8D61"/> +</category> + +<category name="GL_EXT_texture_type_2_10_10_10_REV" number="42"> + <enum name="UNSIGNED_INT_2_10_10_10_REV_EXT" value="0x8368"/> +</category> + +<category name="GL_OES_packed_depth_stencil" number="43"> + <enum name="DEPTH_STENCIL_OES" value="0x84F9"/> + <enum name="UNSIGNED_INT_24_8_OES" value="0x84FA"/> + <enum name="DEPTH24_STENCIL8_OES" value="0x88F0"/> +</category> + +<category name="GL_OES_depth_texture" number="44"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_OES_standard_derivatives" number="45"> + <enum name="FRAGMENT_SHADER_DERIVATIVE_HINT_OES" value="0x8B8B"/> +</category> + +<category name="GL_OES_vertex_type_10_10_10_2" number="46"> + <enum name="UNSIGNED_INT_10_10_10_2_OES" value="0x8DF6"/> + <enum name="INT_10_10_10_2_OES" value="0x8DF7"/> +</category> + +<category name="GL_OES_get_program_binary" number="47"> + <enum name="PROGRAM_BINARY_LENGTH_OES" value="0x8741"/> + <enum name="NUM_PROGRAM_BINARY_FORMATS_OES" value="0x87FE"/> + <enum name="PROGRAM_BINARY_FORMATS_OES" value="0x87FF"/> + + <function name="GetProgramBinaryOES" offset="assign"> + <param name="program" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="binaryFormat" type="GLenum *"/> + <param name="binary" type="GLvoid *"/> + </function> + + <function name="ProgramBinaryOES" offset="assign"> + <param name="program" type="GLuint"/> + <param name="binaryFormat" type="GLenum"/> + <param name="binary" type="const GLvoid *"/> + <param name="length" type="GLint"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es_COMPAT.xml b/src/mesa/es/glapi/es_COMPAT.xml new file mode 100644 index 0000000000..bb6d28db83 --- /dev/null +++ b/src/mesa/es/glapi/es_COMPAT.xml @@ -0,0 +1,2646 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<OpenGLAPI> + +<!-- This file defines the following categories + + a subset of 1.0 + a subset of 1.1 + a subset of 1.2 + a subset of GL_ARB_multitexture + GL_APPLE_vertex_array_object + + to make sure the generated glapi headers are compatible with Mesa. + It is included by es1_COMPAT.xml and es2_COMPAT.xml. +--> + +<category name="1.0"> + <type name="double" size="8" float="true" glx_name="FLOAT64"/> + <type name="clampd" size="8" float="true" glx_name="FLOAT64"/> + + <type name="float" size="4" float="true" glx_name="FLOAT32"/> + <type name="clampf" size="4" float="true" glx_name="FLOAT32"/> + + <type name="int" size="4" glx_name="CARD32"/> + <type name="uint" size="4" unsigned="true" glx_name="CARD32"/> + <type name="sizei" size="4" unsigned="true" glx_name="CARD32"/> + <type name="enum" size="4" unsigned="true" glx_name="ENUM"/> + <type name="bitfield" size="4" unsigned="true" glx_name="CARD32"/> + + <type name="short" size="2" glx_name="CARD16"/> + <type name="ushort" size="2" unsigned="true" glx_name="CARD16"/> + + <type name="byte" size="1" glx_name="CARD8"/> + <type name="ubyte" size="1" unsigned="true" glx_name="CARD8"/> + <type name="boolean" size="1" unsigned="true" glx_name="CARD8"/> + + <type name="void" size="1"/> + + <function name="NewList" offset="0" static_dispatch="false"> + <param name="list" type="GLuint"/> + <param name="mode" type="GLenum"/> + <glx sop="101"/> + </function> + + <function name="EndList" offset="1" static_dispatch="false"> + <glx sop="102"/> + </function> + + <function name="CallList" offset="2" static_dispatch="false"> + <param name="list" type="GLuint"/> + <glx rop="1"/> + </function> + + <function name="CallLists" offset="3" static_dispatch="false"> + <param name="n" type="GLsizei" counter="true"/> + <param name="type" type="GLenum"/> + <param name="lists" type="const GLvoid *" variable_param="type" count="n"/> + <glx rop="2" large="true"/> + </function> + + <function name="DeleteLists" offset="4" static_dispatch="false"> + <param name="list" type="GLuint"/> + <param name="range" type="GLsizei"/> + <glx sop="103"/> + </function> + + <function name="GenLists" offset="5" static_dispatch="false"> + <param name="range" type="GLsizei"/> + <return type="GLuint"/> + <glx sop="104"/> + </function> + + <function name="ListBase" offset="6" static_dispatch="false"> + <param name="base" type="GLuint"/> + <glx rop="3"/> + </function> + + <function name="Begin" offset="7" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="4"/> + </function> + + <function name="Bitmap" offset="8" static_dispatch="false"> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="xorig" type="GLfloat"/> + <param name="yorig" type="GLfloat"/> + <param name="xmove" type="GLfloat"/> + <param name="ymove" type="GLfloat"/> + <param name="bitmap" type="const GLubyte *" img_width="width" img_height="height" img_format="GL_COLOR_INDEX" img_type="GL_BITMAP" img_target="0" img_pad_dimensions="false"/> + <glx rop="5" large="true"/> + </function> + + <function name="Color3b" offset="9" vectorequiv="Color3bv" static_dispatch="false"> + <param name="red" type="GLbyte"/> + <param name="green" type="GLbyte"/> + <param name="blue" type="GLbyte"/> + </function> + + <function name="Color3bv" offset="10" static_dispatch="false"> + <param name="v" type="const GLbyte *" count="3"/> + <glx rop="6"/> + </function> + + <function name="Color3d" offset="11" vectorequiv="Color3dv" static_dispatch="false"> + <param name="red" type="GLdouble"/> + <param name="green" type="GLdouble"/> + <param name="blue" type="GLdouble"/> + </function> + + <function name="Color3dv" offset="12" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="7"/> + </function> + + <function name="Color3f" offset="13" vectorequiv="Color3fv" static_dispatch="false"> + <param name="red" type="GLfloat"/> + <param name="green" type="GLfloat"/> + <param name="blue" type="GLfloat"/> + </function> + + <function name="Color3fv" offset="14" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="8"/> + </function> + + <function name="Color3i" offset="15" vectorequiv="Color3iv" static_dispatch="false"> + <param name="red" type="GLint"/> + <param name="green" type="GLint"/> + <param name="blue" type="GLint"/> + </function> + + <function name="Color3iv" offset="16" static_dispatch="false"> + <param name="v" type="const GLint *" count="3"/> + <glx rop="9"/> + </function> + + <function name="Color3s" offset="17" vectorequiv="Color3sv" static_dispatch="false"> + <param name="red" type="GLshort"/> + <param name="green" type="GLshort"/> + <param name="blue" type="GLshort"/> + </function> + + <function name="Color3sv" offset="18" static_dispatch="false"> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="10"/> + </function> + + <function name="Color3ub" offset="19" vectorequiv="Color3ubv" static_dispatch="false"> + <param name="red" type="GLubyte"/> + <param name="green" type="GLubyte"/> + <param name="blue" type="GLubyte"/> + </function> + + <function name="Color3ubv" offset="20" static_dispatch="false"> + <param name="v" type="const GLubyte *" count="3"/> + <glx rop="11"/> + </function> + + <function name="Color3ui" offset="21" vectorequiv="Color3uiv" static_dispatch="false"> + <param name="red" type="GLuint"/> + <param name="green" type="GLuint"/> + <param name="blue" type="GLuint"/> + </function> + + <function name="Color3uiv" offset="22" static_dispatch="false"> + <param name="v" type="const GLuint *" count="3"/> + <glx rop="12"/> + </function> + + <function name="Color3us" offset="23" vectorequiv="Color3usv" static_dispatch="false"> + <param name="red" type="GLushort"/> + <param name="green" type="GLushort"/> + <param name="blue" type="GLushort"/> + </function> + + <function name="Color3usv" offset="24" static_dispatch="false"> + <param name="v" type="const GLushort *" count="3"/> + <glx rop="13"/> + </function> + + <function name="Color4b" offset="25" vectorequiv="Color4bv" static_dispatch="false"> + <param name="red" type="GLbyte"/> + <param name="green" type="GLbyte"/> + <param name="blue" type="GLbyte"/> + <param name="alpha" type="GLbyte"/> + </function> + + <function name="Color4bv" offset="26" static_dispatch="false"> + <param name="v" type="const GLbyte *" count="4"/> + <glx rop="14"/> + </function> + + <function name="Color4d" offset="27" vectorequiv="Color4dv" static_dispatch="false"> + <param name="red" type="GLdouble"/> + <param name="green" type="GLdouble"/> + <param name="blue" type="GLdouble"/> + <param name="alpha" type="GLdouble"/> + </function> + + <function name="Color4dv" offset="28" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="4"/> + <glx rop="15"/> + </function> + + <!--function name="Color4f" offset="29" vectorequiv="Color4fv" static_dispatch="false"> + <param name="red" type="GLfloat"/> + <param name="green" type="GLfloat"/> + <param name="blue" type="GLfloat"/> + <param name="alpha" type="GLfloat"/> + </function--> + + <function name="Color4fv" offset="30" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="4"/> + <glx rop="16"/> + </function> + + <function name="Color4i" offset="31" vectorequiv="Color4iv" static_dispatch="false"> + <param name="red" type="GLint"/> + <param name="green" type="GLint"/> + <param name="blue" type="GLint"/> + <param name="alpha" type="GLint"/> + </function> + + <function name="Color4iv" offset="32" static_dispatch="false"> + <param name="v" type="const GLint *" count="4"/> + <glx rop="17"/> + </function> + + <function name="Color4s" offset="33" vectorequiv="Color4sv" static_dispatch="false"> + <param name="red" type="GLshort"/> + <param name="green" type="GLshort"/> + <param name="blue" type="GLshort"/> + <param name="alpha" type="GLshort"/> + </function> + + <function name="Color4sv" offset="34" static_dispatch="false"> + <param name="v" type="const GLshort *" count="4"/> + <glx rop="18"/> + </function> + + <!--function name="Color4ub" offset="35" vectorequiv="Color4ubv" static_dispatch="false"> + <param name="red" type="GLubyte"/> + <param name="green" type="GLubyte"/> + <param name="blue" type="GLubyte"/> + <param name="alpha" type="GLubyte"/> + </function--> + + <function name="Color4ubv" offset="36" static_dispatch="false"> + <param name="v" type="const GLubyte *" count="4"/> + <glx rop="19"/> + </function> + + <function name="Color4ui" offset="37" vectorequiv="Color4uiv" static_dispatch="false"> + <param name="red" type="GLuint"/> + <param name="green" type="GLuint"/> + <param name="blue" type="GLuint"/> + <param name="alpha" type="GLuint"/> + </function> + + <function name="Color4uiv" offset="38" static_dispatch="false"> + <param name="v" type="const GLuint *" count="4"/> + <glx rop="20"/> + </function> + + <function name="Color4us" offset="39" vectorequiv="Color4usv" static_dispatch="false"> + <param name="red" type="GLushort"/> + <param name="green" type="GLushort"/> + <param name="blue" type="GLushort"/> + <param name="alpha" type="GLushort"/> + </function> + + <function name="Color4usv" offset="40" static_dispatch="false"> + <param name="v" type="const GLushort *" count="4"/> + <glx rop="21"/> + </function> + + <function name="EdgeFlag" offset="41" vectorequiv="EdgeFlagv" static_dispatch="false"> + <param name="flag" type="GLboolean"/> + </function> + + <function name="EdgeFlagv" offset="42" static_dispatch="false"> + <param name="flag" type="const GLboolean *" count="1"/> + <glx rop="22"/> + </function> + + <function name="End" offset="43" static_dispatch="false"> + <glx rop="23"/> + </function> + + <function name="Indexd" offset="44" vectorequiv="Indexdv" static_dispatch="false"> + <param name="c" type="GLdouble"/> + </function> + + <function name="Indexdv" offset="45" static_dispatch="false"> + <param name="c" type="const GLdouble *" count="1"/> + <glx rop="24"/> + </function> + + <function name="Indexf" offset="46" vectorequiv="Indexfv" static_dispatch="false"> + <param name="c" type="GLfloat"/> + </function> + + <function name="Indexfv" offset="47" static_dispatch="false"> + <param name="c" type="const GLfloat *" count="1"/> + <glx rop="25"/> + </function> + + <function name="Indexi" offset="48" vectorequiv="Indexiv" static_dispatch="false"> + <param name="c" type="GLint"/> + </function> + + <function name="Indexiv" offset="49" static_dispatch="false"> + <param name="c" type="const GLint *" count="1"/> + <glx rop="26"/> + </function> + + <function name="Indexs" offset="50" vectorequiv="Indexsv" static_dispatch="false"> + <param name="c" type="GLshort"/> + </function> + + <function name="Indexsv" offset="51" static_dispatch="false"> + <param name="c" type="const GLshort *" count="1"/> + <glx rop="27"/> + </function> + + <function name="Normal3b" offset="52" vectorequiv="Normal3bv" static_dispatch="false"> + <param name="nx" type="GLbyte"/> + <param name="ny" type="GLbyte"/> + <param name="nz" type="GLbyte"/> + </function> + + <function name="Normal3bv" offset="53" static_dispatch="false"> + <param name="v" type="const GLbyte *" count="3"/> + <glx rop="28"/> + </function> + + <function name="Normal3d" offset="54" vectorequiv="Normal3dv" static_dispatch="false"> + <param name="nx" type="GLdouble"/> + <param name="ny" type="GLdouble"/> + <param name="nz" type="GLdouble"/> + </function> + + <function name="Normal3dv" offset="55" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="29"/> + </function> + + <!--function name="Normal3f" offset="56" vectorequiv="Normal3fv" static_dispatch="false"> + <param name="nx" type="GLfloat"/> + <param name="ny" type="GLfloat"/> + <param name="nz" type="GLfloat"/> + </function--> + + <function name="Normal3fv" offset="57" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="30"/> + </function> + + <function name="Normal3i" offset="58" vectorequiv="Normal3iv" static_dispatch="false"> + <param name="nx" type="GLint"/> + <param name="ny" type="GLint"/> + <param name="nz" type="GLint"/> + </function> + + <function name="Normal3iv" offset="59" static_dispatch="false"> + <param name="v" type="const GLint *" count="3"/> + <glx rop="31"/> + </function> + + <function name="Normal3s" offset="60" vectorequiv="Normal3sv" static_dispatch="false"> + <param name="nx" type="GLshort"/> + <param name="ny" type="GLshort"/> + <param name="nz" type="GLshort"/> + </function> + + <function name="Normal3sv" offset="61" static_dispatch="false"> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="32"/> + </function> + + <function name="RasterPos2d" offset="62" vectorequiv="RasterPos2dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + </function> + + <function name="RasterPos2dv" offset="63" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="2"/> + <glx rop="33"/> + </function> + + <function name="RasterPos2f" offset="64" vectorequiv="RasterPos2fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + </function> + + <function name="RasterPos2fv" offset="65" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="2"/> + <glx rop="34"/> + </function> + + <function name="RasterPos2i" offset="66" vectorequiv="RasterPos2iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + </function> + + <function name="RasterPos2iv" offset="67" static_dispatch="false"> + <param name="v" type="const GLint *" count="2"/> + <glx rop="35"/> + </function> + + <function name="RasterPos2s" offset="68" vectorequiv="RasterPos2sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + </function> + + <function name="RasterPos2sv" offset="69" static_dispatch="false"> + <param name="v" type="const GLshort *" count="2"/> + <glx rop="36"/> + </function> + + <function name="RasterPos3d" offset="70" vectorequiv="RasterPos3dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + </function> + + <function name="RasterPos3dv" offset="71" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="37"/> + </function> + + <function name="RasterPos3f" offset="72" vectorequiv="RasterPos3fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + </function> + + <function name="RasterPos3fv" offset="73" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="38"/> + </function> + + <function name="RasterPos3i" offset="74" vectorequiv="RasterPos3iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + </function> + + <function name="RasterPos3iv" offset="75" static_dispatch="false"> + <param name="v" type="const GLint *" count="3"/> + <glx rop="39"/> + </function> + + <function name="RasterPos3s" offset="76" vectorequiv="RasterPos3sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + <param name="z" type="GLshort"/> + </function> + + <function name="RasterPos3sv" offset="77" static_dispatch="false"> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="40"/> + </function> + + <function name="RasterPos4d" offset="78" vectorequiv="RasterPos4dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <param name="w" type="GLdouble"/> + </function> + + <function name="RasterPos4dv" offset="79" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="4"/> + <glx rop="41"/> + </function> + + <function name="RasterPos4f" offset="80" vectorequiv="RasterPos4fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <param name="w" type="GLfloat"/> + </function> + + <function name="RasterPos4fv" offset="81" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="4"/> + <glx rop="42"/> + </function> + + <function name="RasterPos4i" offset="82" vectorequiv="RasterPos4iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + <param name="w" type="GLint"/> + </function> + + <function name="RasterPos4iv" offset="83" static_dispatch="false"> + <param name="v" type="const GLint *" count="4"/> + <glx rop="43"/> + </function> + + <function name="RasterPos4s" offset="84" vectorequiv="RasterPos4sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + <param name="z" type="GLshort"/> + <param name="w" type="GLshort"/> + </function> + + <function name="RasterPos4sv" offset="85" static_dispatch="false"> + <param name="v" type="const GLshort *" count="4"/> + <glx rop="44"/> + </function> + + <function name="Rectd" offset="86" vectorequiv="Rectdv" static_dispatch="false"> + <param name="x1" type="GLdouble"/> + <param name="y1" type="GLdouble"/> + <param name="x2" type="GLdouble"/> + <param name="y2" type="GLdouble"/> + </function> + + <function name="Rectdv" offset="87" static_dispatch="false"> + <param name="v1" type="const GLdouble *" count="2"/> + <param name="v2" type="const GLdouble *" count="2"/> + <glx rop="45"/> + </function> + + <function name="Rectf" offset="88" vectorequiv="Rectfv" static_dispatch="false"> + <param name="x1" type="GLfloat"/> + <param name="y1" type="GLfloat"/> + <param name="x2" type="GLfloat"/> + <param name="y2" type="GLfloat"/> + </function> + + <function name="Rectfv" offset="89" static_dispatch="false"> + <param name="v1" type="const GLfloat *" count="2"/> + <param name="v2" type="const GLfloat *" count="2"/> + <glx rop="46"/> + </function> + + <function name="Recti" offset="90" vectorequiv="Rectiv" static_dispatch="false"> + <param name="x1" type="GLint"/> + <param name="y1" type="GLint"/> + <param name="x2" type="GLint"/> + <param name="y2" type="GLint"/> + </function> + + <function name="Rectiv" offset="91" static_dispatch="false"> + <param name="v1" type="const GLint *" count="2"/> + <param name="v2" type="const GLint *" count="2"/> + <glx rop="47"/> + </function> + + <function name="Rects" offset="92" vectorequiv="Rectsv" static_dispatch="false"> + <param name="x1" type="GLshort"/> + <param name="y1" type="GLshort"/> + <param name="x2" type="GLshort"/> + <param name="y2" type="GLshort"/> + </function> + + <function name="Rectsv" offset="93" static_dispatch="false"> + <param name="v1" type="const GLshort *" count="2"/> + <param name="v2" type="const GLshort *" count="2"/> + <glx rop="48"/> + </function> + + <function name="TexCoord1d" offset="94" vectorequiv="TexCoord1dv" static_dispatch="false"> + <param name="s" type="GLdouble"/> + </function> + + <function name="TexCoord1dv" offset="95" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="1"/> + <glx rop="49"/> + </function> + + <function name="TexCoord1f" offset="96" vectorequiv="TexCoord1fv" static_dispatch="false"> + <param name="s" type="GLfloat"/> + </function> + + <function name="TexCoord1fv" offset="97" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="1"/> + <glx rop="50"/> + </function> + + <function name="TexCoord1i" offset="98" vectorequiv="TexCoord1iv" static_dispatch="false"> + <param name="s" type="GLint"/> + </function> + + <function name="TexCoord1iv" offset="99" static_dispatch="false"> + <param name="v" type="const GLint *" count="1"/> + <glx rop="51"/> + </function> + + <function name="TexCoord1s" offset="100" vectorequiv="TexCoord1sv" static_dispatch="false"> + <param name="s" type="GLshort"/> + </function> + + <function name="TexCoord1sv" offset="101" static_dispatch="false"> + <param name="v" type="const GLshort *" count="1"/> + <glx rop="52"/> + </function> + + <function name="TexCoord2d" offset="102" vectorequiv="TexCoord2dv" static_dispatch="false"> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + </function> + + <function name="TexCoord2dv" offset="103" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="2"/> + <glx rop="53"/> + </function> + + <function name="TexCoord2f" offset="104" vectorequiv="TexCoord2fv" static_dispatch="false"> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + </function> + + <function name="TexCoord2fv" offset="105" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="2"/> + <glx rop="54"/> + </function> + + <function name="TexCoord2i" offset="106" vectorequiv="TexCoord2iv" static_dispatch="false"> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + </function> + + <function name="TexCoord2iv" offset="107" static_dispatch="false"> + <param name="v" type="const GLint *" count="2"/> + <glx rop="55"/> + </function> + + <function name="TexCoord2s" offset="108" vectorequiv="TexCoord2sv" static_dispatch="false"> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + </function> + + <function name="TexCoord2sv" offset="109" static_dispatch="false"> + <param name="v" type="const GLshort *" count="2"/> + <glx rop="56"/> + </function> + + <function name="TexCoord3d" offset="110" vectorequiv="TexCoord3dv" static_dispatch="false"> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + <param name="r" type="GLdouble"/> + </function> + + <function name="TexCoord3dv" offset="111" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="57"/> + </function> + + <function name="TexCoord3f" offset="112" vectorequiv="TexCoord3fv" static_dispatch="false"> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + </function> + + <function name="TexCoord3fv" offset="113" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="58"/> + </function> + + <function name="TexCoord3i" offset="114" vectorequiv="TexCoord3iv" static_dispatch="false"> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + <param name="r" type="GLint"/> + </function> + + <function name="TexCoord3iv" offset="115" static_dispatch="false"> + <param name="v" type="const GLint *" count="3"/> + <glx rop="59"/> + </function> + + <function name="TexCoord3s" offset="116" vectorequiv="TexCoord3sv" static_dispatch="false"> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + <param name="r" type="GLshort"/> + </function> + + <function name="TexCoord3sv" offset="117" static_dispatch="false"> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="60"/> + </function> + + <function name="TexCoord4d" offset="118" vectorequiv="TexCoord4dv" static_dispatch="false"> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + <param name="r" type="GLdouble"/> + <param name="q" type="GLdouble"/> + </function> + + <function name="TexCoord4dv" offset="119" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="4"/> + <glx rop="61"/> + </function> + + <function name="TexCoord4f" offset="120" vectorequiv="TexCoord4fv" static_dispatch="false"> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + <param name="q" type="GLfloat"/> + </function> + + <function name="TexCoord4fv" offset="121" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="4"/> + <glx rop="62"/> + </function> + + <function name="TexCoord4i" offset="122" vectorequiv="TexCoord4iv" static_dispatch="false"> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + <param name="r" type="GLint"/> + <param name="q" type="GLint"/> + </function> + + <function name="TexCoord4iv" offset="123" static_dispatch="false"> + <param name="v" type="const GLint *" count="4"/> + <glx rop="63"/> + </function> + + <function name="TexCoord4s" offset="124" vectorequiv="TexCoord4sv" static_dispatch="false"> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + <param name="r" type="GLshort"/> + <param name="q" type="GLshort"/> + </function> + + <function name="TexCoord4sv" offset="125" static_dispatch="false"> + <param name="v" type="const GLshort *" count="4"/> + <glx rop="64"/> + </function> + + <function name="Vertex2d" offset="126" vectorequiv="Vertex2dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + </function> + + <function name="Vertex2dv" offset="127" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="2"/> + <glx rop="65"/> + </function> + + <function name="Vertex2f" offset="128" vectorequiv="Vertex2fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + </function> + + <function name="Vertex2fv" offset="129" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="2"/> + <glx rop="66"/> + </function> + + <function name="Vertex2i" offset="130" vectorequiv="Vertex2iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + </function> + + <function name="Vertex2iv" offset="131" static_dispatch="false"> + <param name="v" type="const GLint *" count="2"/> + <glx rop="67"/> + </function> + + <function name="Vertex2s" offset="132" vectorequiv="Vertex2sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + </function> + + <function name="Vertex2sv" offset="133" static_dispatch="false"> + <param name="v" type="const GLshort *" count="2"/> + <glx rop="68"/> + </function> + + <function name="Vertex3d" offset="134" vectorequiv="Vertex3dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + </function> + + <function name="Vertex3dv" offset="135" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="69"/> + </function> + + <function name="Vertex3f" offset="136" vectorequiv="Vertex3fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + </function> + + <function name="Vertex3fv" offset="137" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="70"/> + </function> + + <function name="Vertex3i" offset="138" vectorequiv="Vertex3iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + </function> + + <function name="Vertex3iv" offset="139" static_dispatch="false"> + <param name="v" type="const GLint *" count="3"/> + <glx rop="71"/> + </function> + + <function name="Vertex3s" offset="140" vectorequiv="Vertex3sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + <param name="z" type="GLshort"/> + </function> + + <function name="Vertex3sv" offset="141" static_dispatch="false"> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="72"/> + </function> + + <function name="Vertex4d" offset="142" vectorequiv="Vertex4dv" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <param name="w" type="GLdouble"/> + </function> + + <function name="Vertex4dv" offset="143" static_dispatch="false"> + <param name="v" type="const GLdouble *" count="4"/> + <glx rop="73"/> + </function> + + <function name="Vertex4f" offset="144" vectorequiv="Vertex4fv" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <param name="w" type="GLfloat"/> + </function> + + <function name="Vertex4fv" offset="145" static_dispatch="false"> + <param name="v" type="const GLfloat *" count="4"/> + <glx rop="74"/> + </function> + + <function name="Vertex4i" offset="146" vectorequiv="Vertex4iv" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + <param name="w" type="GLint"/> + </function> + + <function name="Vertex4iv" offset="147" static_dispatch="false"> + <param name="v" type="const GLint *" count="4"/> + <glx rop="75"/> + </function> + + <function name="Vertex4s" offset="148" vectorequiv="Vertex4sv" static_dispatch="false"> + <param name="x" type="GLshort"/> + <param name="y" type="GLshort"/> + <param name="z" type="GLshort"/> + <param name="w" type="GLshort"/> + </function> + + <function name="Vertex4sv" offset="149" static_dispatch="false"> + <param name="v" type="const GLshort *" count="4"/> + <glx rop="76"/> + </function> + + <function name="ClipPlane" offset="150" static_dispatch="false"> + <param name="plane" type="GLenum"/> + <param name="equation" type="const GLdouble *" count="4"/> + <glx rop="77"/> + </function> + + <function name="ColorMaterial" offset="151" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="mode" type="GLenum"/> + <glx rop="78"/> + </function> + + <!--function name="CullFace" offset="152" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="79"/> + </function> + + <function name="Fogf" offset="153" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="80"/> + </function> + + <function name="Fogfv" offset="154" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="81"/> + </function--> + + <function name="Fogi" offset="155" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="82"/> + </function> + + <function name="Fogiv" offset="156" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="83"/> + </function> + + <!--function name="FrontFace" offset="157" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="84"/> + </function> + + <function name="Hint" offset="158" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="mode" type="GLenum"/> + <glx rop="85"/> + </function> + + <function name="Lightf" offset="159" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="86"/> + </function> + + <function name="Lightfv" offset="160" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="87"/> + </function--> + + <function name="Lighti" offset="161" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="88"/> + </function> + + <function name="Lightiv" offset="162" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="89"/> + </function> + + <!--function name="LightModelf" offset="163" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="90"/> + </function> + + <function name="LightModelfv" offset="164" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="91"/> + </function--> + + <function name="LightModeli" offset="165" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="92"/> + </function> + + <function name="LightModeliv" offset="166" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="93"/> + </function> + + <function name="LineStipple" offset="167" static_dispatch="false"> + <param name="factor" type="GLint"/> + <param name="pattern" type="GLushort"/> + <glx rop="94"/> + </function> + + <!--function name="LineWidth" offset="168" static_dispatch="false"> + <param name="width" type="GLfloat"/> + <glx rop="95"/> + </function> + + <function name="Materialf" offset="169" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="96"/> + </function> + + <function name="Materialfv" offset="170" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="97"/> + </function--> + + <function name="Materiali" offset="171" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="98"/> + </function> + + <function name="Materialiv" offset="172" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="99"/> + </function> + + <!--function name="PointSize" offset="173" static_dispatch="false"> + <param name="size" type="GLfloat"/> + <glx rop="100"/> + </function--> + + <function name="PolygonMode" offset="174" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="mode" type="GLenum"/> + <glx rop="101"/> + </function> + + <function name="PolygonStipple" offset="175" static_dispatch="false"> + <param name="mask" type="const GLubyte *" img_width="32" img_height="32" img_format="GL_COLOR_INDEX" img_type="GL_BITMAP" img_target="0" img_pad_dimensions="false"/> + <glx rop="102"/> + </function> + + <!--function name="Scissor" offset="176" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="103"/> + </function> + + <function name="ShadeModel" offset="177" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="104"/> + </function> + + <function name="TexParameterf" offset="178" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="105"/> + </function> + + <function name="TexParameterfv" offset="179" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="106"/> + </function> + + <function name="TexParameteri" offset="180" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="107"/> + </function> + + <function name="TexParameteriv" offset="181" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="108"/> + </function--> + + <function name="TexImage1D" offset="182" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/> + <glx rop="109" large="true"/> + </function> + + <!--function name="TexImage2D" offset="183" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="target" img_send_null="true" img_pad_dimensions="true"/> + <glx rop="110" large="true"/> + </function> + + <function name="TexEnvf" offset="184" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="111"/> + </function> + + <function name="TexEnvfv" offset="185" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="112"/> + </function> + + <function name="TexEnvi" offset="186" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="113"/> + </function> + + <function name="TexEnviv" offset="187" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="114"/> + </function--> + + <function name="TexGend" offset="188" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLdouble"/> + <glx rop="115"/> + </function> + + <function name="TexGendv" offset="189" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLdouble *" variable_param="pname"/> + <glx rop="116"/> + </function> + + <!--function name="TexGenf" offset="190" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="117"/> + </function> + + <function name="TexGenfv" offset="191" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="118"/> + </function> + + <function name="TexGeni" offset="192" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="119"/> + </function> + + <function name="TexGeniv" offset="193" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="120"/> + </function--> + + <function name="FeedbackBuffer" offset="194" static_dispatch="false"> + <param name="size" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="buffer" type="GLfloat *" output="true"/> + <glx sop="105" handcode="true"/> + </function> + + <function name="SelectBuffer" offset="195" static_dispatch="false"> + <param name="size" type="GLsizei"/> + <param name="buffer" type="GLuint *" output="true"/> + <glx sop="106" handcode="true"/> + </function> + + <function name="RenderMode" offset="196" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <return type="GLint"/> + <glx sop="107" handcode="true"/> + </function> + + <function name="InitNames" offset="197" static_dispatch="false"> + <glx rop="121"/> + </function> + + <function name="LoadName" offset="198" static_dispatch="false"> + <param name="name" type="GLuint"/> + <glx rop="122"/> + </function> + + <function name="PassThrough" offset="199" static_dispatch="false"> + <param name="token" type="GLfloat"/> + <glx rop="123"/> + </function> + + <function name="PopName" offset="200" static_dispatch="false"> + <glx rop="124"/> + </function> + + <function name="PushName" offset="201" static_dispatch="false"> + <param name="name" type="GLuint"/> + <glx rop="125"/> + </function> + + <function name="DrawBuffer" offset="202" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="126"/> + </function> + + <!--function name="Clear" offset="203" static_dispatch="false"> + <param name="mask" type="GLbitfield"/> + <glx rop="127"/> + </function--> + + <function name="ClearAccum" offset="204" static_dispatch="false"> + <param name="red" type="GLfloat"/> + <param name="green" type="GLfloat"/> + <param name="blue" type="GLfloat"/> + <param name="alpha" type="GLfloat"/> + <glx rop="128"/> + </function> + + <function name="ClearIndex" offset="205" static_dispatch="false"> + <param name="c" type="GLfloat"/> + <glx rop="129"/> + </function> + + <!--function name="ClearColor" offset="206" static_dispatch="false"> + <param name="red" type="GLclampf"/> + <param name="green" type="GLclampf"/> + <param name="blue" type="GLclampf"/> + <param name="alpha" type="GLclampf"/> + <glx rop="130"/> + </function> + + <function name="ClearStencil" offset="207" static_dispatch="false"> + <param name="s" type="GLint"/> + <glx rop="131"/> + </function--> + + <function name="ClearDepth" offset="208" static_dispatch="false"> + <param name="depth" type="GLclampd"/> + <glx rop="132"/> + </function> + + <!--function name="StencilMask" offset="209" static_dispatch="false"> + <param name="mask" type="GLuint"/> + <glx rop="133"/> + </function> + + <function name="ColorMask" offset="210" static_dispatch="false"> + <param name="red" type="GLboolean"/> + <param name="green" type="GLboolean"/> + <param name="blue" type="GLboolean"/> + <param name="alpha" type="GLboolean"/> + <glx rop="134"/> + </function> + + <function name="DepthMask" offset="211" static_dispatch="false"> + <param name="flag" type="GLboolean"/> + <glx rop="135"/> + </function--> + + <function name="IndexMask" offset="212" static_dispatch="false"> + <param name="mask" type="GLuint"/> + <glx rop="136"/> + </function> + + <function name="Accum" offset="213" static_dispatch="false"> + <param name="op" type="GLenum"/> + <param name="value" type="GLfloat"/> + <glx rop="137"/> + </function> + + <!--function name="Disable" offset="214" static_dispatch="false"> + <param name="cap" type="GLenum"/> + <glx rop="138" handcode="client"/> + </function> + + <function name="Enable" offset="215" static_dispatch="false"> + <param name="cap" type="GLenum"/> + <glx rop="139" handcode="client"/> + </function> + + <function name="Finish" offset="216" static_dispatch="false"> + <glx sop="108" handcode="true"/> + </function> + + <function name="Flush" offset="217" static_dispatch="false"> + <glx sop="142" handcode="true"/> + </function--> + + <function name="PopAttrib" offset="218" static_dispatch="false"> + <glx rop="141"/> + </function> + + <function name="PushAttrib" offset="219" static_dispatch="false"> + <param name="mask" type="GLbitfield"/> + <glx rop="142"/> + </function> + + <function name="Map1d" offset="220" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="u1" type="GLdouble"/> + <param name="u2" type="GLdouble"/> + <param name="stride" type="GLint" client_only="true"/> + <param name="order" type="GLint"/> + <param name="points" type="const GLdouble *" variable_param="order"/> + <glx rop="143" handcode="true"/> + </function> + + <function name="Map1f" offset="221" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="u1" type="GLfloat"/> + <param name="u2" type="GLfloat"/> + <param name="stride" type="GLint" client_only="true"/> + <param name="order" type="GLint"/> + <param name="points" type="const GLfloat *" variable_param="order"/> + <glx rop="144" handcode="true"/> + </function> + + <function name="Map2d" offset="222" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="u1" type="GLdouble"/> + <param name="u2" type="GLdouble"/> + <param name="ustride" type="GLint" client_only="true"/> + <param name="uorder" type="GLint"/> + <param name="v1" type="GLdouble"/> + <param name="v2" type="GLdouble"/> + <param name="vstride" type="GLint" client_only="true"/> + <param name="vorder" type="GLint"/> + <param name="points" type="const GLdouble *" variable_param="uorder"/> + <glx rop="145" handcode="true"/> + </function> + + <function name="Map2f" offset="223" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="u1" type="GLfloat"/> + <param name="u2" type="GLfloat"/> + <param name="ustride" type="GLint" client_only="true"/> + <param name="uorder" type="GLint"/> + <param name="v1" type="GLfloat"/> + <param name="v2" type="GLfloat"/> + <param name="vstride" type="GLint" client_only="true"/> + <param name="vorder" type="GLint"/> + <param name="points" type="const GLfloat *" variable_param="uorder"/> + <glx rop="146" handcode="true"/> + </function> + + <function name="MapGrid1d" offset="224" static_dispatch="false"> + <param name="un" type="GLint"/> + <param name="u1" type="GLdouble"/> + <param name="u2" type="GLdouble"/> + <glx rop="147"/> + </function> + + <function name="MapGrid1f" offset="225" static_dispatch="false"> + <param name="un" type="GLint"/> + <param name="u1" type="GLfloat"/> + <param name="u2" type="GLfloat"/> + <glx rop="148"/> + </function> + + <function name="MapGrid2d" offset="226" static_dispatch="false"> + <param name="un" type="GLint"/> + <param name="u1" type="GLdouble"/> + <param name="u2" type="GLdouble"/> + <param name="vn" type="GLint"/> + <param name="v1" type="GLdouble"/> + <param name="v2" type="GLdouble"/> + <glx rop="149"/> + </function> + + <function name="MapGrid2f" offset="227" static_dispatch="false"> + <param name="un" type="GLint"/> + <param name="u1" type="GLfloat"/> + <param name="u2" type="GLfloat"/> + <param name="vn" type="GLint"/> + <param name="v1" type="GLfloat"/> + <param name="v2" type="GLfloat"/> + <glx rop="150"/> + </function> + + <function name="EvalCoord1d" offset="228" vectorequiv="EvalCoord1dv" static_dispatch="false"> + <param name="u" type="GLdouble"/> + </function> + + <function name="EvalCoord1dv" offset="229" static_dispatch="false"> + <param name="u" type="const GLdouble *" count="1"/> + <glx rop="151"/> + </function> + + <function name="EvalCoord1f" offset="230" vectorequiv="EvalCoord1fv" static_dispatch="false"> + <param name="u" type="GLfloat"/> + </function> + + <function name="EvalCoord1fv" offset="231" static_dispatch="false"> + <param name="u" type="const GLfloat *" count="1"/> + <glx rop="152"/> + </function> + + <function name="EvalCoord2d" offset="232" vectorequiv="EvalCoord2dv" static_dispatch="false"> + <param name="u" type="GLdouble"/> + <param name="v" type="GLdouble"/> + </function> + + <function name="EvalCoord2dv" offset="233" static_dispatch="false"> + <param name="u" type="const GLdouble *" count="2"/> + <glx rop="153"/> + </function> + + <function name="EvalCoord2f" offset="234" vectorequiv="EvalCoord2fv" static_dispatch="false"> + <param name="u" type="GLfloat"/> + <param name="v" type="GLfloat"/> + </function> + + <function name="EvalCoord2fv" offset="235" static_dispatch="false"> + <param name="u" type="const GLfloat *" count="2"/> + <glx rop="154"/> + </function> + + <function name="EvalMesh1" offset="236" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <param name="i1" type="GLint"/> + <param name="i2" type="GLint"/> + <glx rop="155"/> + </function> + + <function name="EvalPoint1" offset="237" static_dispatch="false"> + <param name="i" type="GLint"/> + <glx rop="156"/> + </function> + + <function name="EvalMesh2" offset="238" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <param name="i1" type="GLint"/> + <param name="i2" type="GLint"/> + <param name="j1" type="GLint"/> + <param name="j2" type="GLint"/> + <glx rop="157"/> + </function> + + <function name="EvalPoint2" offset="239" static_dispatch="false"> + <param name="i" type="GLint"/> + <param name="j" type="GLint"/> + <glx rop="158"/> + </function> + + <!--function name="AlphaFunc" offset="240" static_dispatch="false"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLclampf"/> + <glx rop="159"/> + </function> + + <function name="BlendFunc" offset="241" static_dispatch="false"> + <param name="sfactor" type="GLenum"/> + <param name="dfactor" type="GLenum"/> + <glx rop="160"/> + </function> + + <function name="LogicOp" offset="242" static_dispatch="false"> + <param name="opcode" type="GLenum"/> + <glx rop="161"/> + </function> + + <function name="StencilFunc" offset="243" static_dispatch="false"> + <param name="func" type="GLenum"/> + <param name="ref" type="GLint"/> + <param name="mask" type="GLuint"/> + <glx rop="162"/> + </function> + + <function name="StencilOp" offset="244" static_dispatch="false"> + <param name="fail" type="GLenum"/> + <param name="zfail" type="GLenum"/> + <param name="zpass" type="GLenum"/> + <glx rop="163"/> + </function> + + <function name="DepthFunc" offset="245" static_dispatch="false"> + <param name="func" type="GLenum"/> + <glx rop="164"/> + </function--> + + <function name="PixelZoom" offset="246" static_dispatch="false"> + <param name="xfactor" type="GLfloat"/> + <param name="yfactor" type="GLfloat"/> + <glx rop="165"/> + </function> + + <function name="PixelTransferf" offset="247" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx rop="166"/> + </function> + + <function name="PixelTransferi" offset="248" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx rop="167"/> + </function> + + <function name="PixelStoref" offset="249" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLfloat"/> + <glx sop="109" handcode="client"/> + </function> + + <!--function name="PixelStorei" offset="250" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="param" type="GLint"/> + <glx sop="110" handcode="client"/> + </function--> + + <function name="PixelMapfv" offset="251" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="mapsize" type="GLsizei" counter="true"/> + <param name="values" type="const GLfloat *" count="mapsize"/> + <glx rop="168" large="true"/> + </function> + + <function name="PixelMapuiv" offset="252" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="mapsize" type="GLsizei" counter="true"/> + <param name="values" type="const GLuint *" count="mapsize"/> + <glx rop="169" large="true"/> + </function> + + <function name="PixelMapusv" offset="253" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="mapsize" type="GLsizei" counter="true"/> + <param name="values" type="const GLushort *" count="mapsize"/> + <glx rop="170" large="true"/> + </function> + + <function name="ReadBuffer" offset="254" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="171"/> + </function> + + <function name="CopyPixels" offset="255" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="type" type="GLenum"/> + <glx rop="172"/> + </function> + + <!--function name="ReadPixels" offset="256" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="GLvoid *" output="true" img_width="width" img_height="height" img_format="format" img_type="type" img_target="0"/> + <glx sop="111"/> + </function--> + + <function name="DrawPixels" offset="257" static_dispatch="false"> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="0" img_pad_dimensions="false"/> + <glx rop="173" large="true"/> + </function> + + <!--function name="GetBooleanv" offset="258" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLboolean *" output="true" variable_param="pname"/> + <glx sop="112" handcode="client"/> + </function--> + + <function name="GetClipPlane" offset="259" static_dispatch="false"> + <param name="plane" type="GLenum"/> + <param name="equation" type="GLdouble *" output="true" count="4"/> + <glx sop="113" always_array="true"/> + </function> + + <function name="GetDoublev" offset="260" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLdouble *" output="true" variable_param="pname"/> + <glx sop="114" handcode="client"/> + </function> + + <!--function name="GetError" offset="261" static_dispatch="false"> + <return type="GLenum"/> + <glx sop="115" handcode="client"/> + </function> + + <function name="GetFloatv" offset="262" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="116" handcode="client"/> + </function> + + <function name="GetIntegerv" offset="263" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="117" handcode="client"/> + </function> + + <function name="GetLightfv" offset="264" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="118"/> + </function--> + + <function name="GetLightiv" offset="265" static_dispatch="false"> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="119"/> + </function> + + <function name="GetMapdv" offset="266" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="query" type="GLenum"/> + <param name="v" type="GLdouble *" output="true" variable_param="target query"/> + <glx sop="120"/> + </function> + + <function name="GetMapfv" offset="267" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="query" type="GLenum"/> + <param name="v" type="GLfloat *" output="true" variable_param="target query"/> + <glx sop="121"/> + </function> + + <function name="GetMapiv" offset="268" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="query" type="GLenum"/> + <param name="v" type="GLint *" output="true" variable_param="target query"/> + <glx sop="122"/> + </function> + + <!--function name="GetMaterialfv" offset="269" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="123"/> + </function--> + + <function name="GetMaterialiv" offset="270" static_dispatch="false"> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="124"/> + </function> + + <function name="GetPixelMapfv" offset="271" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="values" type="GLfloat *" output="true" variable_param="map"/> + <glx sop="125"/> + </function> + + <function name="GetPixelMapuiv" offset="272" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="values" type="GLuint *" output="true" variable_param="map"/> + <glx sop="126"/> + </function> + + <function name="GetPixelMapusv" offset="273" static_dispatch="false"> + <param name="map" type="GLenum"/> + <param name="values" type="GLushort *" output="true" variable_param="map"/> + <glx sop="127"/> + </function> + + <function name="GetPolygonStipple" offset="274" static_dispatch="false"> + <param name="mask" type="GLubyte *" output="true" img_width="32" img_height="32" img_format="GL_COLOR_INDEX" img_type="GL_BITMAP"/> + <glx sop="128"/> + </function> + + <!--function name="GetString" offset="275" static_dispatch="false"> + <param name="name" type="GLenum"/> + <return type="const GLubyte *"/> + <glx sop="129" handcode="true"/> + </function> + + <function name="GetTexEnvfv" offset="276" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="130"/> + </function> + + <function name="GetTexEnviv" offset="277" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="131"/> + </function--> + + <function name="GetTexGendv" offset="278" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLdouble *" output="true" variable_param="pname"/> + <glx sop="132"/> + </function> + + <!--function name="GetTexGenfv" offset="279" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="133"/> + </function> + + <function name="GetTexGeniv" offset="280" static_dispatch="false"> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="134"/> + </function--> + + <function name="GetTexImage" offset="281" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="GLvoid *" output="true" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type"/> + <glx sop="135" dimensions_in_reply="true"/> + </function> + + <!--function name="GetTexParameterfv" offset="282" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="136"/> + </function> + + <function name="GetTexParameteriv" offset="283" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="137"/> + </function--> + + <function name="GetTexLevelParameterfv" offset="284" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="138"/> + </function> + + <function name="GetTexLevelParameteriv" offset="285" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="139"/> + </function> + + <!--function name="IsEnabled" offset="286" static_dispatch="false"> + <param name="cap" type="GLenum"/> + <return type="GLboolean"/> + <glx sop="140" handcode="client"/> + </function--> + + <function name="IsList" offset="287" static_dispatch="false"> + <param name="list" type="GLuint"/> + <return type="GLboolean"/> + <glx sop="141"/> + </function> + + <function name="DepthRange" offset="288" static_dispatch="false"> + <param name="zNear" type="GLclampd"/> + <param name="zFar" type="GLclampd"/> + <glx rop="174"/> + </function> + + <function name="Frustum" offset="289" static_dispatch="false"> + <param name="left" type="GLdouble"/> + <param name="right" type="GLdouble"/> + <param name="bottom" type="GLdouble"/> + <param name="top" type="GLdouble"/> + <param name="zNear" type="GLdouble"/> + <param name="zFar" type="GLdouble"/> + <glx rop="175"/> + </function> + + <!--function name="LoadIdentity" offset="290" static_dispatch="false"> + <glx rop="176"/> + </function> + + <function name="LoadMatrixf" offset="291" static_dispatch="false"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="177"/> + </function--> + + <function name="LoadMatrixd" offset="292" static_dispatch="false"> + <param name="m" type="const GLdouble *" count="16"/> + <glx rop="178"/> + </function> + + <!--function name="MatrixMode" offset="293" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="179"/> + </function> + + <function name="MultMatrixf" offset="294" static_dispatch="false"> + <param name="m" type="const GLfloat *" count="16"/> + <glx rop="180"/> + </function--> + + <function name="MultMatrixd" offset="295" static_dispatch="false"> + <param name="m" type="const GLdouble *" count="16"/> + <glx rop="181"/> + </function> + + <function name="Ortho" offset="296" static_dispatch="false"> + <param name="left" type="GLdouble"/> + <param name="right" type="GLdouble"/> + <param name="bottom" type="GLdouble"/> + <param name="top" type="GLdouble"/> + <param name="zNear" type="GLdouble"/> + <param name="zFar" type="GLdouble"/> + <glx rop="182"/> + </function> + + <!--function name="PopMatrix" offset="297" static_dispatch="false"> + <glx rop="183"/> + </function> + + <function name="PushMatrix" offset="298" static_dispatch="false"> + <glx rop="184"/> + </function--> + + <function name="Rotated" offset="299" static_dispatch="false"> + <param name="angle" type="GLdouble"/> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <glx rop="185"/> + </function> + + <!--function name="Rotatef" offset="300" static_dispatch="false"> + <param name="angle" type="GLfloat"/> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="186"/> + </function--> + + <function name="Scaled" offset="301" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <glx rop="187"/> + </function> + + <!--function name="Scalef" offset="302" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="188"/> + </function--> + + <function name="Translated" offset="303" static_dispatch="false"> + <param name="x" type="GLdouble"/> + <param name="y" type="GLdouble"/> + <param name="z" type="GLdouble"/> + <glx rop="189"/> + </function> + + <!--function name="Translatef" offset="304" static_dispatch="false"> + <param name="x" type="GLfloat"/> + <param name="y" type="GLfloat"/> + <param name="z" type="GLfloat"/> + <glx rop="190"/> + </function> + + <function name="Viewport" offset="305" static_dispatch="false"> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="191"/> + </function--> +</category> + +<category name="1.1"> + <function name="ArrayElement" offset="306" static_dispatch="false"> + <param name="i" type="GLint"/> + <glx handcode="true"/> + </function> + + <!--function name="ColorPointer" offset="308" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="DisableClientState" offset="309" static_dispatch="false"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="DrawArrays" offset="310" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint"/> + <param name="count" type="GLsizei"/> + <glx rop="193" handcode="true"/> + </function> + + <function name="DrawElements" offset="311" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <param name="count" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid *"/> + <glx handcode="true"/> + </function--> + + <function name="EdgeFlagPointer" offset="312" static_dispatch="false"> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <!--function name="EnableClientState" offset="313" static_dispatch="false"> + <param name="array" type="GLenum"/> + <glx handcode="true"/> + </function> + + <function name="GetPointerv" offset="329" static_dispatch="false"> + <param name="pname" type="GLenum"/> + <param name="params" type="GLvoid **" output="true"/> + <glx handcode="true"/> + </function--> + + <function name="IndexPointer" offset="314" static_dispatch="false"> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="InterleavedArrays" offset="317" static_dispatch="false"> + <param name="format" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <!--function name="NormalPointer" offset="318" static_dispatch="false"> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="TexCoordPointer" offset="320" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="VertexPointer" offset="321" static_dispatch="false"> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="PolygonOffset" offset="319" static_dispatch="false"> + <param name="factor" type="GLfloat"/> + <param name="units" type="GLfloat"/> + <glx rop="192"/> + </function--> + + <function name="CopyTexImage1D" offset="323" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="border" type="GLint"/> + <glx rop="4119"/> + </function> + + <!--function name="CopyTexImage2D" offset="324" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <glx rop="4120"/> + </function--> + + <function name="CopyTexSubImage1D" offset="325" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <glx rop="4121"/> + </function> + + <!--function name="CopyTexSubImage2D" offset="326" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4122"/> + </function--> + + <function name="TexSubImage1D" offset="332" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_xoff="xoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4099" large="true"/> + </function> + + <!--function name="TexSubImage2D" offset="333" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_xoff="xoffset" img_yoff="yoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4100" large="true"/> + </function--> + + <function name="AreTexturesResident" offset="322" static_dispatch="false"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="const GLuint *" count="n"/> + <param name="residences" type="GLboolean *" output="true" count="n"/> + <return type="GLboolean"/> + <glx sop="143" handcode="client" always_array="true"/> + </function> + + <!--function name="BindTexture" offset="307" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="texture" type="GLuint"/> + <glx rop="4117"/> + </function> + + <function name="DeleteTextures" offset="327" static_dispatch="false"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="const GLuint *" count="n"/> + <glx sop="144"/> + </function> + + <function name="GenTextures" offset="328" static_dispatch="false"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="GLuint *" output="true" count="n"/> + <glx sop="145" always_array="true"/> + </function> + + <function name="IsTexture" offset="330" static_dispatch="false"> + <param name="texture" type="GLuint"/> + <return type="GLboolean"/> + <glx sop="146"/> + </function--> + + <function name="PrioritizeTextures" offset="331" static_dispatch="false"> + <param name="n" type="GLsizei" counter="true"/> + <param name="textures" type="const GLuint *" count="n"/> + <param name="priorities" type="const GLclampf *" count="n"/> + <glx rop="4118"/> + </function> + + <function name="Indexub" offset="315" vectorequiv="Indexubv" static_dispatch="false"> + <param name="c" type="GLubyte"/> + </function> + + <function name="Indexubv" offset="316" static_dispatch="false"> + <param name="c" type="const GLubyte *" count="1"/> + <glx rop="194"/> + </function> + + <function name="PopClientAttrib" offset="334" static_dispatch="false"> + <glx handcode="true"/> + </function> + + <function name="PushClientAttrib" offset="335" static_dispatch="false"> + <param name="mask" type="GLbitfield"/> + <glx handcode="true"/> + </function> +</category> + +<category name="1.2"> + <!--function name="BlendColor" offset="336" static_dispatch="false"> + <param name="red" type="GLclampf"/> + <param name="green" type="GLclampf"/> + <param name="blue" type="GLclampf"/> + <param name="alpha" type="GLclampf"/> + <glx rop="4096"/> + </function> + + <function name="BlendEquation" offset="337" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <glx rop="4097"/> + </function--> + + <function name="DrawRangeElements" offset="338" static_dispatch="false"> + <param name="mode" type="GLenum"/> + <param name="start" type="GLuint"/> + <param name="end" type="GLuint"/> + <param name="count" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid *"/> + <glx handcode="true"/> + </function> + + <function name="ColorTable" offset="339" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="table" type="const GLvoid *" img_width="width" img_pad_dimensions="false" img_format="format" img_type="type" img_target="target"/> + <glx rop="2053" large="true"/> + </function> + + <function name="ColorTableParameterfv" offset="340" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="2054"/> + </function> + + <function name="ColorTableParameteriv" offset="341" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="2055"/> + </function> + + <function name="CopyColorTable" offset="342" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <glx rop="2056"/> + </function> + + <function name="GetColorTable" offset="343" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="table" type="GLvoid *" output="true" img_width="width" img_format="format" img_type="type"/> + <glx sop="147" dimensions_in_reply="true"/> + </function> + + <function name="GetColorTableParameterfv" offset="344" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="148"/> + </function> + + <function name="GetColorTableParameteriv" offset="345" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="149"/> + </function> + + <function name="ColorSubTable" offset="346" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="start" type="GLsizei"/> + <param name="count" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="data" type="const GLvoid *" img_width="count" img_pad_dimensions="false" img_format="format" img_type="type" img_target="target"/> + <glx rop="195" large="true"/> + </function> + + <function name="CopyColorSubTable" offset="347" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="start" type="GLsizei"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <glx rop="196"/> + </function> + + <function name="ConvolutionFilter1D" offset="348" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="image" type="const GLvoid *" img_width="width" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4101" large="true"/> + </function> + + <function name="ConvolutionFilter2D" offset="349" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="image" type="const GLvoid *" img_width="width" img_height="height" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4102" large="true"/> + </function> + + <function name="ConvolutionParameterf" offset="350" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat"/> + <glx rop="4103"/> + </function> + + <function name="ConvolutionParameterfv" offset="351" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLfloat *" variable_param="pname"/> + <glx rop="4104"/> + </function> + + <function name="ConvolutionParameteri" offset="352" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint"/> + <glx rop="4105"/> + </function> + + <function name="ConvolutionParameteriv" offset="353" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="const GLint *" variable_param="pname"/> + <glx rop="4106"/> + </function> + + <function name="CopyConvolutionFilter1D" offset="354" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <glx rop="4107"/> + </function> + + <function name="CopyConvolutionFilter2D" offset="355" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4108"/> + </function> + + <function name="GetConvolutionFilter" offset="356" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="image" type="GLvoid *" output="true" img_width="width" img_height="height" img_format="format" img_type="type"/> + <glx sop="150" dimensions_in_reply="true"/> + </function> + + <function name="GetConvolutionParameterfv" offset="357" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="151"/> + </function> + + <function name="GetConvolutionParameteriv" offset="358" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="152"/> + </function> + + <function name="GetSeparableFilter" offset="359" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="row" type="GLvoid *" output="true"/> + <param name="column" type="GLvoid *" output="true"/> + <param name="span" type="GLvoid *" output="true"/> + <glx sop="153" handcode="true"/> + </function> + + <function name="SeparableFilter2D" offset="360" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="row" type="const GLvoid *"/> + <param name="column" type="const GLvoid *"/> + <glx rop="4109" handcode="true"/> + </function> + + <function name="GetHistogram" offset="361" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="reset" type="GLboolean"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="values" type="GLvoid *" output="true" img_width="width" img_format="format" img_type="type"/> + <glx sop="154" dimensions_in_reply="true" img_reset="reset"/> + </function> + + <function name="GetHistogramParameterfv" offset="362" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="155"/> + </function> + + <function name="GetHistogramParameteriv" offset="363" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="156"/> + </function> + + <function name="GetMinmax" offset="364" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="reset" type="GLboolean"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="values" type="GLvoid *" output="true" img_width="2" img_format="format" img_type="type"/> + <glx sop="157" img_reset="reset"/> + </function> + + <function name="GetMinmaxParameterfv" offset="365" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLfloat *" output="true" variable_param="pname"/> + <glx sop="158"/> + </function> + + <function name="GetMinmaxParameteriv" offset="366" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *" output="true" variable_param="pname"/> + <glx sop="159"/> + </function> + + <function name="Histogram" offset="367" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="internalformat" type="GLenum"/> + <param name="sink" type="GLboolean"/> + <glx rop="4110"/> + </function> + + <function name="Minmax" offset="368" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="internalformat" type="GLenum"/> + <param name="sink" type="GLboolean"/> + <glx rop="4111"/> + </function> + + <function name="ResetHistogram" offset="369" static_dispatch="false"> + <param name="target" type="GLenum"/> + <glx rop="4112"/> + </function> + + <function name="ResetMinmax" offset="370" static_dispatch="false"> + <param name="target" type="GLenum"/> + <glx rop="4113"/> + </function> + + <!--function name="TexImage3D" offset="371" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalformat" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_format="format" img_type="type" img_target="target" img_null_flag="true" img_pad_dimensions="true"/> + <glx rop="4114" large="true"/> + </function> + + <function name="TexSubImage3D" offset="372" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="UNUSED" type="GLuint" padding="true"/> + <param name="pixels" type="const GLvoid *" img_width="width" img_height="height" img_depth="depth" img_xoff="xoffset" img_yoff="yoffset" img_zoff="zoffset" img_format="format" img_type="type" img_target="target" img_pad_dimensions="true"/> + <glx rop="4115" large="true"/> + </function> + + <function name="CopyTexSubImage3D" offset="373" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <glx rop="4123"/> + </function--> +</category> + +<category name="GL_ARB_multitexture" number="1"> + <!--function name="ActiveTextureARB" offset="374" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx rop="197"/> + </function> + + <function name="ClientActiveTextureARB" offset="375" static_dispatch="false"> + <param name="texture" type="GLenum"/> + <glx handcode="true"/> + </function--> + + <function name="MultiTexCoord1dARB" offset="376" vectorequiv="MultiTexCoord1dvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLdouble"/> + </function> + + <function name="MultiTexCoord1dvARB" offset="377" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLdouble *" count="1"/> + <glx rop="198"/> + </function> + + <function name="MultiTexCoord1fARB" offset="378" vectorequiv="MultiTexCoord1fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + </function> + + <function name="MultiTexCoord1fvARB" offset="379" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLfloat *" count="1"/> + <glx rop="199"/> + </function> + + <function name="MultiTexCoord1iARB" offset="380" vectorequiv="MultiTexCoord1ivARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLint"/> + </function> + + <function name="MultiTexCoord1ivARB" offset="381" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLint *" count="1"/> + <glx rop="200"/> + </function> + + <function name="MultiTexCoord1sARB" offset="382" vectorequiv="MultiTexCoord1svARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLshort"/> + </function> + + <function name="MultiTexCoord1svARB" offset="383" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLshort *" count="1"/> + <glx rop="201"/> + </function> + + <function name="MultiTexCoord2dARB" offset="384" vectorequiv="MultiTexCoord2dvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + </function> + + <function name="MultiTexCoord2dvARB" offset="385" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLdouble *" count="2"/> + <glx rop="202"/> + </function> + + <function name="MultiTexCoord2fARB" offset="386" vectorequiv="MultiTexCoord2fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + </function> + + <function name="MultiTexCoord2fvARB" offset="387" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLfloat *" count="2"/> + <glx rop="203"/> + </function> + + <function name="MultiTexCoord2iARB" offset="388" vectorequiv="MultiTexCoord2ivARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + </function> + + <function name="MultiTexCoord2ivARB" offset="389" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLint *" count="2"/> + <glx rop="204"/> + </function> + + <function name="MultiTexCoord2sARB" offset="390" vectorequiv="MultiTexCoord2svARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + </function> + + <function name="MultiTexCoord2svARB" offset="391" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLshort *" count="2"/> + <glx rop="205"/> + </function> + + <function name="MultiTexCoord3dARB" offset="392" vectorequiv="MultiTexCoord3dvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + <param name="r" type="GLdouble"/> + </function> + + <function name="MultiTexCoord3dvARB" offset="393" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLdouble *" count="3"/> + <glx rop="206"/> + </function> + + <function name="MultiTexCoord3fARB" offset="394" vectorequiv="MultiTexCoord3fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + </function> + + <function name="MultiTexCoord3fvARB" offset="395" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLfloat *" count="3"/> + <glx rop="207"/> + </function> + + <function name="MultiTexCoord3iARB" offset="396" vectorequiv="MultiTexCoord3ivARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + <param name="r" type="GLint"/> + </function> + + <function name="MultiTexCoord3ivARB" offset="397" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLint *" count="3"/> + <glx rop="208"/> + </function> + + <function name="MultiTexCoord3sARB" offset="398" vectorequiv="MultiTexCoord3svARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + <param name="r" type="GLshort"/> + </function> + + <function name="MultiTexCoord3svARB" offset="399" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLshort *" count="3"/> + <glx rop="209"/> + </function> + + <function name="MultiTexCoord4dARB" offset="400" vectorequiv="MultiTexCoord4dvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLdouble"/> + <param name="t" type="GLdouble"/> + <param name="r" type="GLdouble"/> + <param name="q" type="GLdouble"/> + </function> + + <function name="MultiTexCoord4dvARB" offset="401" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLdouble *" count="4"/> + <glx rop="210"/> + </function> + + <!--function name="MultiTexCoord4fARB" offset="402" vectorequiv="MultiTexCoord4fvARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLfloat"/> + <param name="t" type="GLfloat"/> + <param name="r" type="GLfloat"/> + <param name="q" type="GLfloat"/> + </function--> + + <function name="MultiTexCoord4fvARB" offset="403" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLfloat *" count="4"/> + <glx rop="211"/> + </function> + + <function name="MultiTexCoord4iARB" offset="404" vectorequiv="MultiTexCoord4ivARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLint"/> + <param name="t" type="GLint"/> + <param name="r" type="GLint"/> + <param name="q" type="GLint"/> + </function> + + <function name="MultiTexCoord4ivARB" offset="405" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLint *" count="4"/> + <glx rop="212"/> + </function> + + <function name="MultiTexCoord4sARB" offset="406" vectorequiv="MultiTexCoord4svARB" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="s" type="GLshort"/> + <param name="t" type="GLshort"/> + <param name="r" type="GLshort"/> + <param name="q" type="GLshort"/> + </function> + + <function name="MultiTexCoord4svARB" offset="407" static_dispatch="false"> + <param name="target" type="GLenum"/> + <param name="v" type="const GLshort *" count="4"/> + <glx rop="213"/> + </function> +</category> + +<xi:include href="../../glapi/APPLE_vertex_array_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/es_EXT.xml b/src/mesa/es/glapi/es_EXT.xml new file mode 100644 index 0000000000..b76cda929a --- /dev/null +++ b/src/mesa/es/glapi/es_EXT.xml @@ -0,0 +1,122 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "../../glapi/gl_API.dtd"> + +<!-- OpenGL ES extensions --> + +<OpenGLAPI> + +<category name="GL_OES_compressed_paletted_texture" number="6"> + <enum name="PALETTE4_RGB8_OES" value="0x8B90"/> + <enum name="PALETTE4_RGBA8_OES" value="0x8B91"/> + <enum name="PALETTE4_R5_G6_B5_OES" value="0x8B92"/> + <enum name="PALETTE4_RGBA4_OES" value="0x8B93"/> + <enum name="PALETTE4_RGB5_A1_OES" value="0x8B94"/> + <enum name="PALETTE8_RGB8_OES" value="0x8B95"/> + <enum name="PALETTE8_RGBA8_OES" value="0x8B96"/> + <enum name="PALETTE8_R5_G6_B5_OES" value="0x8B97"/> + <enum name="PALETTE8_RGBA4_OES" value="0x8B98"/> + <enum name="PALETTE8_RGB5_A1_OES" value="0x8B99"/> +</category> + +<category name="GL_OES_depth24" number="24"> + <enum name="DEPTH_COMPONENT24_OES" value="0x81A6"/> +</category> + +<category name="GL_OES_depth32" number="25"> + <enum name="DEPTH_COMPONENT32_OES" value="0x81A7"/> +</category> + +<category name="GL_OES_element_index_uint" number="26"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_OES_fbo_render_mipmap" number="27"> + <!-- No new functions, types, enums. --> +</category> + +<category name="GL_OES_mapbuffer" number="29"> + <enum name="WRITE_ONLY_OES" value="0x88B9"/> + <enum name="BUFFER_ACCESS_OES" value="0x88BB"/> + <enum name="BUFFER_MAPPED_OES" value="0x88BC"/> + <enum name="BUFFER_MAP_POINTER_OES" value="0x88BD"/> + + <function name="GetBufferPointervOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLvoid **"/> + </function> + + <function name="MapBufferOES" offset="assign"> + <param name="target" type="GLenum"/> + <param name="access" type="GLenum"/> + <return type="GLvoid *"/> + </function> + + <function name="UnmapBufferOES" offset="assign"> + <param name="target" type="GLenum"/> + <return type="GLboolean"/> + </function> +</category> + +<category name="GL_OES_rgb8_rgba8" number="30"> + <enum name="RGB8_OES" value="0x8051"/> + <enum name="RGBA8_OES" value="0x8058"/> +</category> + +<category name="GL_OES_stencil1" number="31"> + <enum name="STENCIL_INDEX1_OES" value="0x8D46"/> +</category> + +<category name="GL_OES_stencil4" number="32"> + <enum name="STENCIL_INDEX4_OES" value="0x8D47"/> +</category> + +<category name="GL_OES_stencil8" number="33"> + <enum name="STENCIL_INDEX8_OES" value="0x8D48"/> +</category> + +<category name="GL_EXT_texture_filter_anisotropic" number="41"> + <enum name="TEXTURE_MAX_ANISOTROPY_EXT" value="0x84FE"/> + <enum name="MAX_TEXTURE_MAX_ANISOTROPY_EXT" value="0x84FF"/> +</category> + +<category name="GL_EXT_texture_compression_dxt1" number="49"> + <enum name="COMPRESSED_RGB_S3TC_DXT1_EXT" value="0x83F0"/> + <enum name="COMPRESSED_RGBA_S3TC_DXT1_EXT" value="0x83F1"/> +</category> + +<category name="GL_EXT_texture_format_BGRA8888" number="51"> + <enum name="BGRA_EXT" value="0x80E1"/> +</category> + +<category name="GL_EXT_blend_minmax" number="65"> + <enum name="MIN_EXT" value="0x8007"/> + <enum name="MAX_EXT" value="0x8008"/> +</category> + +<category name="GL_EXT_read_format_bgra" number="66"> + <enum name="BGRA_EXT" value="0x80E1"/> + <enum name="UNSIGNED_SHORT_4_4_4_4_REV_EXT" value="0x8365"/> + <enum name="UNSIGNED_SHORT_1_5_5_5_REV_EXT" value="0x8366"/> +</category> + +<category name="GL_EXT_multi_draw_arrays" number="69"> + <function name="MultiDrawArraysEXT" offset="assign"> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint *"/> <!-- Spec bug. Should be const. --> + <param name="count" type="GLsizei *"/> <!-- Spec bug. Should be const. --> + <param name="primcount" type="GLsizei"/> + <glx handcode="true"/> + </function> + + <function name="MultiDrawElementsEXT" offset="assign"> + <param name="mode" type="GLenum"/> + <param name="count" type="const GLsizei *"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid **"/> + <param name="primcount" type="GLsizei"/> + <glx handcode="true"/> + </function> +</category> + +</OpenGLAPI> diff --git a/src/mesa/es/glapi/gl_compare.py b/src/mesa/es/glapi/gl_compare.py new file mode 100644 index 0000000000..7a2148cb1f --- /dev/null +++ b/src/mesa/es/glapi/gl_compare.py @@ -0,0 +1,354 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> +# +# 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 +# IBM 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. + +import sys +import os.path +import getopt + +GLAPI = "../../glapi" +sys.path.append(GLAPI) + +import gl_XML +import glX_XML + +class ApiSet(object): + def __init__(self, api, elts=["enum", "type", "function"]): + self.api = api + self.elts = elts + + def _check_enum(self, e1, e2, strict=True): + if e1.name != e2.name: + raise ValueError("%s: name mismatch" % e1.name) + if e1.value != e2.value: + raise ValueError("%s: value 0x%04x != 0x%04x" + % (e1.name, e1.value, e2.value)) + + def _check_type(self, t1, t2, strict=True): + if t1.name != t2.name: + raise ValueError("%s: name mismatch" % t1.name) + if t1.type_expr.string() != t2.type_expr.string(): + raise ValueError("%s: type %s != %s" + % (t1.name, t1.type_expr.string(), t2.type_expr.string())) + + def _check_function(self, f1, f2, strict=True): + if f1.name != f2.name: + raise ValueError("%s: name mismatch" % f1.name) + if f1.return_type != f2.return_type: + raise ValueError("%s: return type %s != %s" + % (f1.name, f1.return_type, f2.return_type)) + # there might be padded parameters + if strict and len(f1.parameters) != len(f2.parameters): + raise ValueError("%s: parameter length %d != %d" + % (f1.name, len(f1.parameters), len(f2.parameters))) + if f1.assign_offset != f2.assign_offset: + if ((f1.assign_offset and f2.offset < 0) or + (f2.assign_offset and f1.offset < 0)): + raise ValueError("%s: assign offset %d != %d" + % (f1.name, f1.assign_offset, f2.assign_offset)) + elif not f1.assign_offset: + if f1.offset != f2.offset: + raise ValueError("%s: offset %d != %d" + % (f1.name, f1.offset, f2.offset)) + + if strict: + l1 = f1.entry_points + l2 = f2.entry_points + l1.sort() + l2.sort() + if l1 != l2: + raise ValueError("%s: entry points %s != %s" + % (f1.name, l1, l2)) + + l1 = f1.static_entry_points + l2 = f2.static_entry_points + l1.sort() + l2.sort() + if l1 != l2: + raise ValueError("%s: static entry points %s != %s" + % (f1.name, l1, l2)) + + pad = 0 + for i in xrange(len(f1.parameters)): + p1 = f1.parameters[i] + p2 = f2.parameters[i + pad] + + if not strict and p1.is_padding != p2.is_padding: + if p1.is_padding: + pad -= 1 + continue + else: + pad += 1 + p2 = f2.parameters[i + pad] + + if strict and p1.name != p2.name: + raise ValueError("%s: parameter %d name %s != %s" + % (f1.name, i, p1.name, p2.name)) + if p1.type_expr.string() != p2.type_expr.string(): + if (strict or + # special case + f1.name == "TexImage2D" and p1.name != "internalformat"): + raise ValueError("%s: parameter %s type %s != %s" + % (f1.name, p1.name, p1.type_expr.string(), + p2.type_expr.string())) + + def union(self, other): + union = gl_XML.gl_api(None) + + if "enum" in self.elts: + union.enums_by_name = other.enums_by_name.copy() + for key, val in self.api.enums_by_name.iteritems(): + if key not in union.enums_by_name: + union.enums_by_name[key] = val + else: + self._check_enum(val, other.enums_by_name[key]) + + if "type" in self.elts: + union.types_by_name = other.types_by_name.copy() + for key, val in self.api.types_by_name.iteritems(): + if key not in union.types_by_name: + union.types_by_name[key] = val + else: + self._check_type(val, other.types_by_name[key]) + + if "function" in self.elts: + union.functions_by_name = other.functions_by_name.copy() + for key, val in self.api.functions_by_name.iteritems(): + if key not in union.functions_by_name: + union.functions_by_name[key] = val + else: + self._check_function(val, other.functions_by_name[key]) + + return union + + def intersection(self, other): + intersection = gl_XML.gl_api(None) + + if "enum" in self.elts: + for key, val in self.api.enums_by_name.iteritems(): + if key in other.enums_by_name: + self._check_enum(val, other.enums_by_name[key]) + intersection.enums_by_name[key] = val + + if "type" in self.elts: + for key, val in self.api.types_by_name.iteritems(): + if key in other.types_by_name: + self._check_type(val, other.types_by_name[key]) + intersection.types_by_name[key] = val + + if "function" in self.elts: + for key, val in self.api.functions_by_name.iteritems(): + if key in other.functions_by_name: + self._check_function(val, other.functions_by_name[key]) + intersection.functions_by_name[key] = val + + return intersection + + def difference(self, other): + difference = gl_XML.gl_api(None) + + if "enum" in self.elts: + for key, val in self.api.enums_by_name.iteritems(): + if key not in other.enums_by_name: + difference.enums_by_name[key] = val + else: + self._check_enum(val, other.enums_by_name[key]) + + if "type" in self.elts: + for key, val in self.api.types_by_name.iteritems(): + if key not in other.types_by_name: + difference.types_by_name[key] = val + else: + self._check_type(val, other.types_by_name[key]) + + if "function" in self.elts: + for key, val in self.api.functions_by_name.iteritems(): + if key not in other.functions_by_name: + difference.functions_by_name[key] = val + else: + self._check_function(val, other.functions_by_name[key], False) + + return difference + +def cmp_enum(e1, e2): + if e1.value < e2.value: + return -1 + elif e1.value > e2.value: + return 1 + else: + return 0 + +def cmp_type(t1, t2): + return t1.size - t2.size + +def cmp_function(f1, f2): + if f1.name > f2.name: + return 1 + elif f1.name < f2.name: + return -1 + else: + return 0 + +def spaces(n, str=""): + spaces = n - len(str) + if spaces < 1: + spaces = 1 + return " " * spaces + +def output_enum(e, indent=0): + attrs = 'name="%s"' % e.name + if e.default_count > 0: + tab = spaces(37, attrs) + attrs += '%scount="%d"' % (tab, e.default_count) + tab = spaces(48, attrs) + val = "%04x" % e.value + val = "0x" + val.upper() + attrs += '%svalue="%s"' % (tab, val) + + # no child + if not e.functions: + print '%s<enum %s/>' % (spaces(indent), attrs) + return + + print '%s<enum %s>' % (spaces(indent), attrs) + for key, val in e.functions.iteritems(): + attrs = 'name="%s"' % key + if val[0] != e.default_count: + attrs += ' count="%d"' % val[0] + if not val[1]: + attrs += ' mode="get"' + + print '%s<size %s/>' % (spaces(indent * 2), attrs) + + print '%s</enum>' % spaces(indent) + +def output_type(t, indent=0): + tab = spaces(16, t.name) + attrs = 'name="%s"%ssize="%d"' % (t.name, tab, t.size) + ctype = t.type_expr.string() + if ctype.find("unsigned") != -1: + attrs += ' unsigned="true"' + elif ctype.find("signed") == -1: + attrs += ' float="true"' + print '%s<type %s/>' % (spaces(indent), attrs) + +def output_function(f, indent=0): + attrs = 'name="%s"' % f.name + if f.offset > 0: + if f.assign_offset: + attrs += ' offset="assign"' + else: + attrs += ' offset="%d"' % f.offset + print '%s<function %s>' % (spaces(indent), attrs) + + for p in f.parameters: + attrs = 'name="%s" type="%s"' \ + % (p.name, p.type_expr.original_string) + print '%s<param %s/>' % (spaces(indent * 2), attrs) + if f.return_type != "void": + attrs = 'type="%s"' % f.return_type + print '%s<return %s/>' % (spaces(indent * 2), attrs) + + print '%s</function>' % spaces(indent) + +def output_category(api, indent=0): + enums = api.enums_by_name.values() + enums.sort(cmp_enum) + types = api.types_by_name.values() + types.sort(cmp_type) + functions = api.functions_by_name.values() + functions.sort(cmp_function) + + for e in enums: + output_enum(e, indent) + if enums and types: + print + for t in types: + output_type(t, indent) + if enums or types: + print + for f in functions: + output_function(f, indent) + if f != functions[-1]: + print + +def is_api_empty(api): + return bool(not api.enums_by_name and + not api.types_by_name and + not api.functions_by_name) + +def show_usage(ops): + print "Usage: %s [-k elts] <%s> <file1> <file2>" % (sys.argv[0], "|".join(ops)) + print " -k elts A comma separated string of types of elements to" + print " skip. Possible types are enum, type, and function." + sys.exit(1) + +def main(): + ops = ["union", "intersection", "difference"] + elts = ["enum", "type", "function"] + + try: + options, args = getopt.getopt(sys.argv[1:], "k:") + except Exception, e: + show_usage(ops) + + if len(args) != 3: + show_usage(ops) + op, file1, file2 = args + if op not in ops: + show_usage(ops) + + skips = [] + for opt, val in options: + if opt == "-k": + skips = val.split(",") + + for elt in skips: + try: + elts.remove(elt) + except ValueError: + show_usage(ops) + + api1 = gl_XML.parse_GL_API(file1, glX_XML.glx_item_factory()) + api2 = gl_XML.parse_GL_API(file2, glX_XML.glx_item_factory()) + + set = ApiSet(api1, elts) + func = getattr(set, op) + result = func(api2) + + if not is_api_empty(result): + cat_name = "%s_of_%s_and_%s" \ + % (op, os.path.basename(file1), os.path.basename(file2)) + + print '<?xml version="1.0"?>' + print '<!DOCTYPE OpenGLAPI SYSTEM "%s/gl_API.dtd">' % GLAPI + print + print '<OpenGLAPI>' + print + print '<category name="%s">' % (cat_name) + output_category(result, 4) + print '</category>' + print + print '</OpenGLAPI>' + +if __name__ == "__main__": + main() diff --git a/src/mesa/es/glapi/gl_parse_header.py b/src/mesa/es/glapi/gl_parse_header.py new file mode 100644 index 0000000000..8b8d16b395 --- /dev/null +++ b/src/mesa/es/glapi/gl_parse_header.py @@ -0,0 +1,450 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> +# +# 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 +# IBM 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. + +import sys +import os.path +import getopt +import re + +GLAPI = "../../glapi" +sys.path.append(GLAPI) + +class HeaderParser(object): + """Parser for GL header files.""" + + def __init__(self, verbose=0): + # match #if and #ifdef + self.IFDEF = re.compile('#\s*if(n?def\s+(?P<ifdef>\w+)|\s+(?P<if>.+))') + # match #endif + self.ENDIF = re.compile('#\s*endif') + # match typedef abc def; + self.TYPEDEF = re.compile('typedef\s+(?P<from>[\w ]+)\s+(?P<to>\w+);') + # match #define XYZ VAL + self.DEFINE = re.compile('#\s*define\s+(?P<key>\w+)(?P<value>\s+[\w"]*)?') + # match GLAPI + self.GLAPI = re.compile('^GL_?API(CALL)?\s+(?P<return>[\w\s*]+[\w*])\s+(GL)?_?APIENTRY\s+(?P<name>\w+)\s*\((?P<params>[\w\s(,*\[\])]+)\)\s*;') + + self.split_params = re.compile('\s*,\s*') + self.split_ctype = re.compile('(\W)') + # ignore GL_VERSION_X_Y + self.ignore_enum = re.compile('GL(_ES)?_VERSION(_ES_C[ML])?_\d_\d') + + self.verbose = verbose + self._reset() + + def _reset(self): + """Reset to initial state.""" + self.ifdef_levels = [] + self.need_char = False + + # use typeexpr? + def _format_ctype(self, ctype, fix=True): + """Format a ctype string, optionally fix it.""" + # split the type string + tmp = self.split_ctype.split(ctype) + tmp = [s for s in tmp if s and s != " "] + + pretty = "" + for i in xrange(len(tmp)): + # add missing GL prefix + if (fix and tmp[i] != "const" and tmp[i] != "*" and + not tmp[i].startswith("GL")): + tmp[i] = "GL" + tmp[i] + + if i == 0: + pretty = tmp[i] + else: + sep = " " + if tmp[i - 1] == "*": + sep = "" + pretty += sep + tmp[i] + return pretty + + # use typeexpr? + def _get_ctype_attrs(self, ctype): + """Get the attributes of a ctype.""" + is_float = (ctype.find("float") != -1 or ctype.find("double") != -1) + is_signed = not (ctype.find("unsigned") != -1) + + size = 0 + if ctype.find("char") != -1: + size = 1 + elif ctype.find("short") != -1: + size = 2 + elif ctype.find("int") != -1: + size = 4 + elif is_float: + if ctype.find("float") != -1: + size = 4 + else: + size = 8 + + return (size, is_float, is_signed) + + def _parse_define(self, line): + """Parse a #define line for an <enum>.""" + m = self.DEFINE.search(line) + if not m: + if self.verbose and line.find("#define") >= 0: + print "ignore %s" % (line) + return None + + key = m.group("key").strip() + val = m.group("value").strip() + + # enum must begin with GL_ and be all uppercase + if ((not (key.startswith("GL_") and key.isupper())) or + (self.ignore_enum.match(key) and val == "1")): + if self.verbose: + print "ignore enum %s" % (key) + return None + + return (key, val) + + def _parse_typedef(self, line): + """Parse a typedef line for a <type>.""" + m = self.TYPEDEF.search(line) + if not m: + if self.verbose and line.find("typedef") >= 0: + print "ignore %s" % (line) + return None + + f = m.group("from").strip() + t = m.group("to").strip() + if not t.startswith("GL"): + if self.verbose: + print "ignore type %s" % (t) + return None + attrs = self._get_ctype_attrs(f) + + return (f, t, attrs) + + def _parse_gl_api(self, line): + """Parse a GLAPI line for a <function>.""" + m = self.GLAPI.search(line) + if not m: + if self.verbose and line.find("APIENTRY") >= 0: + print "ignore %s" % (line) + return None + + rettype = m.group("return") + rettype = self._format_ctype(rettype) + if rettype == "GLvoid": + rettype = "" + + name = m.group("name") + + param_str = m.group("params") + chunks = self.split_params.split(param_str) + chunks = [s.strip() for s in chunks] + if len(chunks) == 1 and (chunks[0] == "void" or chunks[0] == "GLvoid"): + chunks = [] + + params = [] + for c in chunks: + # split type and variable name + idx = c.rfind("*") + if idx < 0: + idx = c.rfind(" ") + if idx >= 0: + idx += 1 + ctype = c[:idx] + var = c[idx:] + else: + ctype = c + var = "unnamed" + + # convert array to pointer + idx = var.find("[") + if idx >= 0: + var = var[:idx] + ctype += "*" + + ctype = self._format_ctype(ctype) + var = var.strip() + + if not self.need_char and ctype.find("GLchar") >= 0: + self.need_char = True + + params.append((ctype, var)) + + return (rettype, name, params) + + def _change_level(self, line): + """Parse a #ifdef line and change level.""" + m = self.IFDEF.search(line) + if m: + ifdef = m.group("ifdef") + if not ifdef: + ifdef = m.group("if") + self.ifdef_levels.append(ifdef) + return True + m = self.ENDIF.search(line) + if m: + self.ifdef_levels.pop() + return True + return False + + def _read_header(self, header): + """Open a header file and read its contents.""" + lines = [] + try: + fp = open(header, "rb") + lines = fp.readlines() + fp.close() + except IOError, e: + print "failed to read %s: %s" % (header, e) + return lines + + def _cmp_enum(self, enum1, enum2): + """Compare two enums.""" + # sort by length of the values as strings + val1 = enum1[1] + val2 = enum2[1] + ret = len(val1) - len(val2) + # sort by the values + if not ret: + val1 = int(val1, 16) + val2 = int(val2, 16) + ret = val1 - val2 + # in case int cannot hold the result + if ret > 0: + ret = 1 + elif ret < 0: + ret = -1 + # sort by the names + if not ret: + if enum1[0] < enum2[0]: + ret = -1 + elif enum1[0] > enum2[0]: + ret = 1 + return ret + + def _cmp_type(self, type1, type2): + """Compare two types.""" + attrs1 = type1[2] + attrs2 = type2[2] + # sort by type size + ret = attrs1[0] - attrs2[0] + # float is larger + if not ret: + ret = attrs1[1] - attrs2[1] + # signed is larger + if not ret: + ret = attrs1[2] - attrs2[2] + # reverse + ret = -ret + return ret + + def _cmp_function(self, func1, func2): + """Compare two functions.""" + name1 = func1[1] + name2 = func2[1] + ret = 0 + # sort by the names + if name1 < name2: + ret = -1 + elif name1 > name2: + ret = 1 + return ret + + def _postprocess_dict(self, hdict): + """Post-process a header dict and return an ordered list.""" + hlist = [] + largest = 0 + for key, cat in hdict.iteritems(): + size = len(cat["enums"]) + len(cat["types"]) + len(cat["functions"]) + # ignore empty category + if not size: + continue + + cat["enums"].sort(self._cmp_enum) + # remove duplicates + dup = [] + for i in xrange(1, len(cat["enums"])): + if cat["enums"][i] == cat["enums"][i - 1]: + dup.insert(0, i) + for i in dup: + e = cat["enums"].pop(i) + if self.verbose: + print "remove duplicate enum %s" % e[0] + + cat["types"].sort(self._cmp_type) + cat["functions"].sort(self._cmp_function) + + # largest category comes first + if size > largest: + hlist.insert(0, (key, cat)) + largest = size + else: + hlist.append((key, cat)) + return hlist + + def parse(self, header): + """Parse a header file.""" + self._reset() + + if self.verbose: + print "Parsing %s" % (header) + + hdict = {} + lines = self._read_header(header) + for line in lines: + if self._change_level(line): + continue + + # skip until the first ifdef (i.e. __gl_h_) + if not self.ifdef_levels: + continue + + cat_name = os.path.basename(header) + # check if we are in an extension + if (len(self.ifdef_levels) > 1 and + self.ifdef_levels[-1].startswith("GL_")): + cat_name = self.ifdef_levels[-1] + + try: + cat = hdict[cat_name] + except KeyError: + cat = { + "enums": [], + "types": [], + "functions": [] + } + hdict[cat_name] = cat + + key = "enums" + elem = self._parse_define(line) + if not elem: + key = "types" + elem = self._parse_typedef(line) + if not elem: + key = "functions" + elem = self._parse_gl_api(line) + + if elem: + cat[key].append(elem) + + if self.need_char: + if self.verbose: + print "define GLchar" + elem = self._parse_typedef("typedef char GLchar;") + cat["types"].append(elem) + return self._postprocess_dict(hdict) + +def spaces(n, str=""): + spaces = n - len(str) + if spaces < 1: + spaces = 1 + return " " * spaces + +def output_xml(name, hlist): + """Output a parsed header in OpenGLAPI XML.""" + + for i in xrange(len(hlist)): + cat_name, cat = hlist[i] + + print '<category name="%s">' % (cat_name) + indent = 4 + + for enum in cat["enums"]: + name = enum[0][3:] + value = enum[1] + tab = spaces(41, name) + attrs = 'name="%s"%svalue="%s"' % (name, tab, value) + print '%s<enum %s/>' % (spaces(indent), attrs) + + if cat["enums"] and cat["types"]: + print + + for type in cat["types"]: + ctype = type[0] + size, is_float, is_signed = type[2] + + attrs = 'name="%s"' % (type[1][2:]) + attrs += spaces(16, attrs) + 'size="%d"' % (size) + if is_float: + attrs += ' float="true"' + elif not is_signed: + attrs += ' unsigned="true"' + + print '%s<type %s/>' % (spaces(indent), attrs) + + for func in cat["functions"]: + print + ret = func[0] + name = func[1][2:] + params = func[2] + + attrs = 'name="%s" offset="assign"' % name + print '%s<function %s>' % (spaces(indent), attrs) + + for param in params: + attrs = 'name="%s" type="%s"' % (param[1], param[0]) + print '%s<param %s/>' % (spaces(indent * 2), attrs) + if ret: + attrs = 'type="%s"' % ret + print '%s<return %s/>' % (spaces(indent * 2), attrs) + + print '%s</function>' % spaces(indent) + + print '</category>' + print + +def show_usage(): + print "Usage: %s [-v] <header> ..." % sys.argv[0] + sys.exit(1) + +def main(): + try: + args, headers = getopt.getopt(sys.argv[1:], "v") + except Exception, e: + show_usage() + if not headers: + show_usage() + + verbose = 0 + for arg in args: + if arg[0] == "-v": + verbose += 1 + + need_xml_header = True + parser = HeaderParser(verbose) + for h in headers: + h = os.path.abspath(h) + hlist = parser.parse(h) + + if need_xml_header: + print '<?xml version="1.0"?>' + print '<!DOCTYPE OpenGLAPI SYSTEM "%s/gl_API.dtd">' % GLAPI + need_xml_header = False + + print + print '<!-- %s -->' % (h) + print '<OpenGLAPI>' + print + output_xml(h, hlist) + print '</OpenGLAPI>' + +if __name__ == '__main__': + main() diff --git a/src/mesa/es/main/APIspec.dtd b/src/mesa/es/main/APIspec.dtd new file mode 100644 index 0000000000..efcfa31f10 --- /dev/null +++ b/src/mesa/es/main/APIspec.dtd @@ -0,0 +1,52 @@ +<!ELEMENT apispec (template|api)+> + +<!ELEMENT api (category*, function*)> +<!ELEMENT category EMPTY> +<!ELEMENT function EMPTY> + +<!ELEMENT template (proto, desc*)> +<!ELEMENT proto (return, (param|vector)*)> +<!ELEMENT return EMPTY> +<!ELEMENT param EMPTY> +<!ELEMENT vector (param*)> +<!ELEMENT desc ((value|range)*, desc*)> +<!ELEMENT value EMPTY> +<!ELEMENT range EMPTY> + +<!ATTLIST api name NMTOKEN #REQUIRED + implementation (true | false) "false"> +<!ATTLIST category name NMTOKEN #REQUIRED> +<!ATTLIST function name NMTOKEN #REQUIRED + default_prefix NMTOKEN "_mesa_" + external (true | false) "false" + template NMTOKEN #REQUIRED + gltype CDATA #IMPLIED + vector_size NMTOKEN #IMPLIED + expand_vector (true | false) "false" + skip_desc (true | false) "false"> + +<!ATTLIST template name NMTOKEN #REQUIRED + direction (set | get) "set"> + +<!ATTLIST return type CDATA #REQUIRED> +<!ATTLIST param name NMTOKEN #REQUIRED + type CDATA #REQUIRED + hide_if_expanded (true | false) "false" + category NMTOKEN #IMPLIED> +<!ATTLIST vector name NMTOKEN #REQUIRED + type CDATA #REQUIRED + size NMTOKEN #REQUIRED + category NMTOKEN #IMPLIED> + +<!ATTLIST desc name NMTOKEN #REQUIRED + vector_size CDATA #IMPLIED + convert (true | false) #IMPLIED + error NMTOKEN "GL_INVALID_ENUM" + category NMTOKEN #IMPLIED> + +<!ATTLIST value name CDATA #REQUIRED + category NMTOKEN #IMPLIED> +<!ATTLIST range from NMTOKEN #REQUIRED + to NMTOKEN #REQUIRED + base NMTOKEN #IMPLIED + category NMTOKEN #IMPLIED> diff --git a/src/mesa/es/main/APIspec.py b/src/mesa/es/main/APIspec.py new file mode 100644 index 0000000000..6947f7301c --- /dev/null +++ b/src/mesa/es/main/APIspec.py @@ -0,0 +1,617 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> +# +# 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 +# IBM 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. +""" +A parser for APIspec. +""" + +class SpecError(Exception): + """Error in the spec file.""" + + +class Spec(object): + """A Spec is an abstraction of the API spec.""" + + def __init__(self, doc): + self.doc = doc + + self.spec_node = doc.getRootElement() + self.tmpl_nodes = {} + self.api_nodes = {} + self.impl_node = None + + # parse <apispec> + node = self.spec_node.children + while node: + if node.type == "element": + if node.name == "template": + self.tmpl_nodes[node.prop("name")] = node + elif node.name == "api": + self.api_nodes[node.prop("name")] = node + else: + raise SpecError("unexpected node %s in apispec" % + node.name) + node = node.next + + # find an implementation + for name, node in self.api_nodes.iteritems(): + if node.prop("implementation") == "true": + self.impl_node = node + break + if not self.impl_node: + raise SpecError("unable to find an implementation") + + def get_impl(self): + """Return the implementation.""" + return API(self, self.impl_node) + + def get_api(self, name): + """Return an API.""" + return API(self, self.api_nodes[name]) + + +class API(object): + """An API consists of categories and functions.""" + + def __init__(self, spec, api_node): + self.name = api_node.prop("name") + self.is_impl = (api_node.prop("implementation") == "true") + + self.categories = [] + self.functions = [] + + # parse <api> + func_nodes = [] + node = api_node.children + while node: + if node.type == "element": + if node.name == "category": + cat = node.prop("name") + self.categories.append(cat) + elif node.name == "function": + func_nodes.append(node) + else: + raise SpecError("unexpected node %s in api" % node.name) + node = node.next + + # realize functions + for func_node in func_nodes: + tmpl_node = spec.tmpl_nodes[func_node.prop("template")] + try: + func = Function(tmpl_node, func_node, self.is_impl, + self.categories) + except SpecError, e: + func_name = func_node.prop("name") + raise SpecError("failed to parse %s: %s" % (func_name, e)) + self.functions.append(func) + + def match(self, func, conversions={}): + """Find a matching function in the API.""" + match = None + need_conv = False + for f in self.functions: + matched, conv = f.match(func, conversions) + if matched: + match = f + need_conv = conv + # exact match + if not need_conv: + break + return (match, need_conv) + + +class Function(object): + """Parse and realize a <template> node.""" + + def __init__(self, tmpl_node, func_node, force_skip_desc=False, categories=[]): + self.tmpl_name = tmpl_node.prop("name") + self.direction = tmpl_node.prop("direction") + + self.name = func_node.prop("name") + self.prefix = func_node.prop("default_prefix") + self.is_external = (func_node.prop("external") == "true") + + if force_skip_desc: + self._skip_desc = True + else: + self._skip_desc = (func_node.prop("skip_desc") == "true") + + self._categories = categories + + # these attributes decide how the template is realized + self._gltype = func_node.prop("gltype") + if func_node.hasProp("vector_size"): + self._vector_size = int(func_node.prop("vector_size")) + else: + self._vector_size = 0 + self._expand_vector = (func_node.prop("expand_vector") == "true") + + self.return_type = "void" + param_nodes = [] + + # find <proto> + proto_node = tmpl_node.children + while proto_node: + if proto_node.type == "element" and proto_node.name == "proto": + break + proto_node = proto_node.next + if not proto_node: + raise SpecError("no proto") + # and parse it + node = proto_node.children + while node: + if node.type == "element": + if node.name == "return": + self.return_type = node.prop("type") + elif node.name == "param" or node.name == "vector": + if self.support_node(node): + # make sure the node is not hidden + if not (self._expand_vector and + (node.prop("hide_if_expanded") == "true")): + param_nodes.append(node) + else: + raise SpecError("unexpected node %s in proto" % node.name) + node = node.next + + self._init_params(param_nodes) + self._init_descs(tmpl_node, param_nodes) + + def __str__(self): + return "%s %s%s(%s)" % (self.return_type, self.prefix, self.name, + self.param_string(True)) + + def _init_params(self, param_nodes): + """Parse and initialize parameters.""" + self.params = [] + + for param_node in param_nodes: + size = self.param_node_size(param_node) + # when no expansion, vector is just like param + if param_node.name == "param" or not self._expand_vector: + param = Parameter(param_node, self._gltype, size) + self.params.append(param) + continue + + if not size or size > param_node.lsCountNode(): + raise SpecError("could not expand %s with unknown or " + "mismatch sizes" % param.name) + + # expand the vector + expanded_params = [] + child = param_node.children + while child: + if (child.type == "element" and child.name == "param" and + self.support_node(child)): + expanded_params.append(Parameter(child, self._gltype)) + if len(expanded_params) == size: + break + child = child.next + # just in case that lsCountNode counts unknown nodes + if len(expanded_params) < size: + raise SpecError("not enough named parameters") + + self.params.extend(expanded_params) + + def _init_descs(self, tmpl_node, param_nodes): + """Parse and initialize parameter descriptions.""" + self.checker = Checker() + if self._skip_desc: + return + + node = tmpl_node.children + while node: + if node.type == "element" and node.name == "desc": + if self.support_node(node): + # parse <desc> + desc = Description(node, self._categories) + self.checker.add_desc(desc) + node = node.next + + self.checker.validate(self, param_nodes) + + def support_node(self, node): + """Return true if a node is in the supported category.""" + return (not node.hasProp("category") or + node.prop("category") in self._categories) + + def get_param(self, name): + """Return the named parameter.""" + for param in self.params: + if param.name == name: + return param + return None + + def param_node_size(self, param): + """Return the size of a vector.""" + if param.name != "vector": + return 0 + + size = param.prop("size") + if size.isdigit(): + size = int(size) + else: + size = 0 + if not size: + size = self._vector_size + if not size and self._expand_vector: + # return the number of named parameters + size = param.lsCountNode() + return size + + def param_string(self, declaration): + """Return the C code of the parameters.""" + args = [] + if declaration: + for param in self.params: + sep = "" if param.type.endswith("*") else " " + args.append("%s%s%s" % (param.type, sep, param.name)) + if not args: + args.append("void") + else: + for param in self.params: + args.append(param.name) + return ", ".join(args) + + def match(self, other, conversions={}): + """Return true if the functions match, probably with a conversion.""" + if (self.tmpl_name != other.tmpl_name or + self.return_type != other.return_type or + len(self.params) != len(other.params)): + return (False, False) + + need_conv = False + for i in xrange(len(self.params)): + src = other.params[i] + dst = self.params[i] + if (src.is_vector != dst.is_vector or src.size != dst.size): + return (False, False) + if src.type != dst.type: + if dst.base_type() in conversions.get(src.base_type(), []): + need_conv = True + else: + # unable to convert + return (False, False) + + return (True, need_conv) + + +class Parameter(object): + """A parameter of a function.""" + + def __init__(self, param_node, gltype=None, size=0): + self.is_vector = (param_node.name == "vector") + + self.name = param_node.prop("name") + self.size = size + + type = param_node.prop("type") + if gltype: + type = type.replace("GLtype", gltype) + elif type.find("GLtype") != -1: + raise SpecError("parameter %s has unresolved type" % self.name) + + self.type = type + + def base_type(self): + """Return the base GL type by stripping qualifiers.""" + return [t for t in self.type.split(" ") if t.startswith("GL")][0] + + +class Checker(object): + """A checker is the collection of all descriptions on the same level. + Descriptions of the same parameter are concatenated. + """ + + def __init__(self): + self.switches = {} + self.switch_constants = {} + + def add_desc(self, desc): + """Add a description.""" + # TODO allow index to vary + const_attrs = ["index", "error", "convert", "size_str"] + if desc.name not in self.switches: + self.switches[desc.name] = [] + self.switch_constants[desc.name] = {} + for attr in const_attrs: + self.switch_constants[desc.name][attr] = None + + # some attributes, like error code, should be the same for all descs + consts = self.switch_constants[desc.name] + for attr in const_attrs: + if getattr(desc, attr) is not None: + if (consts[attr] is not None and + consts[attr] != getattr(desc, attr)): + raise SpecError("mismatch %s for %s" % (attr, desc.name)) + consts[attr] = getattr(desc, attr) + + self.switches[desc.name].append(desc) + + def validate(self, func, param_nodes): + """Validate the checker against a function.""" + tmp = Checker() + + for switch in self.switches.itervalues(): + valid_descs = [] + for desc in switch: + if desc.validate(func, param_nodes): + valid_descs.append(desc) + # no possible values + if not valid_descs: + return False + for desc in valid_descs: + if not desc._is_noop: + tmp.add_desc(desc) + + self.switches = tmp.switches + self.switch_constants = tmp.switch_constants + return True + + def flatten(self, name=None): + """Return a flat list of all descriptions of the named parameter.""" + flat_list = [] + for switch in self.switches.itervalues(): + for desc in switch: + if not name or desc.name == name: + flat_list.append(desc) + flat_list.extend(desc.checker.flatten(name)) + return flat_list + + def always_check(self, name): + """Return true if the parameter is checked in all possible pathes.""" + if name in self.switches: + return True + + # a param is always checked if any of the switch always checks it + for switch in self.switches.itervalues(): + # a switch always checks it if all of the descs always check it + always = True + for desc in switch: + if not desc.checker.always_check(name): + always = False + break + if always: + return True + return False + + def _c_switch(self, name, indent="\t"): + """Output C switch-statement for the named parameter, for debug.""" + switch = self.switches.get(name, []) + # make sure there are valid values + need_switch = False + for desc in switch: + if desc.values: + need_switch = True + if not need_switch: + return [] + + stmts = [] + var = switch[0].name + if switch[0].index >= 0: + var += "[%d]" % switch[0].index + stmts.append("switch (%s) { /* assume GLenum */" % var) + + for desc in switch: + if desc.values: + for val in desc.values: + stmts.append("case %s:" % val) + for dep_name in desc.checker.switches.iterkeys(): + dep_stmts = [indent + s for s in desc.checker._c_switch(dep_name, indent)] + stmts.extend(dep_stmts) + stmts.append(indent + "break;") + + stmts.append("default:") + stmts.append(indent + "ON_ERROR(%s);" % switch[0].error); + stmts.append(indent + "break;") + stmts.append("}") + + return stmts + + def dump(self, indent="\t"): + """Dump the descriptions in C code.""" + stmts = [] + for name in self.switches.iterkeys(): + c_switch = self._c_switch(name) + print "\n".join(c_switch) + + +class Description(object): + """A description desribes a parameter and its relationship with other + parameters. + """ + + def __init__(self, desc_node, categories=[]): + self._categories = categories + self._is_noop = False + + self.name = desc_node.prop("name") + self.index = -1 + + self.error = desc_node.prop("error") or "GL_INVALID_ENUM" + # vector_size may be C code + self.size_str = desc_node.prop("vector_size") + + self._has_enum = False + self.values = [] + dep_nodes = [] + + # parse <desc> + valid_names = ["value", "range", "desc"] + node = desc_node.children + while node: + if node.type == "element": + if node.name in valid_names: + # ignore nodes that require unsupported categories + if (node.prop("category") and + node.prop("category") not in self._categories): + node = node.next + continue + else: + raise SpecError("unexpected node %s in desc" % node.name) + + if node.name == "value": + val = node.prop("name") + if not self._has_enum and val.startswith("GL_"): + self._has_enum = True + self.values.append(val) + elif node.name == "range": + first = int(node.prop("from")) + last = int(node.prop("to")) + base = node.prop("base") or "" + if not self._has_enum and base.startswith("GL_"): + self._has_enum = True + # expand range + for i in xrange(first, last + 1): + self.values.append("%s%d" % (base, i)) + else: # dependent desc + dep_nodes.append(node) + node = node.next + + # default to convert if there is no enum + self.convert = not self._has_enum + if desc_node.hasProp("convert"): + self.convert = (desc_node.prop("convert") == "true") + + self._init_deps(dep_nodes) + + def _init_deps(self, dep_nodes): + """Parse and initialize dependents.""" + self.checker = Checker() + + for dep_node in dep_nodes: + # recursion! + dep = Description(dep_node, self._categories) + self.checker.add_desc(dep) + + def _search_param_node(self, param_nodes, name=None): + """Search the template parameters for the named node.""" + param_node = None + param_index = -1 + + if not name: + name = self.name + for node in param_nodes: + if name == node.prop("name"): + param_node = node + elif node.name == "vector": + child = node.children + idx = 0 + while child: + if child.type == "element" and child.name == "param": + if name == child.prop("name"): + param_node = node + param_index = idx + break + idx += 1 + child = child.next + if param_node: + break + return (param_node, param_index) + + def _find_final(self, func, param_nodes): + """Find the final parameter.""" + param = func.get_param(self.name) + param_index = -1 + + # the described param is not in the final function + if not param: + # search the template parameters + node, index = self._search_param_node(param_nodes) + if not node: + raise SpecError("invalid desc %s in %s" % + (self.name, func.name)) + + # a named parameter of a vector + if index >= 0: + param = func.get_param(node.prop("name")) + param_index = index + elif node.name == "vector": + # must be an expanded vector, check its size + if self.size_str and self.size_str.isdigit(): + size = int(self.size_str) + expanded_size = func.param_node_size(node) + if size != expanded_size: + return (False, None, -1) + # otherwise, it is a valid, but no-op, description + + return (True, param, param_index) + + def validate(self, func, param_nodes): + """Validate a description against certain function.""" + if self.checker.switches and not self.values: + raise SpecError("no valid values for %s" % self.name) + + valid, param, param_index = self._find_final(func, param_nodes) + if not valid: + return False + + # the description is valid, but the param is gone + # mark it no-op so that it will be skipped + if not param: + self._is_noop = True + return True + + if param.is_vector: + # if param was known, this should have been done in __init__ + if self._has_enum: + self.size_str = "1" + # size mismatch + if (param.size and self.size_str and self.size_str.isdigit() and + param.size != int(self.size_str)): + return False + elif self.size_str: + # only vector accepts vector_size + raise SpecError("vector_size is invalid for %s" % param.name) + + if not self.checker.validate(func, param_nodes): + return False + + # update the description + self.name = param.name + self.index = param_index + + return True + + +def main(): + import libxml2 + + filename = "APIspec.xml" + apinames = ["GLES1.1", "GLES2.0"] + + doc = libxml2.readFile(filename, None, + libxml2.XML_PARSE_DTDLOAD + + libxml2.XML_PARSE_DTDVALID + + libxml2.XML_PARSE_NOBLANKS) + + spec = Spec(doc) + impl = spec.get_impl() + for apiname in apinames: + spec.get_api(apiname) + + doc.freeDoc() + + print "%s is successfully parsed" % filename + + +if __name__ == "__main__": + main() diff --git a/src/mesa/es/main/APIspec.xml b/src/mesa/es/main/APIspec.xml new file mode 100644 index 0000000000..f6f33130b1 --- /dev/null +++ b/src/mesa/es/main/APIspec.xml @@ -0,0 +1,4297 @@ +<?xml version="1.0"?> +<!DOCTYPE apispec SYSTEM "APIspec.dtd"> + +<!-- A function is generated from a template. Multiple functions can be + generated from a single template with different arguments. For example, + glColor3f can be generated from + + <function name="Color3f" template="Color" gltype="GLfloat" vector_size="3" expand_vector="true"/> + + and glColor4iv can be generated from + + <function name="Color4iv" template="Color" gltype="GLint" vector_size="4"/> + + In a template, there are <desc>s that describe the properties of + parameters. A <desc> can enumerate the valid values of a parameter. It + can also specify the error code when an invalid value is given, and etc. + By nesting <desc>s, they can create dependency between parameters. + + A function can be marked as external. It means that the function cannot + be dispatched to the corresponding mesa function, if one exists, directly, + and requires an external implementation. +--> + +<apispec> + +<template name="Color"> + <proto> + <return type="void"/> + <vector name="v" type="const GLtype *" size="dynamic"> + <param name="red" type="GLtype"/> + <param name="green" type="GLtype"/> + <param name="blue" type="GLtype"/> + <param name="alpha" type="GLtype"/> + </vector> + </proto> +</template> + +<template name="ClipPlane"> + <proto> + <return type="void"/> + <param name="plane" type="GLenum"/> + <vector name="equation" type="const GLtype *" size="4"/> + </proto> + + <desc name="plane"> + <range base="GL_CLIP_PLANE" from="0" to="5"/> + </desc> +</template> + +<template name="CullFace"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="mode"> + <value name="GL_FRONT"/> + <value name="GL_BACK"/> + <value name="GL_FRONT_AND_BACK"/> + </desc> +</template> + +<template name="Fog"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="pname"> + <value name="GL_FOG_MODE"/> + <desc name="param"> + <value name="GL_EXP"/> + <value name="GL_EXP2"/> + <value name="GL_LINEAR"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_FOG_COLOR"/> + + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_FOG_DENSITY"/> + <value name="GL_FOG_START"/> + <value name="GL_FOG_END"/> + + <desc name="params" vector_size="1"/> + </desc> +</template> + +<template name="FrontFace"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="mode"> + <value name="GL_CW"/> + <value name="GL_CCW"/> + </desc> +</template> + +<template name="Hint"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="target" category="GLES1.1"> + <value name="GL_FOG_HINT"/> + <value name="GL_LINE_SMOOTH_HINT"/> + <value name="GL_PERSPECTIVE_CORRECTION_HINT"/> + <value name="GL_POINT_SMOOTH_HINT"/> + </desc> + <desc name="target" category="OES_standard_derivatives"> + <value name="GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES"/> + </desc> + <desc name="target"> + <value name="GL_GENERATE_MIPMAP_HINT"/> + </desc> + + <desc name="mode"> + <value name="GL_FASTEST"/> + <value name="GL_NICEST"/> + <value name="GL_DONT_CARE"/> + </desc> +</template> + +<template name="Light"> + <proto> + <return type="void"/> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="light"> + <range base="GL_LIGHT" from="0" to="7"/> + </desc> + + <desc name="pname"> + <value name="GL_AMBIENT"/> + <value name="GL_DIFFUSE"/> + <value name="GL_SPECULAR"/> + <value name="GL_POSITION"/> + + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_SPOT_DIRECTION"/> + + <desc name="params" vector_size="3"/> + </desc> + + <desc name="pname"> + <value name="GL_SPOT_EXPONENT"/> + <value name="GL_SPOT_CUTOFF"/> + <value name="GL_CONSTANT_ATTENUATION"/> + <value name="GL_LINEAR_ATTENUATION"/> + <value name="GL_QUADRATIC_ATTENUATION"/> + + <desc name="params" vector_size="1"/> + </desc> +</template> + +<template name="LightModel"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="pname"> + <value name="GL_LIGHT_MODEL_AMBIENT"/> + + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_LIGHT_MODEL_TWO_SIDE"/> + <desc name="param"> + <value name="GL_TRUE"/> + <value name="GL_FALSE"/> + </desc> + </desc> +</template> + +<template name="LineWidth"> + <proto> + <return type="void"/> + <param name="width" type="GLtype"/> + </proto> +</template> + +<template name="Material"> + <proto> + <return type="void"/> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="face"> + <value name="GL_FRONT_AND_BACK"/> + </desc> + + <desc name="pname"> + <value name="GL_AMBIENT"/> + <value name="GL_DIFFUSE"/> + <value name="GL_AMBIENT_AND_DIFFUSE"/> + <value name="GL_SPECULAR"/> + <value name="GL_EMISSION"/> + + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_SHININESS"/> + + <desc name="params" vector_size="1"/> + </desc> +</template> + +<template name="PointSize"> + <proto> + <return type="void"/> + <param name="size" type="GLtype"/> + </proto> +</template> + +<template name="PointSizePointer"> + <proto> + <return type="void"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="type"> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + </desc> +</template> + +<template name="Scissor"> + <proto> + <return type="void"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </proto> +</template> + +<template name="ShadeModel"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="mode"> + <value name="GL_FLAT"/> + <value name="GL_SMOOTH"/> + </desc> +</template> + +<template name="TexParameter"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_3D_OES" category="OES_texture_3D"/> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_WRAP_S"/> + <value name="GL_TEXTURE_WRAP_T"/> + <value name="GL_TEXTURE_WRAP_R_OES" category="OES_texture_3D"/> + + <desc name="param"> + <value name="GL_CLAMP_TO_EDGE"/> + <value name="GL_REPEAT"/> + <value name="GL_MIRRORED_REPEAT" category="GLES2.0"/> + <value name="GL_MIRRORED_REPEAT_OES" category="OES_texture_mirrored_repeat"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_MIN_FILTER"/> + + <desc name="param"> + <value name="GL_NEAREST"/> + <value name="GL_LINEAR"/> + <value name="GL_NEAREST_MIPMAP_NEAREST"/> + <value name="GL_NEAREST_MIPMAP_LINEAR"/> + <value name="GL_LINEAR_MIPMAP_NEAREST"/> + <value name="GL_LINEAR_MIPMAP_LINEAR"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_MAG_FILTER"/> + + <desc name="param"> + <value name="GL_NEAREST"/> + <value name="GL_LINEAR"/> + </desc> + </desc> + + <desc name="pname" category="GLES1.1"> + <value name="GL_GENERATE_MIPMAP"/> + + <desc name="param"> + <value name="GL_TRUE"/> + <value name="GL_FALSE"/> + </desc> + </desc> + + <desc name="pname" category="EXT_texture_filter_anisotropic"> + <value name="GL_TEXTURE_MAX_ANISOTROPY_EXT"/> + <desc name="params" vector_size="1"/> + </desc> + + <desc name="pname" category="OES_draw_texture"> + <value name="GL_TEXTURE_CROP_RECT_OES"/> + <desc name="params" vector_size="4"/> + </desc> +</template> + +<template name="TexImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalFormat" type="GLint"/> <!-- should be GLenum --> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="internalFormat" error="GL_INVALID_VALUE"> + <value name="GL_ALPHA"/> + <value name="GL_RGB"/> + <value name="GL_RGBA"/> + <value name="GL_LUMINANCE"/> + <value name="GL_LUMINANCE_ALPHA"/> + <value name="GL_DEPTH_COMPONENT" category="OES_depth_texture"/> + <value name="GL_DEPTH_STENCIL_OES" category="OES_packed_depth_stencil"/> + </desc> + + <desc name="border" error="GL_INVALID_VALUE"> + <value name="0"/> + </desc> + + <desc name="format"> + <value name="GL_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGB"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_5_6_5"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGBA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4"/> + <value name="GL_UNSIGNED_SHORT_5_5_5_1"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format" category="OES_depth_texture"> + <value name="GL_DEPTH_COMPONENT"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_SHORT"/> + <value name="GL_UNSIGNED_INT"/> + </desc> + </desc> + + <desc name="format" category="OES_packed_depth_stencil"> + <value name="GL_DEPTH_STENCIL_OES"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_INT_24_8_OES"/> + </desc> + </desc> +</template> + +<template name="TexEnv"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="target" category="OES_point_sprite"> + <value name="GL_POINT_SPRITE_OES"/> + + <desc name="pname"> + <value name="GL_COORD_REPLACE_OES"/> + </desc> + </desc> + + <desc name="pname" category="OES_point_sprite"> + <value name="GL_COORD_REPLACE_OES"/> + + <desc name="param"> + <value name="GL_TRUE"/> + <value name="GL_FALSE"/> + </desc> + </desc> + + <desc name="target" category="EXT_texture_lod_bias"> + <value name="GL_TEXTURE_FILTER_CONTROL_EXT"/> + + <desc name="pname"> + <value name="GL_TEXTURE_LOD_BIAS_EXT"/> + </desc> + </desc> + + <desc name="pname" category="EXT_texture_lod_bias"> + <value name="GL_TEXTURE_LOD_BIAS_EXT"/> + <desc name="params" vector_size="1"/> + </desc> + + <desc name="target"> + <value name="GL_TEXTURE_ENV"/> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_MODE"/> + <value name="GL_COMBINE_RGB"/> + <value name="GL_COMBINE_ALPHA"/> + <value name="GL_RGB_SCALE"/> + <value name="GL_ALPHA_SCALE"/> + <value name="GL_SRC0_RGB"/> + <value name="GL_SRC1_RGB"/> + <value name="GL_SRC2_RGB"/> + <value name="GL_SRC0_ALPHA"/> + <value name="GL_SRC1_ALPHA"/> + <value name="GL_SRC2_ALPHA"/> + <value name="GL_OPERAND0_RGB"/> + <value name="GL_OPERAND1_RGB"/> + <value name="GL_OPERAND2_RGB"/> + <value name="GL_OPERAND0_ALPHA"/> + <value name="GL_OPERAND1_ALPHA"/> + <value name="GL_OPERAND2_ALPHA"/> + <value name="GL_TEXTURE_ENV_COLOR"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_MODE"/> + + <desc name="param"> + <value name="GL_REPLACE"/> + <value name="GL_MODULATE"/> + <value name="GL_DECAL"/> + <value name="GL_BLEND"/> + <value name="GL_ADD"/> + <value name="GL_COMBINE"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_COMBINE_RGB"/> + + <desc name="param"> + <value name="GL_REPLACE"/> + <value name="GL_MODULATE"/> + <value name="GL_ADD"/> + <value name="GL_ADD_SIGNED"/> + <value name="GL_INTERPOLATE"/> + <value name="GL_SUBTRACT"/> + <value name="GL_DOT3_RGB"/> + <value name="GL_DOT3_RGBA"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_COMBINE_ALPHA"/> + + <desc name="param"> + <value name="GL_REPLACE"/> + <value name="GL_MODULATE"/> + <value name="GL_ADD"/> + <value name="GL_ADD_SIGNED"/> + <value name="GL_INTERPOLATE"/> + <value name="GL_SUBTRACT"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_RGB_SCALE"/> + <value name="GL_ALPHA_SCALE"/> + + <desc name="param" convert="true" error="GL_INVALID_VALUE"> + <value name="1.0"/> + <value name="2.0"/> + <value name="4.0"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_SRC0_RGB"/> + <value name="GL_SRC1_RGB"/> + <value name="GL_SRC2_RGB"/> + <value name="GL_SRC0_ALPHA"/> + <value name="GL_SRC1_ALPHA"/> + <value name="GL_SRC2_ALPHA"/> + + <desc name="param"> + <value name="GL_TEXTURE"/> + <value name="GL_CONSTANT"/> + <value name="GL_PRIMARY_COLOR"/> + <value name="GL_PREVIOUS"/> + + <range base="GL_TEXTURE" from="0" to="31" category="OES_texture_env_crossbar"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_OPERAND0_RGB"/> + <value name="GL_OPERAND1_RGB"/> + <value name="GL_OPERAND2_RGB"/> + + <desc name="param"> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_OPERAND0_ALPHA"/> + <value name="GL_OPERAND1_ALPHA"/> + <value name="GL_OPERAND2_ALPHA"/> + + <desc name="param"> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_COLOR"/> + + <desc name="params" vector_size="4"/> + </desc> +</template> + +<template name="TexGen"> + <proto> + <return type="void"/> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="coord" category="OES_texture_cube_map"> + <value name="GL_TEXTURE_GEN_STR_OES"/> + </desc> + + <desc name="pname" category="OES_texture_cube_map"> + <value name="GL_TEXTURE_GEN_MODE_OES"/> + + <desc name="param"> + <value name="GL_NORMAL_MAP_OES"/> + <value name="GL_REFLECTION_MAP_OES"/> + </desc> + </desc> +</template> + +<template name="Clear"> + <proto> + <return type="void"/> + <param name="mask" type="GLbitfield"/> + </proto> + + <desc name="mask" error="GL_INVALID_VALUE"> + <value name="0"/> + <value name="(GL_COLOR_BUFFER_BIT)"/> + <value name="(GL_DEPTH_BUFFER_BIT)"/> + <value name="(GL_STENCIL_BUFFER_BIT)"/> + <value name="(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)"/> + <value name="(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)"/> + <value name="(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)"/> + <value name="(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)"/> + </desc> +</template> + +<template name="ClearColor"> + <proto> + <return type="void"/> + <param name="red" type="GLtype"/> + <param name="green" type="GLtype"/> + <param name="blue" type="GLtype"/> + <param name="alpha" type="GLtype"/> + </proto> +</template> + +<template name="ClearStencil"> + <proto> + <return type="void"/> + <param name="s" type="GLint"/> + </proto> +</template> + +<template name="ClearDepth"> + <proto> + <return type="void"/> + <param name="depth" type="GLtype"/> + </proto> +</template> + +<template name="StencilMask"> + <proto> + <return type="void"/> + <param name="mask" type="GLuint"/> + </proto> +</template> + +<template name="StencilMaskSeparate"> + <proto> + <return type="void"/> + <param name="face" type="GLenum"/> + <param name="mask" type="GLuint"/> + </proto> + + <desc name="face"> + <value name="GL_FRONT"/> + <value name="GL_BACK"/> + <value name="GL_FRONT_AND_BACK"/> + </desc> +</template> + +<template name="ColorMask"> + <proto> + <return type="void"/> + <param name="red" type="GLboolean"/> + <param name="green" type="GLboolean"/> + <param name="blue" type="GLboolean"/> + <param name="alpha" type="GLboolean"/> + </proto> +</template> + +<template name="DepthMask"> + <proto> + <return type="void"/> + <param name="flag" type="GLboolean"/> + </proto> +</template> + +<template name="Disable"> + <proto> + <return type="void"/> + <param name="cap" type="GLenum"/> + </proto> + + <desc name="cap" category="GLES1.1"> + <value name="GL_NORMALIZE"/> + <value name="GL_RESCALE_NORMAL"/> + + <range base="GL_CLIP_PLANE" from="0" to="5"/> + + <value name="GL_FOG"/> + <value name="GL_LIGHTING"/> + <value name="GL_COLOR_MATERIAL"/> + + <range base="GL_LIGHT" from="0" to="7"/> + + <value name="GL_POINT_SMOOTH"/> + <value name="GL_LINE_SMOOTH"/> + <value name="GL_CULL_FACE"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_MULTISAMPLE"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_ALPHA_TO_ONE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_TEXTURE_2D"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_ALPHA_TEST"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_BLEND"/> + <value name="GL_DITHER"/> + <value name="GL_COLOR_LOGIC_OP"/> + + <value name="GL_POINT_SPRITE_OES" category="OES_point_sprite"/> + <value name="GL_MATRIX_PALETTE_OES" category="OES_matrix_palette"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_GEN_STR_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="cap" category="GLES2.0"> + <value name="GL_CULL_FACE"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_DITHER"/> + <value name="GL_BLEND"/> + </desc> +</template> + +<!-- it is exactly the same as Disable --> +<template name="Enable"> + <proto> + <return type="void"/> + <param name="cap" type="GLenum"/> + </proto> + + <desc name="cap" category="GLES1.1"> + <value name="GL_NORMALIZE"/> + <value name="GL_RESCALE_NORMAL"/> + + <range base="GL_CLIP_PLANE" from="0" to="5"/> + + <value name="GL_FOG"/> + <value name="GL_LIGHTING"/> + <value name="GL_COLOR_MATERIAL"/> + + <range base="GL_LIGHT" from="0" to="7"/> + + <value name="GL_POINT_SMOOTH"/> + <value name="GL_LINE_SMOOTH"/> + <value name="GL_CULL_FACE"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_MULTISAMPLE"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_ALPHA_TO_ONE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_TEXTURE_2D"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_ALPHA_TEST"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_BLEND"/> + <value name="GL_DITHER"/> + <value name="GL_COLOR_LOGIC_OP"/> + + <value name="GL_POINT_SPRITE_OES" category="OES_point_sprite"/> + <value name="GL_MATRIX_PALETTE_OES" category="OES_matrix_palette"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_GEN_STR_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="cap" category="GLES2.0"> + <value name="GL_CULL_FACE"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_DITHER"/> + <value name="GL_BLEND"/> + </desc> +</template> + +<template name="Finish"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="Flush"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="AlphaFunc"> + <proto> + <return type="void"/> + <param name="func" type="GLenum"/> + <param name="ref" type="GLtype"/> + </proto> + <desc name="func"> + <value name="GL_NEVER"/> + <value name="GL_LESS"/> + <value name="GL_EQUAL"/> + <value name="GL_LEQUAL"/> + <value name="GL_GREATER"/> + <value name="GL_NOTEQUAL"/> + <value name="GL_GEQUAL"/> + <value name="GL_ALWAYS"/> + </desc> +</template> + +<template name="BlendFunc"> + <proto> + <return type="void"/> + <param name="sfactor" type="GLenum"/> + <param name="dfactor" type="GLenum"/> + </proto> + + <desc name="sfactor"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + <value name="GL_SRC_ALPHA_SATURATE"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> + + <desc name="dfactor"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> +</template> + +<template name="LogicOp"> + <proto> + <return type="void"/> + <param name="opcode" type="GLenum"/> + </proto> + + <desc name="opcode"> + <value name="GL_CLEAR"/> + <value name="GL_SET"/> + <value name="GL_COPY"/> + <value name="GL_COPY_INVERTED"/> + <value name="GL_NOOP"/> + <value name="GL_INVERT"/> + <value name="GL_AND"/> + <value name="GL_NAND"/> + <value name="GL_OR"/> + <value name="GL_NOR"/> + <value name="GL_XOR"/> + <value name="GL_EQUIV"/> + <value name="GL_AND_REVERSE"/> + <value name="GL_AND_INVERTED"/> + <value name="GL_OR_REVERSE"/> + <value name="GL_OR_INVERTED"/> + </desc> +</template> + +<template name="StencilFunc"> + <proto> + <return type="void"/> + <param name="func" type="GLenum"/> + <param name="ref" type="GLint"/> + <param name="mask" type="GLuint"/> + </proto> + + <desc name="func"> + <value name="GL_NEVER"/> + <value name="GL_LESS"/> + <value name="GL_LEQUAL"/> + <value name="GL_GREATER"/> + <value name="GL_GEQUAL"/> + <value name="GL_EQUAL"/> + <value name="GL_NOTEQUAL"/> + <value name="GL_ALWAYS"/> + </desc> +</template> + +<template name="StencilFuncSeparate"> + <proto> + <return type="void"/> + <param name="face" type="GLenum"/> + <param name="func" type="GLenum"/> + <param name="ref" type="GLint"/> + <param name="mask" type="GLuint"/> + </proto> + + <desc name="face"> + <value name="GL_FRONT"/> + <value name="GL_BACK"/> + <value name="GL_FRONT_AND_BACK"/> + </desc> + + <desc name="func"> + <value name="GL_NEVER"/> + <value name="GL_LESS"/> + <value name="GL_LEQUAL"/> + <value name="GL_GREATER"/> + <value name="GL_GEQUAL"/> + <value name="GL_EQUAL"/> + <value name="GL_NOTEQUAL"/> + <value name="GL_ALWAYS"/> + </desc> +</template> + +<template name="StencilOp"> + <proto> + <return type="void"/> + <param name="fail" type="GLenum"/> + <param name="zfail" type="GLenum"/> + <param name="zpass" type="GLenum"/> + </proto> + + <desc name="fail"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP" category="GLES2.0"/> + <value name="GL_DECR_WRAP" category="GLES2.0"/> + <value name="GL_INCR_WRAP_OES" category="OES_stencil_wrap"/> + <value name="GL_DECR_WRAP_OES" category="OES_stencil_wrap"/> + </desc> + + <desc name="zfail"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP" category="GLES2.0"/> + <value name="GL_DECR_WRAP" category="GLES2.0"/> + <value name="GL_INCR_WRAP_OES" category="OES_stencil_wrap"/> + <value name="GL_DECR_WRAP_OES" category="OES_stencil_wrap"/> + </desc> + + <desc name="zpass"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP" category="GLES2.0"/> + <value name="GL_DECR_WRAP" category="GLES2.0"/> + <value name="GL_INCR_WRAP_OES" category="OES_stencil_wrap"/> + <value name="GL_DECR_WRAP_OES" category="OES_stencil_wrap"/> + </desc> +</template> + +<template name="StencilOpSeparate"> + <proto> + <return type="void"/> + <param name="face" type="GLenum"/> + <param name="fail" type="GLenum"/> + <param name="zfail" type="GLenum"/> + <param name="zpass" type="GLenum"/> + </proto> + + <desc name="face"> + <value name="GL_FRONT"/> + <value name="GL_BACK"/> + <value name="GL_FRONT_AND_BACK"/> + </desc> + + <desc name="fail"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP"/> + <value name="GL_DECR_WRAP"/> + </desc> + + <desc name="zfail"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP"/> + <value name="GL_DECR_WRAP"/> + </desc> + + <desc name="zpass"> + <value name="GL_KEEP"/> + <value name="GL_ZERO"/> + <value name="GL_REPLACE"/> + <value name="GL_INCR"/> + <value name="GL_DECR"/> + <value name="GL_INVERT"/> + <value name="GL_INCR_WRAP"/> + <value name="GL_DECR_WRAP"/> + </desc> +</template> + +<template name="DepthFunc"> + <proto> + <return type="void"/> + <param name="func" type="GLenum"/> + </proto> + + <desc name="func"> + <value name="GL_NEVER"/> + <value name="GL_LESS"/> + <value name="GL_EQUAL"/> + <value name="GL_LEQUAL"/> + <value name="GL_GREATER"/> + <value name="GL_NOTEQUAL"/> + <value name="GL_GEQUAL"/> + <value name="GL_ALWAYS"/> + </desc> +</template> + +<template name="PixelStore"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <param name="param" type="GLtype"/> + </proto> + + <desc name="pname"> + <value name="GL_PACK_ALIGNMENT"/> + <value name="GL_UNPACK_ALIGNMENT"/> + </desc> + + <desc name="param" error="GL_INVALID_VALUE"> + <value name="1"/> + <value name="2"/> + <value name="4"/> + <value name="8"/> + </desc> +</template> + +<template name="ReadPixels" direction="get"> + <proto> + <return type="void"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="GLvoid *"/> + </proto> + + <!-- Technically, only two combinations are actually allowed: + GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific + internal preferred combination. I don't know what that is, so I'm + allowing any valid combination for now; the underlying support + should fail when necessary.--> + <desc name="format"> + <value name="GL_ALPHA"/> + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGB"/> + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_5_6_5"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGBA"/> + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4"/> + <value name="GL_UNSIGNED_SHORT_5_5_5_1"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE"/> + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE_ALPHA"/> + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + </desc> + </desc> + + <desc name="format" category="EXT_read_format_bgra"> + <value name="GL_BGRA_EXT"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT"/> + <value name="GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT"/> + </desc> + </desc> +</template> + +<template name="GetClipPlane" direction="get"> + <proto> + <return type="void"/> + <param name="plane" type="GLenum"/> + <vector name="equation" type="GLtype *" size="4"/> + </proto> + + <desc name="plane"> + <range base="GL_CLIP_PLANE" from="0" to="5"/> + </desc> +</template> + +<template name="GetError" direction="get"> + <proto> + <return type="GLenum"/> + </proto> +</template> + +<!-- template for GetFloatv, GetIntegerv, GetBoolean, and GetFixedv --> +<template name="GetState" direction="get"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + <!-- param checking is done in mesa --> +</template> + +<template name="GetLight" direction="get"> + <proto> + <return type="void"/> + <param name="light" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="light"> + <range base="GL_LIGHT" from="0" to="7"/> + </desc> + + <desc name="pname"> + <value name="GL_AMBIENT"/> + <value name="GL_DIFFUSE"/> + <value name="GL_SPECULAR"/> + <value name="GL_POSITION"/> + + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_SPOT_DIRECTION"/> + + <desc name="params" vector_size="3"/> + </desc> + + <desc name="pname"> + <value name="GL_SPOT_EXPONENT"/> + <value name="GL_SPOT_CUTOFF"/> + <value name="GL_CONSTANT_ATTENUATION"/> + <value name="GL_LINEAR_ATTENUATION"/> + <value name="GL_QUADRATIC_ATTENUATION"/> + + <desc name="params" vector_size="1"/> + </desc> +</template> + +<template name="GetMaterial" direction="get"> + <proto> + <return type="void"/> + <param name="face" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="face"> + <value name="GL_FRONT"/> + <value name="GL_BACK"/> + </desc> + + <desc name="pname"> + <value name="GL_SHININESS"/> + <desc name="params" vector_size="1"/> + </desc> + + <desc name="pname"> + <value name="GL_AMBIENT"/> + <value name="GL_DIFFUSE"/> + <value name="GL_AMBIENT_AND_DIFFUSE"/> + <value name="GL_SPECULAR"/> + <value name="GL_EMISSION"/> + + <desc name="params" vector_size="4"/> + </desc> +</template> + +<template name="GetString" direction="get"> + <proto> + <return type="const GLubyte *"/> + <param name="name" type="GLenum"/> + </proto> + + <desc name="name"> + <value name="GL_VENDOR"/> + <value name="GL_RENDERER"/> + <value name="GL_VERSION"/> + <value name="GL_EXTENSIONS"/> + <value name="GL_SHADING_LANGUAGE_VERSION" category="GLES2.0"/> + </desc> +</template> + +<template name="GetTexEnv" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="target" category="OES_point_sprite"> + <value name="GL_POINT_SPRITE_OES"/> + <desc name="pname"> + <value name="GL_COORD_REPLACE_OES"/> + </desc> + </desc> + + <desc name="pname" category="OES_point_sprite"> + <value name="GL_COORD_REPLACE_OES"/> + <desc name="params" vector_size="1" convert="false"/> + </desc> + + <desc name="target" category="EXT_texture_lod_bias"> + <value name="GL_TEXTURE_FILTER_CONTROL_EXT"/> + + <desc name="pname"> + <value name="GL_TEXTURE_LOD_BIAS_EXT"/> + </desc> + </desc> + + <desc name="pname" category="EXT_texture_lod_bias"> + <value name="GL_TEXTURE_LOD_BIAS_EXT"/> + <desc name="params" vector_size="1"/> + </desc> + + <desc name="target"> + <value name="GL_TEXTURE_ENV"/> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_COLOR"/> + <value name="GL_RGB_SCALE"/> + <value name="GL_ALPHA_SCALE"/> + <value name="GL_TEXTURE_ENV_MODE"/> + <value name="GL_COMBINE_RGB"/> + <value name="GL_COMBINE_ALPHA"/> + <value name="GL_SRC0_RGB"/> + <value name="GL_SRC1_RGB"/> + <value name="GL_SRC2_RGB"/> + <value name="GL_SRC0_ALPHA"/> + <value name="GL_SRC1_ALPHA"/> + <value name="GL_SRC2_ALPHA"/> + <value name="GL_OPERAND0_RGB"/> + <value name="GL_OPERAND1_RGB"/> + <value name="GL_OPERAND2_RGB"/> + <value name="GL_OPERAND0_ALPHA"/> + <value name="GL_OPERAND1_ALPHA"/> + <value name="GL_OPERAND2_ALPHA"/> + </desc> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_COLOR"/> + <desc name="params" vector_size="4"/> + </desc> + + <desc name="pname"> + <value name="GL_RGB_SCALE"/> + <value name="GL_ALPHA_SCALE"/> + + <desc name="params" vector_size="1"/> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_ENV_MODE"/> + <value name="GL_COMBINE_RGB"/> + <value name="GL_COMBINE_ALPHA"/> + <value name="GL_SRC0_RGB"/> + <value name="GL_SRC1_RGB"/> + <value name="GL_SRC2_RGB"/> + <value name="GL_SRC0_ALPHA"/> + <value name="GL_SRC1_ALPHA"/> + <value name="GL_SRC2_ALPHA"/> + <value name="GL_OPERAND0_RGB"/> + <value name="GL_OPERAND1_RGB"/> + <value name="GL_OPERAND2_RGB"/> + <value name="GL_OPERAND0_ALPHA"/> + <value name="GL_OPERAND1_ALPHA"/> + <value name="GL_OPERAND2_ALPHA"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> +</template> + +<template name="GetTexGen" direction="get"> + <proto> + <return type="void"/> + <param name="coord" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="coord"> + <value name="GL_TEXTURE_GEN_STR_OES"/> + </desc> + <desc name="pname"> + <value name="GL_TEXTURE_GEN_MODE_OES"/> + <desc name="params" vector_size="1" convert="false"/> + </desc> +</template> + +<template name="GetTexParameter" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_3D_OES" category="OES_texture_3D"/> + </desc> + + <desc name="pname"> + <value name="GL_TEXTURE_WRAP_S"/> + <value name="GL_TEXTURE_WRAP_T"/> + <value name="GL_TEXTURE_WRAP_R_OES" category="OES_texture_3D"/> + <value name="GL_TEXTURE_MIN_FILTER"/> + <value name="GL_TEXTURE_MAG_FILTER"/> + <value name="GL_GENERATE_MIPMAP" category="GLES1.1"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> + + <desc name="pname" category="OES_draw_texture"> + <value name="GL_TEXTURE_CROP_RECT_OES"/> + <desc name="params" vector_size="4"/> + </desc> +</template> + +<template name="IsEnabled" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="cap" type="GLenum"/> + </proto> + + <desc name="cap" category="GLES1.1"> + <value name="GL_NORMALIZE"/> + <value name="GL_RESCALE_NORMAL"/> + + <range base="GL_CLIP_PLANE" from="0" to="5"/> + + <value name="GL_FOG"/> + <value name="GL_LIGHTING"/> + <value name="GL_COLOR_MATERIAL"/> + + <range base="GL_LIGHT" from="0" to="7"/> + + <value name="GL_POINT_SMOOTH"/> + <value name="GL_LINE_SMOOTH"/> + <value name="GL_CULL_FACE"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_MULTISAMPLE"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_ALPHA_TO_ONE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_TEXTURE_2D"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_ALPHA_TEST"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_BLEND"/> + <value name="GL_DITHER"/> + <value name="GL_COLOR_LOGIC_OP"/> + + <value name="GL_POINT_SPRITE_OES" category="OES_point_sprite"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_GEN_STR_OES" category="OES_texture_cube_map"/> + + <value name="GL_VERTEX_ARRAY"/> + <value name="GL_NORMAL_ARRAY"/> + <value name="GL_COLOR_ARRAY"/> + <value name="GL_TEXTURE_COORD_ARRAY"/> + <value name="GL_MATRIX_INDEX_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_WEIGHT_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_POINT_SIZE_ARRAY_OES" category="OES_point_size_array"/> + </desc> + + <desc name="cap" category="GLES2.0"> + <value name="GL_CULL_FACE"/> + <value name="GL_SCISSOR_TEST"/> + <value name="GL_POLYGON_OFFSET_FILL"/> + <value name="GL_SAMPLE_ALPHA_TO_COVERAGE"/> + <value name="GL_SAMPLE_COVERAGE"/> + <value name="GL_STENCIL_TEST"/> + <value name="GL_DEPTH_TEST"/> + <value name="GL_DITHER"/> + <value name="GL_BLEND"/> + </desc> +</template> + +<template name="DepthRange"> + <proto> + <return type="void"/> + <param name="zNear" type="GLtype"/> + <param name="zFar" type="GLtype"/> + </proto> +</template> + +<template name="Frustum"> + <proto> + <return type="void"/> + <param name="left" type="GLtype"/> + <param name="right" type="GLtype"/> + <param name="bottom" type="GLtype"/> + <param name="top" type="GLtype"/> + <param name="zNear" type="GLtype"/> + <param name="zFar" type="GLtype"/> + </proto> +</template> + +<template name="LoadIdentity"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="LoadMatrix"> + <proto> + <return type="void"/> + <vector name="m" type="const GLtype *" size="16"/> + </proto> +</template> + +<template name="MatrixMode"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="mode"> + <value name="GL_MODELVIEW"/> + <value name="GL_PROJECTION"/> + <value name="GL_TEXTURE"/> + <value name="GL_MATRIX_PALETTE_OES" category="OES_matrix_palette"/> + </desc> +</template> + +<template name="MultMatrix"> + <proto> + <return type="void"/> + <vector name="m" type="const GLtype *" size="16"/> + </proto> +</template> + +<template name="Ortho"> + <proto> + <return type="void"/> + <param name="left" type="GLtype"/> + <param name="right" type="GLtype"/> + <param name="bottom" type="GLtype"/> + <param name="top" type="GLtype"/> + <param name="zNear" type="GLtype"/> + <param name="zFar" type="GLtype"/> + </proto> +</template> + +<template name="PopMatrix"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="PushMatrix"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="Rotate"> + <proto> + <return type="void"/> + <param name="angle" type="GLtype"/> + <param name="x" type="GLtype"/> + <param name="y" type="GLtype"/> + <param name="z" type="GLtype"/> + </proto> +</template> + +<template name="Scale"> + <proto> + <return type="void"/> + <param name="x" type="GLtype"/> + <param name="y" type="GLtype"/> + <param name="z" type="GLtype"/> + </proto> +</template> + +<template name="Translate"> + <proto> + <return type="void"/> + <param name="x" type="GLtype"/> + <param name="y" type="GLtype"/> + <param name="z" type="GLtype"/> + </proto> +</template> + +<template name="Viewport"> + <proto> + <return type="void"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </proto> +</template> + +<template name="ColorPointer"> + <proto> + <return type="void"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="size" error="GL_INVALID_VALUE"> + <value name="4"/> + </desc> + + <desc name="type"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + <value name="GL_HALF_FLOAT_OES" category="OES_vertex_half_float"/> + </desc> +</template> + +<template name="DisableClientState"> + <proto> + <return type="void"/> + <param name="array" type="GLenum"/> + </proto> + + <desc name="array"> + <value name="GL_VERTEX_ARRAY"/> + <value name="GL_NORMAL_ARRAY"/> + <value name="GL_COLOR_ARRAY"/> + <value name="GL_TEXTURE_COORD_ARRAY"/> + <value name="GL_MATRIX_INDEX_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_WEIGHT_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_POINT_SIZE_ARRAY_OES" category="OES_point_size_array"/> + </desc> +</template> + +<template name="DrawArrays"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint"/> + <param name="count" type="GLsizei"/> + </proto> + + <desc name="mode"> + <value name="GL_POINTS"/> + <value name="GL_LINES"/> + <value name="GL_LINE_LOOP"/> + <value name="GL_LINE_STRIP"/> + <value name="GL_TRIANGLES"/> + <value name="GL_TRIANGLE_STRIP"/> + <value name="GL_TRIANGLE_FAN"/> + </desc> +</template> + +<template name="DrawElements"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + <param name="count" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid *"/> + </proto> + + <desc name="mode"> + <value name="GL_POINTS"/> + <value name="GL_LINES"/> + <value name="GL_LINE_LOOP"/> + <value name="GL_LINE_STRIP"/> + <value name="GL_TRIANGLES"/> + <value name="GL_TRIANGLE_STRIP"/> + <value name="GL_TRIANGLE_FAN"/> + </desc> + + <desc name="type"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT"/> + <!-- GL_UNSIGNED_INT is not defined in GLES1.1 headers --> + <value name="(0x1405 /* GL_UNSIGNED_INT */)" category="OES_element_index_uint"/> + </desc> +</template> + +<template name="EnableClientState"> + <proto> + <return type="void"/> + <param name="array" type="GLenum"/> + </proto> + + <desc name="array"> + <value name="GL_VERTEX_ARRAY"/> + <value name="GL_NORMAL_ARRAY"/> + <value name="GL_COLOR_ARRAY"/> + <value name="GL_TEXTURE_COORD_ARRAY"/> + <value name="GL_MATRIX_INDEX_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_WEIGHT_ARRAY_OES" category="OES_matrix_palette"/> + <value name="GL_POINT_SIZE_ARRAY_OES" category="OES_point_size_array"/> + </desc> +</template> + +<template name="GetPointer" direction="get"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLvoid **" size="dynamic"/> + </proto> + + <desc name="pname"> + <value name="GL_VERTEX_ARRAY_POINTER"/> + <value name="GL_NORMAL_ARRAY_POINTER"/> + <value name="GL_COLOR_ARRAY_POINTER"/> + <value name="GL_TEXTURE_COORD_ARRAY_POINTER"/> + <value name="GL_MATRIX_INDEX_ARRAY_POINTER_OES" category="OES_matrix_palette"/> + <value name="GL_WEIGHT_ARRAY_POINTER_OES" category="OES_matrix_palette"/> + <value name="GL_POINT_SIZE_ARRAY_POINTER_OES" category="OES_point_size_array"/> + </desc> +</template> + +<template name="Normal"> + <proto> + <return type="void"/> + <vector name="v" type="const GLtype *" size="3"> + <param name="nx" type="GLtype"/> + <param name="ny" type="GLtype"/> + <param name="nz" type="GLtype"/> + </vector> + </proto> +</template> + +<template name="NormalPointer"> + <proto> + <return type="void"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="type"> + <value name="GL_BYTE"/> + <value name="GL_SHORT"/> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + <value name="GL_HALF_FLOAT_OES" category="OES_vertex_half_float"/> + </desc> +</template> + +<template name="TexCoordPointer"> + <proto> + <return type="void"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="size" error="GL_INVALID_VALUE"> + <value name="2"/> + <value name="3"/> + <value name="4"/> + </desc> + + <desc name="type"> + <value name="GL_BYTE"/> + <value name="GL_SHORT"/> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + <value name="GL_HALF_FLOAT_OES" category="OES_vertex_half_float"/> + </desc> +</template> + +<template name="VertexPointer"> + <proto> + <return type="void"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="size" error="GL_INVALID_VALUE"> + <value name="2"/> + <value name="3"/> + <value name="4"/> + </desc> + + <desc name="type"> + <value name="GL_BYTE"/> + <value name="GL_SHORT"/> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + <value name="GL_HALF_FLOAT_OES" category="OES_vertex_half_float"/> + </desc> +</template> + +<template name="PolygonOffset"> + <proto> + <return type="void"/> + <param name="factor" type="GLtype"/> + <param name="units" type="GLtype"/> + </proto> +</template> + +<template name="CopyTexImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalFormat" type="GLenum"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="internalFormat" error="GL_INVALID_VALUE"> + <value name="GL_ALPHA"/> + <value name="GL_RGB"/> + <value name="GL_RGBA"/> + <value name="GL_LUMINANCE"/> + <value name="GL_LUMINANCE_ALPHA"/> + </desc> + + <desc name="border" error="GL_INVALID_VALUE"> + <value name="0"/> + </desc> +</template> + +<template name="CopyTexSubImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> +</template> + +<template name="TexSubImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="format"> + <value name="GL_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGB"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_5_6_5"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGBA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4"/> + <value name="GL_UNSIGNED_SHORT_5_5_5_1"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format" category="OES_depth_texture"> + <value name="GL_DEPTH_COMPONENT"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_SHORT"/> + <value name="GL_UNSIGNED_INT"/> + </desc> + </desc> + + <desc name="format" category="OES_packed_depth_stencil"> + <value name="GL_DEPTH_STENCIL_OES"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_INT_24_8_OES"/> + </desc> + </desc> +</template> + +<template name="BindTexture"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="texture" type="GLuint"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_3D_OES" category="OES_texture_3D"/> + </desc> +</template> + +<template name="DeleteTextures"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="textures" type="const GLuint *"/> + </proto> +</template> + +<template name="GenTextures" direction="get"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="textures" type="GLuint *"/> + </proto> +</template> + +<template name="IsTexture" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="texture" type="GLuint"/> + </proto> +</template> + +<template name="BlendColor"> + <proto> + <return type="void"/> + <param name="red" type="GLtype"/> + <param name="green" type="GLtype"/> + <param name="blue" type="GLtype"/> + <param name="alpha" type="GLtype"/> + </proto> +</template> + +<template name="BlendEquation"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + </proto> + + <desc name="mode"> + <value name="GL_FUNC_ADD" category="GLES2.0"/> + <value name="GL_FUNC_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_REVERSE_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_ADD_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_SUBTRACT_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_REVERSE_SUBTRACT_OES" category="OES_blend_subtract"/> + + <value name="GL_MIN_EXT" category="EXT_blend_minmax"/> + <value name="GL_MAX_EXT" category="EXT_blend_minmax"/> + </desc> +</template> + +<template name="BlendEquationSeparate"> + <proto> + <return type="void"/> + <param name="modeRGB" type="GLenum"/> + <param name="modeAlpha" type="GLenum"/> + </proto> + + <desc name="modeRGB"> + <value name="GL_FUNC_ADD" category="GLES2.0"/> + <value name="GL_FUNC_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_REVERSE_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_ADD_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_SUBTRACT_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_REVERSE_SUBTRACT_OES" category="OES_blend_subtract"/> + + <value name="GL_MIN_EXT" category="EXT_blend_minmax"/> + <value name="GL_MAX_EXT" category="EXT_blend_minmax"/> + </desc> + + <desc name="modeAlpha"> + <value name="GL_FUNC_ADD" category="GLES2.0"/> + <value name="GL_FUNC_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_REVERSE_SUBTRACT" category="GLES2.0"/> + <value name="GL_FUNC_ADD_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_SUBTRACT_OES" category="OES_blend_subtract"/> + <value name="GL_FUNC_REVERSE_SUBTRACT_OES" category="OES_blend_subtract"/> + + <value name="GL_MIN_EXT" category="EXT_blend_minmax"/> + <value name="GL_MAX_EXT" category="EXT_blend_minmax"/> + </desc> +</template> + +<template name="TexImage3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalFormat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_3D_OES"/> + </desc> + + <desc name="internalFormat"> + <value name="GL_ALPHA"/> + <value name="GL_RGB"/> + <value name="GL_RGBA"/> + <value name="GL_LUMINANCE"/> + <value name="GL_LUMINANCE_ALPHA"/> + </desc> + + <desc name="format"> + <value name="GL_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGB"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_5_6_5"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGBA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4"/> + <value name="GL_UNSIGNED_SHORT_5_5_5_1"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> +</template> + +<template name="TexSubImage3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="type" type="GLenum"/> + <param name="pixels" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_3D_OES"/> + </desc> + + <desc name="format"> + <value name="GL_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGB"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_5_6_5"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_RGBA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT_4_4_4_4"/> + <value name="GL_UNSIGNED_SHORT_5_5_5_1"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + <value name="GL_UNSIGNED_INT_2_10_10_10_REV_EXT" category="EXT_texture_type_2_10_10_10_REV"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> + + <desc name="format"> + <value name="GL_LUMINANCE_ALPHA"/> + + <desc name="type" error="GL_INVALID_OPERATION"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_FLOAT" category="OES_texture_float"/> + <value name="GL_HALF_FLOAT_OES" category="OES_texture_half_float"/> + </desc> + </desc> +</template> + +<template name="CopyTexSubImage3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_3D_OES"/> + </desc> +</template> + +<template name="MultiTexCoord"> + <proto> + <return type="void"/> + <param name="texture" type="GLenum"/> + <vector name="v" type="const GLtype *" size="dynamic"> + <param name="s" type="GLtype"/> + <param name="t" type="GLtype"/> + <param name="r" type="GLtype"/> + <param name="q" type="GLtype"/> + </vector> + </proto> + + <desc name="texture"> + <range base="GL_TEXTURE" from="0" to="31"/> + </desc> +</template> + +<template name="CompressedTexImage3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalFormat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="imagesize" type="GLsizei"/> + <param name="data" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_3D_OES"/> + </desc> + + <desc name="internalFormat"> + <value name="GL_3DC_X_AMD" category="AMD_compressed_3DC_texture"/> + <value name="GL_3DC_XY_AMD" category="AMD_compressed_3DC_texture"/> + <value name="GL_ATC_RGB_AMD" category="AMD_compressed_ATC_texture"/> + <value name="GL_ATC_RGBA_EXPLICIT_ALPHA_AMD" category="AMD_compressed_ATC_texture"/> + <value name="GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD" category="AMD_compressed_ATC_texture"/> + </desc> +</template> + +<template name="CompressedTexSubImage3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="zoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="depth" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="imagesize" type="GLsizei"/> + <param name="data" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_3D_OES"/> + </desc> +</template> + +<template name="ActiveTexture"> + <proto> + <return type="void"/> + <param name="texture" type="GLenum"/> + </proto> + + <desc name="texture"> + <range base="GL_TEXTURE" from="0" to="31"/> + </desc> +</template> + +<template name="ClientActiveTexture"> + <proto> + <return type="void"/> + <param name="texture" type="GLenum"/> + </proto> + + <desc name="texture"> + <range base="GL_TEXTURE" from="0" to="31"/> + </desc> +</template> + +<template name="SampleCoverage"> + <proto> + <return type="void"/> + <param name="value" type="GLtype"/> + <param name="invert" type="GLboolean"/> + </proto> +</template> + +<template name="CompressedTexImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="internalFormat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="border" type="GLint"/> + <param name="imageSize" type="GLsizei"/> + <param name="data" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="internalFormat"> + <value name="GL_ETC1_RGB8_OES" category="OES_compressed_ETC1_RGB8_texture"/> + + <value name="GL_PALETTE4_RGB8_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE4_RGBA8_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE4_R5_G6_B5_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE4_RGBA4_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE4_RGB5_A1_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE8_RGB8_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE8_RGBA8_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE8_R5_G6_B5_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE8_RGBA4_OES" category="OES_compressed_paletted_texture"/> + <value name="GL_PALETTE8_RGB5_A1_OES" category="OES_compressed_paletted_texture"/> + + <value name="GL_3DC_X_AMD" category="AMD_compressed_3DC_texture"/> + <value name="GL_3DC_XY_AMD" category="AMD_compressed_3DC_texture"/> + + <value name="GL_ATC_RGB_AMD" category="AMD_compressed_ATC_texture"/> + <value name="GL_ATC_RGBA_EXPLICIT_ALPHA_AMD" category="AMD_compressed_ATC_texture"/> + <value name="GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD" category="AMD_compressed_ATC_texture"/> + + <value name="GL_COMPRESSED_RGB_S3TC_DXT1_EXT" category="EXT_texture_compression_dxt1"/> + <value name="GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" category="EXT_texture_compression_dxt1"/> + </desc> + + <desc name="border" error="GL_INVALID_VALUE"> + <value name="0"/> + </desc> +</template> + +<template name="CompressedTexSubImage2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="level" type="GLint"/> + <param name="xoffset" type="GLint"/> + <param name="yoffset" type="GLint"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + <param name="format" type="GLenum"/> + <param name="imageSize" type="GLsizei"/> + <param name="data" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + + <desc name="format"> + <value name="GL_COMPRESSED_RGB_S3TC_DXT1_EXT" category="EXT_texture_compression_dxt1"/> + <value name="GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" category="EXT_texture_compression_dxt1"/> + </desc> +</template> + +<template name="BlendFuncSeparate"> + <proto> + <return type="void"/> + <param name="srcRGB" type="GLenum"/> + <param name="dstRGB" type="GLenum"/> + <param name="srcAlpha" type="GLenum"/> + <param name="dstAlpha" type="GLenum"/> + </proto> + + <desc name="srcRGB"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + <value name="GL_SRC_ALPHA_SATURATE"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> + + <desc name="dstRGB"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> + + <desc name="srcAlpha"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + <value name="GL_SRC_ALPHA_SATURATE"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> + + <desc name="dstAlpha"> + <value name="GL_ZERO"/> + <value name="GL_ONE"/> + <value name="GL_SRC_COLOR"/> + <value name="GL_ONE_MINUS_SRC_COLOR"/> + <value name="GL_SRC_ALPHA"/> + <value name="GL_ONE_MINUS_SRC_ALPHA"/> + <value name="GL_DST_ALPHA"/> + <value name="GL_ONE_MINUS_DST_ALPHA"/> + <value name="GL_DST_COLOR"/> + <value name="GL_ONE_MINUS_DST_COLOR"/> + + <value name="GL_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_COLOR" category="GLES2.0"/> + <value name="GL_CONSTANT_ALPHA" category="GLES2.0"/> + <value name="GL_ONE_MINUS_CONSTANT_ALPHA" category="GLES2.0"/> + </desc> +</template> + +<template name="PointParameter"> + <proto> + <return type="void"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="const GLtype *" size="dynamic"> + <param name="param" type="GLtype"/> + </vector> + </proto> + + <desc name="pname"> + <value name="GL_POINT_SIZE_MIN"/> + <value name="GL_POINT_SIZE_MAX"/> + <value name="GL_POINT_FADE_THRESHOLD_SIZE"/> + + <desc name="params" vector_size="1"/> + </desc> + + <desc name="pname"> + <value name="GL_POINT_DISTANCE_ATTENUATION"/> + <desc name="params" vector_size="3"/> + </desc> +</template> + +<template name="VertexAttrib"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + <vector name="v" type="const GLtype *" size="dynamic"> + <param name="x" type="GLtype"/> + <param name="y" type="GLtype"/> + <param name="z" type="GLtype"/> + <param name="w" type="GLtype"/> + </vector> + </proto> +</template> + +<template name="VertexAttribPointer"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="normalized" type="GLboolean"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </proto> + + <desc name="size" error="GL_INVALID_VALUE"> + <value name="1"/> + <value name="2"/> + <value name="3"/> + <value name="4"/> + </desc> + + <desc name="type" error="GL_INVALID_VALUE"> + <value name="GL_BYTE"/> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_SHORT"/> + <value name="GL_UNSIGNED_SHORT"/> + <value name="GL_FLOAT"/> + <value name="GL_FIXED"/> + <value name="GL_HALF_FLOAT_OES" category="OES_vertex_half_float"/> + <value name="GL_UNSIGNED_INT_10_10_10_2_OES" category="OES_vertex_type_10_10_10_2"/> + <value name="GL_INT_10_10_10_2_OES" category="OES_vertex_type_10_10_10_2"/> + </desc> + + <desc name="type" category="OES_vertex_type_10_10_10_2"> + <value name="GL_UNSIGNED_INT_10_10_10_2_OES"/> + <value name="GL_INT_10_10_10_2_OES"/> + + <desc name="size"> + <value name="3"/> + <value name="4"/> + </desc> + </desc> +</template> + +<template name="EnableVertexAttribArray"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + </proto> +</template> + +<template name="DisableVertexAttribArray"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + </proto> +</template> + +<template name="IsProgram" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="program" type="GLuint"/> + </proto> +</template> + +<template name="GetProgram" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="pname"> + <value name="GL_DELETE_STATUS"/> + <value name="GL_LINK_STATUS"/> + <value name="GL_VALIDATE_STATUS"/> + <value name="GL_INFO_LOG_LENGTH"/> + <value name="GL_ATTACHED_SHADERS"/> + <value name="GL_ACTIVE_ATTRIBUTES"/> + <value name="GL_ACTIVE_ATTRIBUTE_MAX_LENGTH"/> + <value name="GL_ACTIVE_UNIFORMS"/> + <value name="GL_ACTIVE_UNIFORM_MAX_LENGTH"/> + <value name="GL_PROGRAM_BINARY_LENGTH_OES" category="OES_get_program_binary"/> + + <desc name="params" convert="false"/> + </desc> +</template> + +<template name="GetVertexAttrib" direction="get"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="pname"> + <value name="GL_VERTEX_ATTRIB_ARRAY_ENABLED"/> + <value name="GL_VERTEX_ATTRIB_ARRAY_SIZE"/> + <value name="GL_VERTEX_ATTRIB_ARRAY_STRIDE"/> + <value name="GL_VERTEX_ATTRIB_ARRAY_TYPE"/> + <value name="GL_VERTEX_ATTRIB_ARRAY_NORMALIZED"/> + <value name="GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> + + <desc name="pname"> + <value name="GL_CURRENT_VERTEX_ATTRIB"/> + <desc name="params" vector_size="16?" convert="false"/> + </desc> +</template> + +<template name="GetVertexAttribPointer" direction="get"> + <proto> + <return type="void"/> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <vector name="pointer" type="GLvoid **" size="dynamic"/> + </proto> + + <desc name="pname"> + <value name="GL_VERTEX_ATTRIB_ARRAY_POINTER"/> + </desc> +</template> + +<template name="GetBufferPointer" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLvoid **" size="dynamic"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> + + <desc name="pname"> + <value name="GL_BUFFER_MAP_POINTER_OES"/> + </desc> +</template> + +<template name="MapBuffer" direction="get"> + <proto> + <return type="void *"/> + <param name="target" type="GLenum"/> + <param name="access" type="GLenum"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> + + <desc name="access"> + <value name="GL_WRITE_ONLY_OES"/> + </desc> +</template> + +<template name="UnmapBuffer" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="target" type="GLenum"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> +</template> + +<template name="BindBuffer"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="buffer" type="GLuint"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> +</template> + +<template name="BufferData"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="size" type="GLsizeiptr"/> + <param name="data" type="const GLvoid *"/> + <param name="usage" type="GLenum"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> + + <desc name="usage"> + <value name="GL_STATIC_DRAW"/> + <value name="GL_DYNAMIC_DRAW"/> + <value name="GL_STREAM_DRAW" category="GLES2.0"/> + </desc> +</template> + +<template name="BufferSubData"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="offset" type="GLintptr"/> + <param name="size" type="GLsizeiptr"/> + <param name="data" type="const GLvoid *"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> +</template> + +<template name="DeleteBuffers"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="buffer" type="const GLuint *"/> + </proto> +</template> + +<template name="GenBuffers" direction="get"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="buffer" type="GLuint *"/> + </proto> +</template> + +<template name="GetBufferParameter" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="target"> + <value name="GL_ARRAY_BUFFER"/> + <value name="GL_ELEMENT_ARRAY_BUFFER"/> + </desc> + + <desc name="pname"> + <value name="GL_BUFFER_SIZE"/> + <value name="GL_BUFFER_USAGE"/> + <value name="GL_BUFFER_ACCESS_OES" category="OES_mapbuffer"/> + <value name="GL_BUFFER_MAPPED_OES" category="OES_mapbuffer"/> + </desc> +</template> + +<template name="IsBuffer" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="buffer" type="GLuint"/> + </proto> +</template> + +<template name="CreateShader"> + <proto> + <return type="GLuint"/> + <param name="type" type="GLenum"/> + </proto> + + <desc name="type"> + <value name="GL_VERTEX_SHADER"/> + <value name="GL_FRAGMENT_SHADER"/> + </desc> +</template> + +<template name="ShaderSource"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + <param name="count" type="GLsizei"/> + <param name="string" type="const GLchar **"/> + <param name="length" type="const int *"/> + </proto> +</template> + +<template name="CompileShader"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + </proto> +</template> + +<template name="ReleaseShaderCompiler"> + <proto> + <return type="void"/> + </proto> +</template> + +<template name="DeleteShader"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + </proto> +</template> + +<template name="ShaderBinary"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="shaders" type="const GLuint *"/> + <param name="binaryformat" type="GLenum"/> + <param name="binary" type="const GLvoid *"/> + <param name="length" type="GLsizei"/> + </proto> +</template> + +<template name="CreateProgram"> + <proto> + <return type="GLuint"/> + </proto> +</template> + +<template name="AttachShader"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="shader" type="GLuint"/> + </proto> +</template> + +<template name="DetachShader"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="shader" type="GLuint"/> + </proto> +</template> + +<template name="LinkProgram"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + </proto> +</template> + +<template name="UseProgram"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + </proto> +</template> + +<template name="DeleteProgram"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + </proto> +</template> + +<template name="GetActiveAttrib" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="size" type="GLint *"/> + <param name="type" type="GLenum *"/> + <param name="name" type="GLchar *"/> + </proto> +</template> + +<template name="GetAttribLocation" direction="get"> + <proto> + <return type="GLint"/> + <param name="program" type="GLuint"/> + <param name="name" type="const char *"/> + </proto> +</template> + +<template name="BindAttribLocation"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="name" type="const char *"/> + </proto> +</template> + +<template name="GetUniformLocation" direction="get"> + <proto> + <return type="GLint"/> + <param name="program" type="GLuint"/> + <param name="name" type="const char *"/> + </proto> +</template> + +<template name="GetActiveUniform" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="size" type="GLint *"/> + <param name="type" type="GLenum *"/> + <param name="name" type="GLchar *"/> + </proto> +</template> + +<template name="Uniform"> + <proto> + <return type="void"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei" hide_if_expanded="true"/> + <vector name="values" type="const GLtype *" size="dynamic"> + <param name="v0" type="GLtype"/> + <param name="v1" type="GLtype"/> + <param name="v2" type="GLtype"/> + <param name="v3" type="GLtype"/> + </vector> + </proto> +</template> + +<template name="UniformMatrix"> + <proto> + <return type="void"/> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="transpose" type="GLboolean"/> + <vector name="value" type="const GLtype *" size="dynamic"/> + </proto> +</template> + +<template name="ValidateProgram"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + </proto> +</template> + +<template name="GenerateMipmap"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + </proto> + + <desc name="target"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_3D_OES" category="OES_texture_3D"/> + </desc> +</template> + +<template name="BindFramebuffer"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="framebuffer" type="GLuint"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> +</template> + +<template name="DeleteFramebuffers"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="framebuffers" type="const GLuint *"/> + </proto> +</template> + +<template name="GenFramebuffers"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="ids" type="GLuint *"/> + </proto> +</template> + +<template name="BindRenderbuffer"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </proto> + + <desc name="target"> + <value name="GL_RENDERBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_RENDERBUFFER" category="GLES2.0"/> + </desc> +</template> + +<template name="DeleteRenderbuffers"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="renderbuffers" type="const GLuint *"/> + </proto> +</template> + +<template name="GenRenderbuffers"> + <proto> + <return type="void"/> + <param name="n" type="GLsizei"/> + <param name="renderbuffers" type="GLuint *"/> + </proto> +</template> + +<template name="RenderbufferStorage"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="internalFormat" type="GLenum"/> + <param name="width" type="GLsizei"/> + <param name="height" type="GLsizei"/> + </proto> + + <desc name="target"> + <value name="GL_RENDERBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_RENDERBUFFER" category="GLES2.0"/> + </desc> + + <desc name="internalFormat"> + <value name="GL_DEPTH_COMPONENT16_OES" category="OES_framebuffer_object"/> + <value name="GL_RGBA4_OES" category="OES_framebuffer_object"/> + <value name="GL_RGB5_A1_OES" category="OES_framebuffer_object"/> + <value name="GL_RGB565_OES" category="OES_framebuffer_object"/> + <value name="GL_STENCIL_INDEX8_OES" category="OES_stencil8"/> + + <value name="GL_DEPTH_COMPONENT16" category="GLES2.0"/> + <value name="GL_RGBA4" category="GLES2.0"/> + <value name="GL_RGB5_A1" category="GLES2.0"/> + <value name="GL_RGB565" category="GLES2.0"/> + <value name="GL_STENCIL_INDEX8" category="GLES2.0"/> + + <value name="GL_DEPTH_COMPONENT24_OES" category="OES_depth24"/> + <value name="GL_DEPTH_COMPONENT32_OES" category="OES_depth32"/> + <value name="GL_RGB8_OES" category="OES_rgb8_rgba8"/> + <value name="GL_RGBA8_OES" category="OES_rgb8_rgba8"/> + <value name="GL_STENCIL_INDEX1_OES" category="OES_stencil1"/> + <value name="GL_STENCIL_INDEX4_OES" category="OES_stencil4"/> + <value name="GL_DEPTH24_STENCIL8_OES" category="OES_packed_depth_stencil"/> + </desc> +</template> + +<template name="FramebufferRenderbuffer"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="renderbuffertarget" type="GLenum"/> + <param name="renderbuffer" type="GLuint"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> + + <desc name="attachment"> + <value name="GL_COLOR_ATTACHMENT0_OES" category="OES_framebuffer_object"/> + <value name="GL_DEPTH_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_STENCIL_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_COLOR_ATTACHMENT0" category="GLES2.0"/> + <value name="GL_DEPTH_ATTACHMENT" category="GLES2.0"/> + <value name="GL_STENCIL_ATTACHMENT" category="GLES2.0"/> + </desc> + + <desc name="renderbuffertarget"> + <value name="GL_RENDERBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_RENDERBUFFER" category="GLES2.0"/> + </desc> +</template> + +<template name="FramebufferTexture2D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="textarget" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> + + <desc name="attachment"> + <value name="GL_COLOR_ATTACHMENT0_OES" category="OES_framebuffer_object"/> + <value name="GL_DEPTH_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_STENCIL_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_COLOR_ATTACHMENT0" category="GLES2.0"/> + <value name="GL_DEPTH_ATTACHMENT" category="GLES2.0"/> + <value name="GL_STENCIL_ATTACHMENT" category="GLES2.0"/> + </desc> + + <desc name="textarget" error="GL_INVALID_OPERATION"> + <value name="GL_TEXTURE_2D"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" category="GLES2.0"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES" category="OES_texture_cube_map"/> + <value name="GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES" category="OES_texture_cube_map"/> + </desc> + <!-- According to the base specification, "level" must be 0. But + extension GL_OES_fbo_render_mipmap lifts that restriction, + so no restriction is placed here. --> +</template> + +<template name="FramebufferTexture3D"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="textarget" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + <param name="zoffset" type="GLint"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> + + <desc name="attachment"> + <value name="GL_COLOR_ATTACHMENT0_OES" category="OES_framebuffer_object"/> + <value name="GL_DEPTH_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_STENCIL_ATTACHMENT_OES" category="OES_framebuffer_object"/> + <value name="GL_COLOR_ATTACHMENT0" category="GLES2.0"/> + <value name="GL_DEPTH_ATTACHMENT" category="GLES2.0"/> + <value name="GL_STENCIL_ATTACHMENT" category="GLES2.0"/> + </desc> + + <desc name="textarget" error="GL_INVALID_OPERATION"> + <value name="GL_TEXTURE_3D_OES" category="OES_texture_3D"/> + </desc> +</template> + +<template name="CheckFramebufferStatus" direction="get"> + <proto> + <return type="GLenum"/> + <param name="target" type="GLenum"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> +</template> + +<template name="GetFramebufferAttachmentParameter" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="target"> + <value name="GL_FRAMEBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER" category="GLES2.0"/> + </desc> + + <desc name="pname"> + <value name="GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES" category="OES_framebuffer_object"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES" category="OES_framebuffer_object"/> + + <value name="GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE" category="GLES2.0"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME" category="GLES2.0"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL" category="GLES2.0"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE" category="GLES2.0"/> + <value name="GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES" category="OES_texture_3D"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> +</template> + +<template name="GetRenderbufferParameter" direction="get"> + <proto> + <return type="void"/> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="target"> + <value name="GL_RENDERBUFFER_OES" category="OES_framebuffer_object"/> + <value name="GL_RENDERBUFFER" category="GLES2.0"/> + </desc> + + <desc name="pname" category="OES_framebuffer_object"> + <value name="GL_RENDERBUFFER_WIDTH_OES"/> + <value name="GL_RENDERBUFFER_HEIGHT_OES"/> + <value name="GL_RENDERBUFFER_INTERNAL_FORMAT_OES"/> + <value name="GL_RENDERBUFFER_RED_SIZE_OES"/> + <value name="GL_RENDERBUFFER_GREEN_SIZE_OES"/> + <value name="GL_RENDERBUFFER_BLUE_SIZE_OES"/> + <value name="GL_RENDERBUFFER_ALPHA_SIZE_OES"/> + <value name="GL_RENDERBUFFER_DEPTH_SIZE_OES"/> + <value name="GL_RENDERBUFFER_STENCIL_SIZE_OES"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> + + <desc name="pname" category="GLES2.0"> + <value name="GL_RENDERBUFFER_WIDTH"/> + <value name="GL_RENDERBUFFER_HEIGHT"/> + <value name="GL_RENDERBUFFER_INTERNAL_FORMAT"/> + <value name="GL_RENDERBUFFER_RED_SIZE"/> + <value name="GL_RENDERBUFFER_GREEN_SIZE"/> + <value name="GL_RENDERBUFFER_BLUE_SIZE"/> + <value name="GL_RENDERBUFFER_ALPHA_SIZE"/> + <value name="GL_RENDERBUFFER_DEPTH_SIZE"/> + <value name="GL_RENDERBUFFER_STENCIL_SIZE"/> + + <desc name="params" vector_size="1" convert="false"/> + </desc> +</template> + +<template name="IsRenderbuffer" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="renderbuffer" type="GLuint"/> + </proto> +</template> + +<template name="IsFramebuffer" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="framebuffer" type="GLuint"/> + </proto> +</template> + +<template name="IsShader" direction="get"> + <proto> + <return type="GLboolean"/> + <param name="shader" type="GLuint"/> + </proto> +</template> + +<template name="GetShader" direction="get"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + <param name="pname" type="GLenum"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> + + <desc name="pname"> + <value name="GL_SHADER_TYPE"/> + <value name="GL_COMPILE_STATUS"/> + <value name="GL_DELETE_STATUS"/> + <value name="GL_INFO_LOG_LENGTH"/> + <value name="GL_SHADER_SOURCE_LENGTH"/> + </desc> +</template> + +<template name="GetAttachedShaders" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="maxCount" type="GLsizei"/> + <param name="count" type="GLsizei *"/> + <param name="shaders" type="GLuint *"/> + </proto> +</template> + +<template name="GetShaderInfoLog" direction="get"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="infoLog" type="GLchar *"/> + </proto> +</template> + +<template name="GetProgramInfoLog" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="infoLog" type="GLchar *"/> + </proto> +</template> + +<template name="GetShaderSource" direction="get"> + <proto> + <return type="void"/> + <param name="shader" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="source" type="GLchar *"/> + </proto> +</template> + +<template name="GetShaderPrecisionFormat" direction="get"> + <proto> + <return type="void"/> + <param name="shadertype" type="GLenum"/> + <param name="precisiontype" type="GLenum"/> + <param name="range" type="GLint *"/> + <param name="precision" type="GLint *"/> + </proto> + + <desc name="shadertype"> + <value name="GL_VERTEX_SHADER"/> + <value name="GL_FRAGMENT_SHADER"/> + </desc> + + <desc name="precisiontype"> + <value name="GL_LOW_FLOAT"/> + <value name="GL_MEDIUM_FLOAT"/> + <value name="GL_HIGH_FLOAT"/> + <value name="GL_LOW_INT"/> + <value name="GL_MEDIUM_INT"/> + <value name="GL_HIGH_INT"/> + </desc> +</template> + +<template name="GetUniform" direction="get"> + <proto> + <return type="void"/> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <vector name="params" type="GLtype *" size="dynamic"/> + </proto> +</template> + +<template name="QueryMatrix" direction="get"> + <proto> + <return type="GLbitfield"/> + <vector name="mantissa" type="GLtype *" size="16"/> + <vector name="exponent" type="GLint *" size="16"/> + </proto> +</template> + +<template name="DrawTex"> + <proto> + <return type="void"/> + <vector name="coords" type="const GLtype *" size="5"> + <param name="x" type="GLtype"/> + <param name="y" type="GLtype"/> + <param name="z" type="GLtype"/> + <param name="w" type="GLtype"/> + <param name="h" type="GLtype"/> + </vector> + </proto> +</template> + +<template name="MultiDrawArrays"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint *"/> + <param name="count" type="GLsizei *"/> + <param name="primcount" type="GLsizei"/> + </proto> + + <desc name="mode"> + <value name="GL_POINTS"/> + <value name="GL_LINES"/> + <value name="GL_LINE_LOOP"/> + <value name="GL_LINE_STRIP"/> + <value name="GL_TRIANGLES"/> + <value name="GL_TRIANGLE_STRIP"/> + <value name="GL_TRIANGLE_FAN"/> + </desc> +</template> + +<template name="MultiDrawElements"> + <proto> + <return type="void"/> + <param name="mode" type="GLenum"/> + <param name="count" type="const GLsizei *"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid **"/> + <param name="primcount" type="GLsizei"/> + </proto> + + <desc name="mode"> + <value name="GL_POINTS"/> + <value name="GL_LINES"/> + <value name="GL_LINE_LOOP"/> + <value name="GL_LINE_STRIP"/> + <value name="GL_TRIANGLES"/> + <value name="GL_TRIANGLE_STRIP"/> + <value name="GL_TRIANGLE_FAN"/> + </desc> + + <desc name="type"> + <value name="GL_UNSIGNED_BYTE"/> + <value name="GL_UNSIGNED_SHORT"/> + <!-- GL_UNSIGNED_INT is not defined in GLES1.1 headers --> + <value name="(0x1405 /* GL_UNSIGNED_INT */)" category="OES_element_index_uint"/> + </desc> +</template> + +<api name="mesa" implementation="true"> + <category name="MESA"/> + + <function name="Color4f" default_prefix="_vbo_" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="ClipPlane" template="ClipPlane" gltype="GLdouble"/> + <function name="CullFace" template="CullFace"/> + + <function name="Fogf" template="Fog" gltype="GLfloat" expand_vector="true"/> + <function name="Fogfv" template="Fog" gltype="GLfloat"/> + + <function name="FrontFace" template="FrontFace"/> + <function name="Hint" template="Hint"/> + + <function name="Lightf" template="Light" gltype="GLfloat" expand_vector="true"/> + <function name="Lightfv" template="Light" gltype="GLfloat"/> + + <function name="LightModelf" template="LightModel" gltype="GLfloat" expand_vector="true"/> + <function name="LightModelfv" template="LightModel" gltype="GLfloat"/> + + <function name="LineWidth" template="LineWidth" gltype="GLfloat"/> + + <function name="Materialf" default_prefix="_vbo_" template="Material" gltype="GLfloat" expand_vector="true"/> + <function name="Materialfv" default_prefix="_vbo_" template="Material" gltype="GLfloat"/> + + <function name="PointSize" template="PointSize" gltype="GLfloat"/> + <function name="PointSizePointer" template="PointSizePointer"/> + + <function name="Scissor" template="Scissor"/> + <function name="ShadeModel" template="ShadeModel"/> + + <function name="TexParameterf" template="TexParameter" gltype="GLfloat" expand_vector="true"/> + <function name="TexParameterfv" template="TexParameter" gltype="GLfloat"/> + <function name="TexParameteri" template="TexParameter" gltype="GLint" expand_vector="true"/> + <function name="TexParameteriv" template="TexParameter" gltype="GLint"/> + + <function name="TexImage2D" template="TexImage2D"/> + + <function name="TexEnvf" template="TexEnv" gltype="GLfloat" expand_vector="true"/> + <function name="TexEnvi" template="TexEnv" gltype="GLint" expand_vector="true"/> + <function name="TexEnvfv" template="TexEnv" gltype="GLfloat"/> + <function name="TexEnviv" template="TexEnv" gltype="GLint"/> + + <function name="TexGenf" template="TexGen" gltype="GLfloat" expand_vector="true"/> + <function name="TexGenfv" template="TexGen" gltype="GLfloat"/> + + <function name="Clear" template="Clear"/> + <function name="ClearColor" template="ClearColor" gltype="GLclampf"/> + <function name="ClearStencil" template="ClearStencil"/> + <function name="ClearDepth" template="ClearDepth" gltype="GLclampd"/> + + <function name="StencilMask" template="StencilMask"/> + <function name="StencilMaskSeparate" template="StencilMaskSeparate"/> + <function name="ColorMask" template="ColorMask"/> + <function name="DepthMask" template="DepthMask"/> + <function name="Disable" template="Disable"/> + <function name="Enable" template="Enable"/> + <function name="Finish" template="Finish"/> + <function name="Flush" template="Flush"/> + + <function name="AlphaFunc" template="AlphaFunc" gltype="GLclampf"/> + + <function name="BlendFunc" template="BlendFunc"/> + <function name="LogicOp" template="LogicOp"/> + <function name="StencilFunc" template="StencilFunc"/> + <function name="StencilFuncSeparate" template="StencilFuncSeparate"/> + <function name="StencilOp" template="StencilOp"/> + <function name="StencilOpSeparate" template="StencilOpSeparate"/> + <function name="DepthFunc" template="DepthFunc"/> + <function name="PixelStorei" template="PixelStore" gltype="GLint"/> + + <function name="ReadPixels" template="ReadPixels"/> + <function name="GetBooleanv" template="GetState" gltype="GLboolean"/> + <function name="GetClipPlane" template="GetClipPlane" gltype="GLdouble"/> + <function name="GetError" template="GetError"/> + <function name="GetFloatv" template="GetState" gltype="GLfloat"/> + <function name="GetFixedv" template="GetState" gltype="GLfixed"/> + <function name="GetIntegerv" template="GetState" gltype="GLint"/> + + <function name="GetLightfv" template="GetLight" gltype="GLfloat"/> + <function name="GetMaterialfv" template="GetMaterial" gltype="GLfloat"/> + <function name="GetMaterialiv" template="GetMaterial" gltype="GLint"/> + + <function name="GetString" template="GetString"/> + + <function name="GetTexEnvfv" template="GetTexEnv" gltype="GLfloat"/> + <function name="GetTexEnviv" template="GetTexEnv" gltype="GLint"/> + <function name="GetTexGenfv" template="GetTexGen" gltype="GLfloat"/> + <function name="GetTexParameterfv" template="GetTexParameter" gltype="GLfloat"/> + <function name="GetTexParameteriv" template="GetTexParameter" gltype="GLint"/> + + <function name="IsEnabled" template="IsEnabled"/> + + <function name="DepthRange" template="DepthRange" gltype="GLclampd"/> + <function name="Frustum" template="Frustum" gltype="GLdouble"/> + + <function name="LoadIdentity" template="LoadIdentity"/> + <function name="LoadMatrixf" template="LoadMatrix" gltype="GLfloat"/> + <function name="MatrixMode" template="MatrixMode"/> + + <function name="MultMatrixf" template="MultMatrix" gltype="GLfloat"/> + <function name="Ortho" template="Ortho" gltype="GLdouble"/> + <function name="PopMatrix" template="PopMatrix"/> + <function name="PushMatrix" template="PushMatrix"/> + + <function name="Rotatef" template="Rotate" gltype="GLfloat"/> + <function name="Scalef" template="Scale" gltype="GLfloat"/> + <function name="Translatef" template="Translate" gltype="GLfloat"/> + + <function name="Viewport" template="Viewport"/> + + <function name="ColorPointer" template="ColorPointer"/> + <function name="DisableClientState" template="DisableClientState"/> + <function name="DrawArrays" template="DrawArrays"/> + <function name="DrawElements" template="DrawElements"/> + <function name="EnableClientState" template="EnableClientState"/> + + <function name="GetPointerv" template="GetPointer"/> + <function name="Normal3f" default_prefix="_vbo_" template="Normal" gltype="GLfloat" expand_vector="true"/> + <function name="NormalPointer" template="NormalPointer"/> + <function name="TexCoordPointer" template="TexCoordPointer"/> + <function name="VertexPointer" template="VertexPointer"/> + + <function name="PolygonOffset" template="PolygonOffset" gltype="GLfloat"/> + <function name="CopyTexImage2D" template="CopyTexImage2D"/> + <function name="CopyTexSubImage2D" template="CopyTexSubImage2D"/> + <function name="TexSubImage2D" template="TexSubImage2D"/> + + <function name="BindTexture" template="BindTexture"/> + <function name="DeleteTextures" template="DeleteTextures"/> + <function name="GenTextures" template="GenTextures"/> + <function name="IsTexture" template="IsTexture"/> + + <function name="BlendColor" template="BlendColor" gltype="GLclampf"/> + <function name="BlendEquation" template="BlendEquation"/> + <function name="BlendEquationSeparateEXT" template="BlendEquationSeparate"/> + + <function name="TexImage3D" template="TexImage3D"/> + <function name="TexSubImage3D" template="TexSubImage3D"/> + <function name="CopyTexSubImage3D" template="CopyTexSubImage3D"/> + + <function name="CompressedTexImage3DARB" template="CompressedTexImage3D"/> + <function name="CompressedTexSubImage3DARB" template="CompressedTexSubImage3D"/> + + <function name="ActiveTextureARB" template="ActiveTexture"/> + <function name="ClientActiveTextureARB" template="ClientActiveTexture"/> + + <function name="MultiTexCoord4f" default_prefix="_vbo_" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> + + <function name="SampleCoverageARB" template="SampleCoverage" gltype="GLclampf"/> + + <function name="CompressedTexImage2DARB" template="CompressedTexImage2D"/> + <function name="CompressedTexSubImage2DARB" template="CompressedTexSubImage2D"/> + + <function name="BlendFuncSeparateEXT" template="BlendFuncSeparate"/> + + <function name="PointParameterf" template="PointParameter" gltype="GLfloat" expand_vector="true"/> + <function name="PointParameterfv" template="PointParameter" gltype="GLfloat"/> + + <function name="VertexAttrib1f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="VertexAttrib2f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="VertexAttrib3f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="VertexAttrib4f" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="VertexAttrib1fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> + <function name="VertexAttrib2fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> + <function name="VertexAttrib3fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> + <function name="VertexAttrib4fv" default_prefix="_vbo_" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> + + <function name="VertexAttribPointerARB" template="VertexAttribPointer"/> + <function name="EnableVertexAttribArrayARB" template="EnableVertexAttribArray"/> + <function name="DisableVertexAttribArrayARB" template="DisableVertexAttribArray"/> + + <function name="IsProgram" template="IsProgram"/> + <function name="GetProgramiv" template="GetProgram" gltype="GLint"/> + + <function name="GetVertexAttribfvARB" template="GetVertexAttrib" gltype="GLfloat"/> + <function name="GetVertexAttribivARB" template="GetVertexAttrib" gltype="GLint"/> + <function name="GetVertexAttribPointervARB" template="GetVertexAttribPointer"/> + + <function name="GetBufferPointervARB" template="GetBufferPointer"/> + <function name="MapBufferARB" template="MapBuffer"/> + <function name="UnmapBufferARB" template="UnmapBuffer"/> + <function name="BindBufferARB" template="BindBuffer"/> + <function name="BufferDataARB" template="BufferData"/> + <function name="BufferSubDataARB" template="BufferSubData"/> + <function name="DeleteBuffersARB" template="DeleteBuffers"/> + <function name="GenBuffersARB" template="GenBuffers"/> + <function name="GetBufferParameterivARB" template="GetBufferParameter" gltype="GLint"/> + <function name="IsBufferARB" template="IsBuffer"/> + + <function name="CreateShader" template="CreateShader"/> + <function name="ShaderSourceARB" template="ShaderSource"/> + <function name="CompileShaderARB" template="CompileShader"/> + <function name="ReleaseShaderCompiler" template="ReleaseShaderCompiler"/> + <function name="DeleteShader" template="DeleteShader"/> + <function name="ShaderBinary" template="ShaderBinary"/> + <function name="CreateProgram" template="CreateProgram"/> + <function name="AttachShader" template="AttachShader"/> + <function name="DetachShader" template="DetachShader"/> + <function name="LinkProgramARB" template="LinkProgram"/> + <function name="UseProgramObjectARB" template="UseProgram"/> + <function name="DeleteProgram" template="DeleteProgram"/> + + <function name="GetActiveAttribARB" template="GetActiveAttrib"/> + <function name="GetAttribLocationARB" template="GetAttribLocation"/> + <function name="BindAttribLocationARB" template="BindAttribLocation"/> + <function name="GetUniformLocationARB" template="GetUniformLocation"/> + <function name="GetActiveUniformARB" template="GetActiveUniform"/> + + <function name="Uniform1fARB" template="Uniform" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="Uniform2fARB" template="Uniform" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="Uniform3fARB" template="Uniform" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="Uniform4fARB" template="Uniform" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="Uniform1iARB" template="Uniform" gltype="GLint" vector_size="1" expand_vector="true"/> + <function name="Uniform2iARB" template="Uniform" gltype="GLint" vector_size="2" expand_vector="true"/> + <function name="Uniform3iARB" template="Uniform" gltype="GLint" vector_size="3" expand_vector="true"/> + <function name="Uniform4iARB" template="Uniform" gltype="GLint" vector_size="4" expand_vector="true"/> + <function name="Uniform1fvARB" template="Uniform" gltype="GLfloat" vector_size="1"/> + <function name="Uniform2fvARB" template="Uniform" gltype="GLfloat" vector_size="2"/> + <function name="Uniform3fvARB" template="Uniform" gltype="GLfloat" vector_size="3"/> + <function name="Uniform4fvARB" template="Uniform" gltype="GLfloat" vector_size="4"/> + <function name="Uniform1ivARB" template="Uniform" gltype="GLint" vector_size="1"/> + <function name="Uniform2ivARB" template="Uniform" gltype="GLint" vector_size="2"/> + <function name="Uniform3ivARB" template="Uniform" gltype="GLint" vector_size="3"/> + <function name="Uniform4ivARB" template="Uniform" gltype="GLint" vector_size="4"/> + + <function name="UniformMatrix2fvARB" template="UniformMatrix" gltype="GLfloat" vector_size="2"/> + <function name="UniformMatrix3fvARB" template="UniformMatrix" gltype="GLfloat" vector_size="3"/> + <function name="UniformMatrix4fvARB" template="UniformMatrix" gltype="GLfloat" vector_size="4"/> + + <function name="ValidateProgramARB" template="ValidateProgram"/> + + <function name="GenerateMipmapEXT" template="GenerateMipmap"/> + <function name="BindFramebufferEXT" template="BindFramebuffer"/> + <function name="DeleteFramebuffersEXT" template="DeleteFramebuffers"/> + <function name="GenFramebuffersEXT" template="GenFramebuffers"/> + <function name="BindRenderbufferEXT" template="BindRenderbuffer"/> + <function name="DeleteRenderbuffersEXT" template="DeleteRenderbuffers"/> + <function name="GenRenderbuffersEXT" template="GenRenderbuffers"/> + <function name="RenderbufferStorageEXT" template="RenderbufferStorage"/> + <function name="FramebufferRenderbufferEXT" template="FramebufferRenderbuffer"/> + <function name="FramebufferTexture2DEXT" template="FramebufferTexture2D"/> + <function name="FramebufferTexture3DEXT" template="FramebufferTexture3D"/> + <function name="CheckFramebufferStatusEXT" template="CheckFramebufferStatus"/> + <function name="GetFramebufferAttachmentParameterivEXT" template="GetFramebufferAttachmentParameter" gltype="GLint"/> + <function name="GetRenderbufferParameterivEXT" template="GetRenderbufferParameter" gltype="GLint"/> + <function name="IsRenderbufferEXT" template="IsRenderbuffer"/> + <function name="IsFramebufferEXT" template="IsFramebuffer"/> + + <function name="IsShader" template="IsShader"/> + <function name="GetShaderiv" template="GetShader" gltype="GLint"/> + <function name="GetAttachedShaders" template="GetAttachedShaders"/> + <function name="GetShaderInfoLog" template="GetShaderInfoLog"/> + <function name="GetProgramInfoLog" template="GetProgramInfoLog"/> + <function name="GetShaderSourceARB" template="GetShaderSource"/> + <function name="GetShaderPrecisionFormat" template="GetShaderPrecisionFormat"/> + <function name="GetUniformfvARB" template="GetUniform" gltype="GLfloat"/> + <function name="GetUniformivARB" template="GetUniform" gltype="GLint"/> + + <function name="DrawTexf" template="DrawTex" gltype="GLfloat" expand_vector="true"/> + <function name="DrawTexfv" template="DrawTex" gltype="GLfloat"/> + <function name="DrawTexi" template="DrawTex" gltype="GLint" expand_vector="true"/> + <function name="DrawTexiv" template="DrawTex" gltype="GLint"/> + <function name="DrawTexs" template="DrawTex" gltype="GLshort" expand_vector="true"/> + <function name="DrawTexsv" template="DrawTex" gltype="GLshort"/> + + <!-- EXT_multi_draw_arrays --> + <function name="MultiDrawArraysEXT" template="MultiDrawArrays"/> + <function name="MultiDrawElementsEXT" template="MultiDrawElements"/> +</api> + +<api name="GLES1.1"> + <category name="GLES1.1"/> + + <category name="OES_byte_coordinates"/> + <category name="OES_fixed_point"/> + <category name="OES_single_precision"/> + <category name="OES_matrix_get"/> + <category name="OES_read_format"/> + <category name="OES_compressed_paletted_texture"/> + <category name="OES_point_size_array"/> + <category name="OES_point_sprite"/> + <category name="OES_query_matrix"/> + <category name="OES_draw_texture"/> + <category name="OES_blend_equation_separate"/> + <category name="OES_blend_func_separate"/> + <category name="OES_blend_subtract"/> + <category name="OES_stencil_wrap"/> + <category name="OES_texture_cube_map"/> + <category name="OES_texture_env_crossbar"/> + <category name="OES_texture_mirrored_repeat"/> + <category name="OES_framebuffer_object"/> + <category name="OES_depth24"/> + <category name="OES_depth32"/> + <category name="OES_fbo_render_mipmap"/> + <category name="OES_rgb8_rgba8"/> + <category name="OES_stencil1"/> + <category name="OES_stencil4"/> + <category name="OES_stencil8"/> + <category name="OES_element_index_uint"/> + <category name="OES_mapbuffer"/> + <category name="EXT_texture_filter_anisotropic"/> + + <category name="ARB_texture_non_power_of_two"/> + <!-- disabled due to missing enums + <category name="EXT_texture_compression_dxt1"/> + <category name="EXT_texture_lod_bias"/> + <category name="EXT_blend_minmax"/> + --> + <category name="EXT_multi_draw_arrays"/> + + <category name="OES_matrix_palette"/> + + <function name="Color4f" template="Color" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="Color4ub" template="Color" gltype="GLubyte" vector_size="4" expand_vector="true"/> + <function name="Color4x" template="Color" gltype="GLfixed" vector_size="4" expand_vector="true"/> + + <function name="ClipPlanef" template="ClipPlane" gltype="GLfloat"/> + <function name="ClipPlanex" template="ClipPlane" gltype="GLfixed"/> + + <function name="CullFace" template="CullFace"/> + + <function name="Fogf" template="Fog" gltype="GLfloat" expand_vector="true"/> + <function name="Fogx" template="Fog" gltype="GLfixed" expand_vector="true"/> + <function name="Fogfv" template="Fog" gltype="GLfloat"/> + <function name="Fogxv" template="Fog" gltype="GLfixed"/> + + <function name="FrontFace" template="FrontFace"/> + <function name="Hint" template="Hint"/> + + <function name="Lightf" template="Light" gltype="GLfloat" expand_vector="true"/> + <function name="Lightx" template="Light" gltype="GLfixed" expand_vector="true"/> + <function name="Lightfv" template="Light" gltype="GLfloat"/> + <function name="Lightxv" template="Light" gltype="GLfixed"/> + + <function name="LightModelf" template="LightModel" gltype="GLfloat" expand_vector="true"/> + <function name="LightModelx" template="LightModel" gltype="GLfixed" expand_vector="true"/> + <function name="LightModelfv" template="LightModel" gltype="GLfloat"/> + <function name="LightModelxv" template="LightModel" gltype="GLfixed"/> + + <function name="LineWidth" template="LineWidth" gltype="GLfloat"/> + <function name="LineWidthx" template="LineWidth" gltype="GLfixed"/> + + <function name="Materialf" template="Material" gltype="GLfloat" expand_vector="true"/> + <function name="Materialfv" template="Material" gltype="GLfloat"/> + <function name="Materialx" template="Material" gltype="GLfixed" expand_vector="true"/> + <function name="Materialxv" template="Material" gltype="GLfixed"/> + + <function name="PointSize" template="PointSize" gltype="GLfloat"/> + <function name="PointSizex" template="PointSize" gltype="GLfixed"/> + <function name="PointSizePointerOES" template="PointSizePointer"/> + + <function name="Scissor" template="Scissor"/> + <function name="ShadeModel" template="ShadeModel"/> + + <function name="TexParameterf" template="TexParameter" gltype="GLfloat" expand_vector="true"/> + <function name="TexParameterfv" template="TexParameter" gltype="GLfloat"/> + <function name="TexParameteri" template="TexParameter" gltype="GLint" expand_vector="true"/> + <function name="TexParameteriv" template="TexParameter" gltype="GLint"/> + <function name="TexParameterx" template="TexParameter" gltype="GLfixed" expand_vector="true"/> + <function name="TexParameterxv" template="TexParameter" gltype="GLfixed"/> + + <function name="TexImage2D" template="TexImage2D"/> + + <function name="TexEnvf" template="TexEnv" gltype="GLfloat" expand_vector="true"/> + <function name="TexEnvfv" template="TexEnv" gltype="GLfloat"/> + <function name="TexEnvi" template="TexEnv" gltype="GLint" expand_vector="true"/> + <function name="TexEnviv" template="TexEnv" gltype="GLint"/> + <function name="TexEnvx" template="TexEnv" gltype="GLfixed" expand_vector="true"/> + <function name="TexEnvxv" template="TexEnv" gltype="GLfixed"/> + + <function name="TexGenfOES" external="true" template="TexGen" gltype="GLfloat" expand_vector="true"/> + <function name="TexGenfvOES" external="true" template="TexGen" gltype="GLfloat"/> + <function name="TexGeniOES" external="true" template="TexGen" gltype="GLint" expand_vector="true"/> + <function name="TexGenivOES" external="true" template="TexGen" gltype="GLint"/> + <function name="TexGenxOES" external="true" template="TexGen" gltype="GLfixed" expand_vector="true"/> + <function name="TexGenxvOES" external="true" template="TexGen" gltype="GLfixed"/> + + <function name="Clear" template="Clear"/> + <function name="ClearColor" template="ClearColor" gltype="GLclampf"/> + <function name="ClearColorx" template="ClearColor" gltype="GLclampx"/> + + <function name="ClearStencil" template="ClearStencil"/> + <function name="ClearDepthf" template="ClearDepth" gltype="GLclampf"/> + <function name="ClearDepthx" template="ClearDepth" gltype="GLclampx"/> + + <function name="StencilMask" template="StencilMask"/> + <function name="ColorMask" template="ColorMask"/> + <function name="DepthMask" template="DepthMask"/> + + <function name="Disable" external="true" template="Disable"/> + <function name="Enable" external="true" template="Enable"/> + <function name="Finish" template="Finish"/> + <function name="Flush" template="Flush"/> + + <function name="AlphaFunc" template="AlphaFunc" gltype="GLclampf"/> + <function name="AlphaFuncx" template="AlphaFunc" gltype="GLclampx"/> + + <function name="BlendFunc" template="BlendFunc"/> + <function name="LogicOp" template="LogicOp"/> + <function name="StencilFunc" template="StencilFunc"/> + + <function name="StencilOp" template="StencilOp"/> + <function name="DepthFunc" template="DepthFunc"/> + + <function name="PixelStorei" template="PixelStore" gltype="GLint"/> + <function name="ReadPixels" template="ReadPixels"/> + + <function name="GetBooleanv" template="GetState" gltype="GLboolean"/> + + <function name="GetClipPlanef" template="GetClipPlane" gltype="GLfloat"/> + <function name="GetClipPlanex" template="GetClipPlane" gltype="GLfixed"/> + + <function name="GetError" template="GetError"/> + <function name="GetFloatv" template="GetState" gltype="GLfloat"/> + <function name="GetFixedv" template="GetState" gltype="GLfixed"/> + <function name="GetIntegerv" template="GetState" gltype="GLint"/> + + <function name="GetLightfv" template="GetLight" gltype="GLfloat"/> + <function name="GetLightxv" template="GetLight" gltype="GLfixed"/> + + <function name="GetMaterialfv" template="GetMaterial" gltype="GLfloat"/> + <function name="GetMaterialxv" template="GetMaterial" gltype="GLfixed"/> + + <function name="GetString" external="true" template="GetString"/> + + <function name="GetTexEnvfv" template="GetTexEnv" gltype="GLfloat"/> + <function name="GetTexEnviv" template="GetTexEnv" gltype="GLint"/> + <function name="GetTexEnvxv" template="GetTexEnv" gltype="GLfixed"/> + + <function name="GetTexGenfvOES" external="true" template="GetTexGen" gltype="GLfloat"/> + <function name="GetTexGenivOES" external="true" template="GetTexGen" gltype="GLint"/> + <function name="GetTexGenxvOES" external="true" template="GetTexGen" gltype="GLfixed"/> + + <function name="GetTexParameterfv" template="GetTexParameter" gltype="GLfloat"/> + <function name="GetTexParameteriv" template="GetTexParameter" gltype="GLint"/> + <function name="GetTexParameterxv" template="GetTexParameter" gltype="GLfixed"/> + + <function name="IsEnabled" external="true" template="IsEnabled"/> + + <function name="DepthRangef" template="DepthRange" gltype="GLclampf"/> + <function name="DepthRangex" template="DepthRange" gltype="GLclampx"/> + + <function name="Frustumf" template="Frustum" gltype="GLfloat"/> + <function name="Frustumx" template="Frustum" gltype="GLfixed"/> + + <function name="LoadIdentity" template="LoadIdentity"/> + <function name="LoadMatrixf" template="LoadMatrix" gltype="GLfloat"/> + <function name="LoadMatrixx" template="LoadMatrix" gltype="GLfixed"/> + <function name="MatrixMode" template="MatrixMode"/> + + <function name="MultMatrixf" template="MultMatrix" gltype="GLfloat"/> + <function name="MultMatrixx" template="MultMatrix" gltype="GLfixed"/> + <function name="Orthof" template="Ortho" gltype="GLfloat"/> + <function name="Orthox" template="Ortho" gltype="GLfixed"/> + + <function name="PopMatrix" template="PopMatrix"/> + <function name="PushMatrix" template="PushMatrix"/> + + <function name="Rotatef" template="Rotate" gltype="GLfloat"/> + <function name="Rotatex" template="Rotate" gltype="GLfixed"/> + <function name="Scalef" template="Scale" gltype="GLfloat"/> + <function name="Scalex" template="Scale" gltype="GLfixed"/> + <function name="Translatef" template="Translate" gltype="GLfloat"/> + <function name="Translatex" template="Translate" gltype="GLfixed"/> + + <function name="Viewport" template="Viewport"/> + <function name="ColorPointer" template="ColorPointer"/> + <function name="DisableClientState" template="DisableClientState"/> + <function name="DrawArrays" template="DrawArrays"/> + <function name="DrawElements" template="DrawElements"/> + <function name="EnableClientState" template="EnableClientState"/> + + <function name="GetPointerv" template="GetPointer"/> + + <function name="Normal3f" template="Normal" gltype="GLfloat" expand_vector="true"/> + <function name="Normal3x" template="Normal" gltype="GLfixed" expand_vector="true"/> + <function name="NormalPointer" template="NormalPointer"/> + <function name="TexCoordPointer" template="TexCoordPointer"/> + <function name="VertexPointer" template="VertexPointer"/> + + <function name="PolygonOffset" template="PolygonOffset" gltype="GLfloat"/> + <function name="PolygonOffsetx" template="PolygonOffset" gltype="GLfixed"/> + + <function name="CopyTexImage2D" template="CopyTexImage2D"/> + <function name="CopyTexSubImage2D" template="CopyTexSubImage2D"/> + + <function name="TexSubImage2D" template="TexSubImage2D"/> + + <function name="BindTexture" template="BindTexture"/> + <function name="DeleteTextures" template="DeleteTextures"/> + <function name="GenTextures" template="GenTextures"/> + <function name="IsTexture" template="IsTexture"/> + + <function name="BlendEquationOES" template="BlendEquation"/> + <function name="BlendEquationSeparateOES" template="BlendEquationSeparate"/> + + <function name="MultiTexCoord4x" template="MultiTexCoord" gltype="GLfixed" vector_size="4" expand_vector="true"/> + + <function name="ActiveTexture" template="ActiveTexture"/> + <function name="ClientActiveTexture" template="ClientActiveTexture"/> + + <function name="MultiTexCoord4f" template="MultiTexCoord" gltype="GLfloat" vector_size="4" expand_vector="true"/> + + <function name="SampleCoverage" template="SampleCoverage" gltype="GLclampf"/> + <function name="SampleCoveragex" template="SampleCoverage" gltype="GLclampx"/> + + <!-- CompressedTexImage2D calls out to two different functions based on + whether the image is a paletted image or not --> + <function name="CompressedTexImage2D" external="true" template="CompressedTexImage2D"/> + <function name="CompressedTexSubImage2D" template="CompressedTexSubImage2D"/> + + <function name="BlendFuncSeparateOES" template="BlendFuncSeparate"/> + + <function name="PointParameterf" template="PointParameter" gltype="GLfloat" expand_vector="true"/> + <function name="PointParameterfv" template="PointParameter" gltype="GLfloat"/> + <function name="PointParameterx" template="PointParameter" gltype="GLfixed" expand_vector="true"/> + <function name="PointParameterxv" template="PointParameter" gltype="GLfixed"/> + + <!-- OES_mapbuffer --> + <function name="GetBufferPointervOES" template="GetBufferPointer"/> + <function name="MapBufferOES" template="MapBuffer"/> + <function name="UnmapBufferOES" template="UnmapBuffer"/> + + <function name="BindBuffer" template="BindBuffer"/> + <function name="BufferData" template="BufferData"/> + <function name="BufferSubData" template="BufferSubData"/> + <function name="DeleteBuffers" template="DeleteBuffers"/> + <function name="GenBuffers" template="GenBuffers"/> + <function name="GetBufferParameteriv" template="GetBufferParameter" gltype="GLint"/> + <function name="IsBuffer" template="IsBuffer"/> + + <!-- OES_framebuffer_object --> + <function name="GenerateMipmapOES" template="GenerateMipmap"/> + <function name="BindFramebufferOES" template="BindFramebuffer"/> + <function name="DeleteFramebuffersOES" template="DeleteFramebuffers"/> + <function name="GenFramebuffersOES" template="GenFramebuffers"/> + <function name="BindRenderbufferOES" template="BindRenderbuffer"/> + <function name="DeleteRenderbuffersOES" template="DeleteRenderbuffers"/> + <function name="GenRenderbuffersOES" template="GenRenderbuffers"/> + <function name="RenderbufferStorageOES" external="true" template="RenderbufferStorage"/> + <function name="FramebufferRenderbufferOES" template="FramebufferRenderbuffer"/> + <function name="FramebufferTexture2DOES" template="FramebufferTexture2D"/> + <function name="CheckFramebufferStatusOES" template="CheckFramebufferStatus"/> + <function name="GetFramebufferAttachmentParameterivOES" template="GetFramebufferAttachmentParameter" gltype="GLint"/> + <function name="GetRenderbufferParameterivOES" template="GetRenderbufferParameter" gltype="GLint"/> + <function name="IsRenderbufferOES" template="IsRenderbuffer"/> + <function name="IsFramebufferOES" template="IsFramebuffer"/> + + <!-- OES_query_matrix --> + <!-- QueryMatrixx returns values in an unusual, decomposed, fixed-value + form; it has its own code for this --> + <function name="QueryMatrixxOES" external="true" template="QueryMatrix" gltype="GLfixed"/> + + <!-- OES_draw_texture --> + <function name="DrawTexfOES" template="DrawTex" gltype="GLfloat" expand_vector="true"/> + <function name="DrawTexiOES" template="DrawTex" gltype="GLint" expand_vector="true"/> + <function name="DrawTexsOES" template="DrawTex" gltype="GLshort" expand_vector="true"/> + <function name="DrawTexxOES" template="DrawTex" gltype="GLfixed" expand_vector="true"/> + <function name="DrawTexfvOES" template="DrawTex" gltype="GLfloat"/> + <function name="DrawTexivOES" template="DrawTex" gltype="GLint"/> + <function name="DrawTexsvOES" template="DrawTex" gltype="GLshort"/> + <function name="DrawTexxvOES" template="DrawTex" gltype="GLfixed"/> + + <!-- EXT_multi_draw_arrays --> + <function name="MultiDrawArraysEXT" template="MultiDrawArrays"/> + <function name="MultiDrawElementsEXT" template="MultiDrawElements"/> +</api> + +<api name="GLES2.0"> + <category name="GLES2.0"/> + + <category name="OES_compressed_paletted_texture"/> + <category name="OES_depth24"/> + <category name="OES_depth32"/> + <category name="OES_fbo_render_mipmap"/> + <category name="OES_rgb8_rgba8"/> + <category name="OES_stencil1"/> + <category name="OES_stencil4"/> + <category name="OES_element_index_uint"/> + <category name="OES_mapbuffer"/> + <category name="OES_texture_3D"/> + <category name="OES_texture_npot"/> + <category name="EXT_texture_filter_anisotropic"/> + <category name="EXT_texture_type_2_10_10_10_REV"/> + <category name="OES_depth_texture"/> + <category name="OES_packed_depth_stencil"/> + <category name="OES_standard_derivatives"/> + + <!-- disabled due to missing enums + <category name="EXT_texture_compression_dxt1"/> + <category name="EXT_blend_minmax"/> + --> + <category name="EXT_multi_draw_arrays"/> + + <function name="CullFace" template="CullFace"/> + + <function name="FrontFace" template="FrontFace"/> + <function name="Hint" template="Hint"/> + + <function name="LineWidth" template="LineWidth" gltype="GLfloat"/> + + <function name="Scissor" template="Scissor"/> + + <function name="TexParameterf" template="TexParameter" gltype="GLfloat" expand_vector="true"/> + <function name="TexParameterfv" template="TexParameter" gltype="GLfloat"/> + <function name="TexParameteri" template="TexParameter" gltype="GLint" expand_vector="true"/> + <function name="TexParameteriv" template="TexParameter" gltype="GLint"/> + + <function name="TexImage2D" template="TexImage2D"/> + + <function name="Clear" template="Clear"/> + <function name="ClearColor" template="ClearColor" gltype="GLclampf"/> + <function name="ClearStencil" template="ClearStencil"/> + <function name="ClearDepthf" template="ClearDepth" gltype="GLclampf"/> + + <function name="StencilMask" template="StencilMask"/> + <function name="StencilMaskSeparate" template="StencilMaskSeparate"/> + <function name="ColorMask" template="ColorMask"/> + <function name="DepthMask" template="DepthMask"/> + <function name="Disable" template="Disable"/> + <function name="Enable" template="Enable"/> + <function name="Finish" template="Finish"/> + <function name="Flush" template="Flush"/> + + <function name="BlendFunc" template="BlendFunc"/> + + <function name="StencilFunc" template="StencilFunc"/> + <function name="StencilFuncSeparate" template="StencilFuncSeparate"/> + <function name="StencilOp" template="StencilOp"/> + <function name="StencilOpSeparate" template="StencilOpSeparate"/> + + <function name="DepthFunc" template="DepthFunc"/> + + <function name="PixelStorei" template="PixelStore" gltype="GLint"/> + <function name="ReadPixels" template="ReadPixels"/> + + <function name="GetBooleanv" template="GetState" gltype="GLboolean"/> + <function name="GetError" template="GetError"/> + <function name="GetFloatv" template="GetState" gltype="GLfloat"/> + <function name="GetIntegerv" template="GetState" gltype="GLint"/> + + <function name="GetString" external="true" template="GetString"/> + + <function name="GetTexParameterfv" template="GetTexParameter" gltype="GLfloat"/> + <function name="GetTexParameteriv" template="GetTexParameter" gltype="GLint"/> + + <function name="IsEnabled" template="IsEnabled"/> + + <function name="DepthRangef" template="DepthRange" gltype="GLclampf"/> + + <function name="Viewport" template="Viewport"/> + + <function name="DrawArrays" template="DrawArrays"/> + <function name="DrawElements" template="DrawElements"/> + + <function name="PolygonOffset" template="PolygonOffset" gltype="GLfloat"/> + <function name="CopyTexImage2D" template="CopyTexImage2D"/> + <function name="CopyTexSubImage2D" template="CopyTexSubImage2D"/> + <function name="TexSubImage2D" template="TexSubImage2D"/> + + <function name="BindTexture" template="BindTexture"/> + <function name="DeleteTextures" template="DeleteTextures"/> + <function name="GenTextures" template="GenTextures"/> + <function name="IsTexture" template="IsTexture"/> + + <function name="BlendColor" template="BlendColor" gltype="GLclampf"/> + <function name="BlendEquation" template="BlendEquation"/> + <function name="BlendEquationSeparate" template="BlendEquationSeparate"/> + + <function name="TexImage3DOES" template="TexImage3D"/> + <function name="TexSubImage3DOES" template="TexSubImage3D"/> + <function name="CopyTexSubImage3DOES" template="CopyTexSubImage3D"/> + + <function name="CompressedTexImage3DOES" template="CompressedTexImage3D"/> + <function name="CompressedTexSubImage3DOES" template="CompressedTexSubImage3D"/> + + <function name="ActiveTexture" template="ActiveTexture"/> + + <function name="SampleCoverage" template="SampleCoverage" gltype="GLclampf"/> + + <function name="CompressedTexImage2D" external="true" template="CompressedTexImage2D"/> + <function name="CompressedTexSubImage2D" template="CompressedTexSubImage2D"/> + + <function name="BlendFuncSeparate" template="BlendFuncSeparate"/> + + <function name="VertexAttrib1f" template="VertexAttrib" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="VertexAttrib2f" template="VertexAttrib" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="VertexAttrib3f" template="VertexAttrib" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="VertexAttrib4f" template="VertexAttrib" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="VertexAttrib1fv" template="VertexAttrib" gltype="GLfloat" vector_size="1"/> + <function name="VertexAttrib2fv" template="VertexAttrib" gltype="GLfloat" vector_size="2"/> + <function name="VertexAttrib3fv" template="VertexAttrib" gltype="GLfloat" vector_size="3"/> + <function name="VertexAttrib4fv" template="VertexAttrib" gltype="GLfloat" vector_size="4"/> + + <function name="VertexAttribPointer" template="VertexAttribPointer"/> + + <function name="EnableVertexAttribArray" template="EnableVertexAttribArray"/> + <function name="DisableVertexAttribArray" template="DisableVertexAttribArray"/> + + <function name="IsProgram" template="IsProgram"/> + <function name="GetProgramiv" template="GetProgram" gltype="GLint"/> + + <function name="GetVertexAttribfv" template="GetVertexAttrib" gltype="GLfloat"/> + <function name="GetVertexAttribiv" template="GetVertexAttrib" gltype="GLint"/> + <function name="GetVertexAttribPointerv" template="GetVertexAttribPointer"/> + + <function name="GetBufferPointervOES" template="GetBufferPointer"/> + <function name="MapBufferOES" template="MapBuffer"/> + <function name="UnmapBufferOES" template="UnmapBuffer"/> + <function name="BindBuffer" template="BindBuffer"/> + <function name="BufferData" template="BufferData"/> + <function name="BufferSubData" template="BufferSubData"/> + <function name="DeleteBuffers" template="DeleteBuffers"/> + <function name="GenBuffers" template="GenBuffers"/> + <function name="GetBufferParameteriv" template="GetBufferParameter" gltype="GLint"/> + <function name="IsBuffer" template="IsBuffer"/> + + <function name="CreateShader" template="CreateShader"/> + <function name="ShaderSource" template="ShaderSource"/> + <function name="CompileShader" template="CompileShader"/> + <function name="ReleaseShaderCompiler" template="ReleaseShaderCompiler"/> + <function name="DeleteShader" template="DeleteShader"/> + <function name="ShaderBinary" template="ShaderBinary"/> + <function name="CreateProgram" template="CreateProgram"/> + <function name="AttachShader" template="AttachShader"/> + <function name="DetachShader" template="DetachShader"/> + <function name="LinkProgram" template="LinkProgram"/> + <function name="UseProgram" template="UseProgram"/> + <function name="DeleteProgram" template="DeleteProgram"/> + + <function name="GetActiveAttrib" template="GetActiveAttrib"/> + <function name="GetAttribLocation" template="GetAttribLocation"/> + <function name="BindAttribLocation" template="BindAttribLocation"/> + <function name="GetUniformLocation" template="GetUniformLocation"/> + <function name="GetActiveUniform" template="GetActiveUniform"/> + + <function name="Uniform1f" template="Uniform" gltype="GLfloat" vector_size="1" expand_vector="true"/> + <function name="Uniform2f" template="Uniform" gltype="GLfloat" vector_size="2" expand_vector="true"/> + <function name="Uniform3f" template="Uniform" gltype="GLfloat" vector_size="3" expand_vector="true"/> + <function name="Uniform4f" template="Uniform" gltype="GLfloat" vector_size="4" expand_vector="true"/> + <function name="Uniform1i" template="Uniform" gltype="GLint" vector_size="1" expand_vector="true"/> + <function name="Uniform2i" template="Uniform" gltype="GLint" vector_size="2" expand_vector="true"/> + <function name="Uniform3i" template="Uniform" gltype="GLint" vector_size="3" expand_vector="true"/> + <function name="Uniform4i" template="Uniform" gltype="GLint" vector_size="4" expand_vector="true"/> + + <function name="Uniform1fv" template="Uniform" gltype="GLfloat" vector_size="1"/> + <function name="Uniform2fv" template="Uniform" gltype="GLfloat" vector_size="2"/> + <function name="Uniform3fv" template="Uniform" gltype="GLfloat" vector_size="3"/> + <function name="Uniform4fv" template="Uniform" gltype="GLfloat" vector_size="4"/> + <function name="Uniform1iv" template="Uniform" gltype="GLint" vector_size="1"/> + <function name="Uniform2iv" template="Uniform" gltype="GLint" vector_size="2"/> + <function name="Uniform3iv" template="Uniform" gltype="GLint" vector_size="3"/> + <function name="Uniform4iv" template="Uniform" gltype="GLint" vector_size="4"/> + + <function name="UniformMatrix2fv" template="UniformMatrix" gltype="GLfloat" vector_size="2"/> + <function name="UniformMatrix3fv" template="UniformMatrix" gltype="GLfloat" vector_size="3"/> + <function name="UniformMatrix4fv" template="UniformMatrix" gltype="GLfloat" vector_size="4"/> + + <function name="ValidateProgram" template="ValidateProgram"/> + + <function name="GenerateMipmap" template="GenerateMipmap"/> + <function name="BindFramebuffer" template="BindFramebuffer"/> + <function name="DeleteFramebuffers" template="DeleteFramebuffers"/> + <function name="GenFramebuffers" template="GenFramebuffers"/> + <function name="BindRenderbuffer" template="BindRenderbuffer"/> + <function name="DeleteRenderbuffers" template="DeleteRenderbuffers"/> + <function name="GenRenderbuffers" template="GenRenderbuffers"/> + <function name="RenderbufferStorage" external="true" template="RenderbufferStorage"/> + <function name="FramebufferRenderbuffer" template="FramebufferRenderbuffer"/> + <function name="FramebufferTexture2D" template="FramebufferTexture2D"/> + <function name="FramebufferTexture3DOES" template="FramebufferTexture3D"/> + <function name="CheckFramebufferStatus" template="CheckFramebufferStatus"/> + <function name="GetFramebufferAttachmentParameteriv" template="GetFramebufferAttachmentParameter" gltype="GLint"/> + <function name="GetRenderbufferParameteriv" template="GetRenderbufferParameter" gltype="GLint"/> + <function name="IsRenderbuffer" template="IsRenderbuffer"/> + <function name="IsFramebuffer" template="IsFramebuffer"/> + + <function name="IsShader" template="IsShader"/> + <function name="GetShaderiv" template="GetShader" gltype="GLint"/> + <function name="GetAttachedShaders" template="GetAttachedShaders"/> + <function name="GetShaderInfoLog" template="GetShaderInfoLog"/> + <function name="GetProgramInfoLog" template="GetProgramInfoLog"/> + <function name="GetShaderSource" template="GetShaderSource"/> + <function name="GetShaderPrecisionFormat" template="GetShaderPrecisionFormat"/> + <function name="GetUniformfv" template="GetUniform" gltype="GLfloat"/> + <function name="GetUniformiv" template="GetUniform" gltype="GLint"/> + + <!-- EXT_multi_draw_arrays --> + <function name="MultiDrawArraysEXT" template="MultiDrawArrays"/> + <function name="MultiDrawElementsEXT" template="MultiDrawElements"/> +</api> + +</apispec> diff --git a/src/mesa/es/main/APIspecutil.py b/src/mesa/es/main/APIspecutil.py new file mode 100644 index 0000000000..27a8fe8a6d --- /dev/null +++ b/src/mesa/es/main/APIspecutil.py @@ -0,0 +1,265 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> +# +# 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 +# IBM 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. +""" +Minimal apiutil.py interface for use by es_generator.py. +""" + +import sys +import libxml2 + +import APIspec + +__spec = {} +__functions = {} +__aliases = {} + +def _ParseXML(filename, apiname): + conversions = { + # from to + 'GLfloat': [ 'GLdouble' ], + 'GLclampf': [ 'GLclampd' ], + 'GLubyte': [ 'GLfloat', 'GLdouble' ], + 'GLint': [ 'GLfloat', 'GLdouble' ], + 'GLfixed': [ 'GLfloat', 'GLdouble' ], + 'GLclampx': [ 'GLclampf', 'GLclampd' ], + } + + doc = libxml2.readFile(filename, None, + libxml2.XML_PARSE_DTDLOAD + + libxml2.XML_PARSE_DTDVALID + + libxml2.XML_PARSE_NOBLANKS) + spec = APIspec.Spec(doc) + impl = spec.get_impl() + api = spec.get_api(apiname) + doc.freeDoc() + + __spec["impl"] = impl + __spec["api"] = api + + for func in api.functions: + alias, need_conv = impl.match(func, conversions) + if not alias: + # external functions are manually dispatched + if not func.is_external: + print >>sys.stderr, "Error: unable to dispatch %s" % func.name + alias = func + need_conv = False + + __functions[func.name] = func + __aliases[func.name] = (alias, need_conv) + + +def AllSpecials(notused=None): + """Return a list of all external functions in the API.""" + api = __spec["api"] + + specials = [] + for func in api.functions: + if func.is_external: + specials.append(func.name) + + return specials + + +def GetAllFunctions(filename, api): + """Return sorted list of all functions in the API.""" + if not __spec: + _ParseXML(filename, api) + + api = __spec["api"] + names = [] + for func in api.functions: + names.append(func.name) + names.sort() + return names + + +def ReturnType(funcname): + """Return the C return type of named function.""" + func = __functions[funcname] + return func.return_type + + +def Properties(funcname): + """Return list of properties of the named GL function.""" + func = __functions[funcname] + return [func.direction] + + +def _ValidValues(func, param): + """Return the valid values of a parameter.""" + valid_values = [] + switch = func.checker.switches.get(param.name, []) + for desc in switch: + # no dependent vector + if not desc.checker.switches: + for val in desc.values: + valid_values.append((val, None, None, [], desc.error, None)) + continue + + items = desc.checker.switches.items() + if len(items) > 1: + print >>sys.stderr, "%s: more than one parameter depend on %s" % \ + (func.name, desc.name) + dep_name, dep_switch = items[0] + + for dep_desc in dep_switch: + if dep_desc.index >= 0 and dep_desc.index != 0: + print >>sys.stderr, "%s: not first element of a vector" % func.name + if dep_desc.checker.switches: + print >>sys.stderr, "%s: deep nested dependence" % func.name + + convert = None if dep_desc.convert else "noconvert" + for val in desc.values: + valid_values.append((val, dep_desc.size_str, dep_desc.name, + dep_desc.values, dep_desc.error, convert)) + return valid_values + + +def _Conversion(func, src_param): + """Return the destination type of the conversion, or None.""" + alias, need_conv = __aliases[func.name] + if need_conv: + dst_param = alias.get_param(src_param.name) + if src_param.type == dst_param.type: + need_conv = False + if not need_conv: + return (None, "none") + + converts = { True: 0, False: 0 } + + # In Fogx, for example, pname may be GL_FOG_DENSITY/GL_FOG_START/GL_FOG_END + # or GL_FOG_MODE. In the former three cases, param is not checked and the + # default is to convert. + if not func.checker.always_check(src_param.name): + converts[True] += 1 + + for desc in func.checker.flatten(src_param.name): + converts[desc.convert] += 1 + if converts[True] and converts[False]: + break + + # it should be "never", "sometimes", and "always"... + if converts[False]: + if converts[True]: + conversion = "some" + else: + conversion = "none" + else: + conversion = "all" + + return (dst_param.base_type(), conversion) + + +def _MaxVecSize(func, param): + """Return the largest possible size of a vector.""" + if not param.is_vector: + return 0 + if param.size: + return param.size + + # need to look at all descriptions + size = 0 + for desc in func.checker.flatten(param.name): + if desc.size_str and desc.size_str.isdigit(): + s = int(desc.size_str) + if s > size: + size = s + if not size: + need_conv = __aliases[func.name][1] + if need_conv: + print >>sys.stderr, \ + "Error: unable to dicide the max size of %s in %s" % \ + (param.name, func.name) + return size + + +def _ParameterTuple(func, param): + """Return a parameter tuple. + + [0] -- parameter name + [1] -- parameter type + [2] -- max vector size or 0 + [3] -- dest type the parameter converts to, or None + [4] -- valid values + [5] -- how often does the conversion happen + + """ + vec_size = _MaxVecSize(func, param) + dst_type, conversion = _Conversion(func, param) + valid_values = _ValidValues(func, param) + + return (param.name, param.type, vec_size, dst_type, valid_values, conversion) + + +def Parameters(funcname): + """Return list of tuples of function parameters.""" + func = __functions[funcname] + params = [] + for param in func.params: + params.append(_ParameterTuple(func, param)) + + return params + + +def FindParamIndex(params, paramname): + """Find the index of a named parameter.""" + for i in xrange(len(params)): + if params[i][0] == paramname: + return i + return None + + +def MakeDeclarationString(params): + """Return a C-style parameter declaration string.""" + string = [] + for p in params: + sep = "" if p[1].endswith("*") else " " + string.append("%s%s%s" % (p[1], sep, p[0])) + if not string: + return "void" + return ", ".join(string) + + +def AliasPrefix(funcname): + """Return the prefix of the function the named function is an alias of.""" + alias = __aliases[funcname][0] + return alias.prefix + + +def Alias(funcname): + """Return the name of the function the named function is an alias of.""" + alias, need_conv = __aliases[funcname] + return alias.name if not need_conv else None + + +def ConversionFunction(funcname): + """Return the name of the function the named function converts to.""" + alias, need_conv = __aliases[funcname] + return alias.name if need_conv else None + + +def Categories(funcname): + """Return all the categories of the named GL function.""" + api = __spec["api"] + return [api.name] diff --git a/src/mesa/es/main/drawtex.c b/src/mesa/es/main/drawtex.c new file mode 100644 index 0000000000..cbd41ca975 --- /dev/null +++ b/src/mesa/es/main/drawtex.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> + * + * 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. + */ + +#include "drawtex.h" +#include "main/state.h" +#include "main/imports.h" + +#include "glapi/dispatch.h" + + +#if FEATURE_OES_draw_texture + + +static void +draw_texture(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, + GLfloat width, GLfloat height) +{ + if (!ctx->Extensions.OES_draw_texture) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDrawTex(unsupported)"); + return; + } + if (width <= 0.0f || height <= 0.0f) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTex(width or height <= 0)"); + return; + } + + if (ctx->NewState) + _mesa_update_state(ctx); + + ASSERT(ctx->Driver.DrawTex); + ctx->Driver.DrawTex(ctx, x, y, z, width, height); +} + + +void GLAPIENTRY +_mesa_DrawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, x, y, z, width, height); +} + + +void GLAPIENTRY +_mesa_DrawTexfv(const GLfloat *coords) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, coords[0], coords[1], coords[2], coords[3], coords[4]); +} + + +void GLAPIENTRY +_mesa_DrawTexi(GLint x, GLint y, GLint z, GLint width, GLint height) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, (GLfloat) x, (GLfloat) y, (GLfloat) z, + (GLfloat) width, (GLfloat) height); +} + + +void GLAPIENTRY +_mesa_DrawTexiv(const GLint *coords) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, (GLfloat) coords[0], (GLfloat) coords[1], + (GLfloat) coords[2], (GLfloat) coords[3], (GLfloat) coords[4]); +} + + +void GLAPIENTRY +_mesa_DrawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, (GLfloat) x, (GLfloat) y, (GLfloat) z, + (GLfloat) width, (GLfloat) height); +} + + +void GLAPIENTRY +_mesa_DrawTexsv(const GLshort *coords) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, (GLfloat) coords[0], (GLfloat) coords[1], + (GLfloat) coords[2], (GLfloat) coords[3], (GLfloat) coords[4]); +} + + +void GLAPIENTRY +_mesa_DrawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, + (GLfloat) x / 65536.0f, + (GLfloat) y / 65536.0f, + (GLfloat) z / 65536.0f, + (GLfloat) width / 65536.0f, + (GLfloat) height / 65536.0f); +} + + +void GLAPIENTRY +_mesa_DrawTexxv(const GLfixed *coords) +{ + GET_CURRENT_CONTEXT(ctx); + draw_texture(ctx, + (GLfloat) coords[0] / 65536.0f, + (GLfloat) coords[1] / 65536.0f, + (GLfloat) coords[2] / 65536.0f, + (GLfloat) coords[3] / 65536.0f, + (GLfloat) coords[4] / 65536.0f); +} + + +void +_mesa_init_drawtex_dispatch(struct _glapi_table *disp) +{ + SET_DrawTexfOES(disp, _mesa_DrawTexf); + SET_DrawTexfvOES(disp, _mesa_DrawTexfv); + SET_DrawTexiOES(disp, _mesa_DrawTexi); + SET_DrawTexivOES(disp, _mesa_DrawTexiv); + SET_DrawTexsOES(disp, _mesa_DrawTexs); + SET_DrawTexsvOES(disp, _mesa_DrawTexsv); + SET_DrawTexxOES(disp, _mesa_DrawTexx); + SET_DrawTexxvOES(disp, _mesa_DrawTexxv); +} + + +#endif /* FEATURE_OES_draw_texture */ diff --git a/src/mesa/es/main/drawtex.h b/src/mesa/es/main/drawtex.h new file mode 100644 index 0000000000..0f3bac38c7 --- /dev/null +++ b/src/mesa/es/main/drawtex.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef DRAWTEX_H +#define DRAWTEX_H + + +#include "main/mtypes.h" + + +#if FEATURE_OES_draw_texture + +#define _MESA_INIT_DRAWTEX_FUNCTIONS(driver, impl) \ + do { \ + (driver)->DrawTex = impl ## DrawTex; \ + } while (0) + +extern void GLAPIENTRY +_mesa_DrawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height); + +extern void GLAPIENTRY +_mesa_DrawTexfv(const GLfloat *coords); + +extern void GLAPIENTRY +_mesa_DrawTexi(GLint x, GLint y, GLint z, GLint width, GLint height); + +extern void GLAPIENTRY +_mesa_DrawTexiv(const GLint *coords); + +extern void GLAPIENTRY +_mesa_DrawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height); + +extern void GLAPIENTRY +_mesa_DrawTexsv(const GLshort *coords); + +extern void GLAPIENTRY +_mesa_DrawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height); + +extern void GLAPIENTRY +_mesa_DrawTexxv(const GLfixed *coords); + +extern void +_mesa_init_drawtex_dispatch(struct _glapi_table *disp); + +#else /* FEATURE_OES_draw_texture */ + +#define _MESA_INIT_DRAWTEX_FUNCTIONS(driver, impl) do { } while (0) + +static INLINE void +_mesa_init_drawtex_dispatch(struct _glapi_table *disp) +{ +} + +#endif /* FEATURE_OES_draw_texture */ + + +#endif /* DRAWTEX_H */ diff --git a/src/mesa/es/main/es_cpaltex.c b/src/mesa/es/main/es_cpaltex.c new file mode 100644 index 0000000000..0c497774ff --- /dev/null +++ b/src/mesa/es/main/es_cpaltex.c @@ -0,0 +1,231 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + +/** + * Code to convert compressed/paletted texture images to ordinary images. + * See the GL_OES_compressed_paletted_texture spec at + * http://khronos.org/registry/gles/extensions/OES/OES_compressed_paletted_texture.txt + * + * XXX this makes it impossible to add hardware support... + */ + + +#include "GLES/gl.h" +#include "GLES/glext.h" + +#include "main/compiler.h" /* for ASSERT */ + + +void GL_APIENTRY _es_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + +void GL_APIENTRY _mesa_GetIntegerv(GLenum pname, GLint *params); +void GL_APIENTRY _mesa_PixelStorei(GLenum pname, GLint param); +void GL_APIENTRY _mesa_TexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +void GL_APIENTRY _mesa_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + +void *_mesa_get_current_context(void); +void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... ); + + +static const struct cpal_format_info { + GLenum cpal_format; + GLenum format; + GLenum type; + GLuint palette_size; + GLuint size; +} formats[] = { + { GL_PALETTE4_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE, 16, 3 }, + { GL_PALETTE4_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE, 16, 4 }, + { GL_PALETTE4_R5_G6_B5_OES, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 16, 2 }, + { GL_PALETTE4_RGBA4_OES, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 16, 2 }, + { GL_PALETTE4_RGB5_A1_OES, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 16, 2 }, + { GL_PALETTE8_RGB8_OES, GL_RGB, GL_UNSIGNED_BYTE, 256, 3 }, + { GL_PALETTE8_RGBA8_OES, GL_RGBA, GL_UNSIGNED_BYTE, 256, 4 }, + { GL_PALETTE8_R5_G6_B5_OES, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 256, 2 }, + { GL_PALETTE8_RGBA4_OES, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 256, 2 }, + { GL_PALETTE8_RGB5_A1_OES, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 256, 2 } +}; + + +/** + * Get a color/entry from the palette. + */ +static GLuint +get_palette_entry(const struct cpal_format_info *info, const GLubyte *palette, + GLuint index, GLubyte *pixel) +{ + memcpy(pixel, palette + info->size * index, info->size); + return info->size; +} + + +/** + * Convert paletted texture to color texture. + */ +static void +paletted_to_color(const struct cpal_format_info *info, const GLubyte *palette, + const void *indices, GLuint num_pixels, GLubyte *image) +{ + GLubyte *pix = image; + GLuint remain, i; + + if (info->palette_size == 16) { + /* 4 bits per index */ + const GLubyte *ind = (const GLubyte *) indices; + + /* two pixels per iteration */ + remain = num_pixels % 2; + for (i = 0; i < num_pixels / 2; i++) { + pix += get_palette_entry(info, palette, (ind[i] >> 4) & 0xf, pix); + pix += get_palette_entry(info, palette, ind[i] & 0xf, pix); + } + if (remain) { + get_palette_entry(info, palette, (ind[i] >> 4) & 0xf, pix); + } + } + else { + /* 8 bits per index */ + const GLubyte *ind = (const GLubyte *) indices; + for (i = 0; i < num_pixels; i++) + pix += get_palette_entry(info, palette, ind[i], pix); + } +} + + +static const struct cpal_format_info * +cpal_get_info(GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei imageSize) +{ + const struct cpal_format_info *info; + GLint lvl, num_levels; + GLsizei w, h, expect_size; + + info = &formats[internalFormat - GL_PALETTE4_RGB8_OES]; + ASSERT(info->cpal_format == internalFormat); + + if (level > 0) { + _mesa_error(_mesa_get_current_context(), GL_INVALID_VALUE, + "glCompressedTexImage2D(level=%d)", level); + return NULL; + } + + num_levels = -level + 1; + expect_size = info->palette_size * info->size; + for (lvl = 0; lvl < num_levels; lvl++) { + w = width >> lvl; + if (!w) + w = 1; + h = height >> lvl; + if (!h) + h = 1; + + if (info->palette_size == 16) + expect_size += (w * h + 1) / 2; + else + expect_size += w * h; + } + if (expect_size > imageSize) { + _mesa_error(_mesa_get_current_context(), GL_INVALID_VALUE, + "glCompressedTexImage2D(imageSize=%d)", imageSize); + return NULL; + } + return info; +} + +/** + * Convert a call to glCompressedTexImage2D() where internalFormat is a + * compressed palette format into a regular GLubyte/RGBA glTexImage2D() call. + */ +static void +cpal_compressed_teximage2d(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei imageSize, + const void *palette) +{ + const struct cpal_format_info *info; + GLint lvl, num_levels; + const GLubyte *indices; + GLint saved_align, align; + + info = cpal_get_info(level, internalFormat, width, height, imageSize); + if (!info) + return; + + info = &formats[internalFormat - GL_PALETTE4_RGB8_OES]; + ASSERT(info->cpal_format == internalFormat); + num_levels = -level + 1; + + /* first image follows the palette */ + indices = (const GLubyte *) palette + info->palette_size * info->size; + + _mesa_GetIntegerv(GL_UNPACK_ALIGNMENT, &saved_align); + align = saved_align; + + for (lvl = 0; lvl < num_levels; lvl++) { + GLsizei w, h; + GLuint num_texels; + GLubyte *image = NULL; + + w = width >> lvl; + if (!w) + w = 1; + h = height >> lvl; + if (!h) + h = 1; + num_texels = w * h; + if (w * info->size % align) { + _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, 1); + align = 1; + } + + /* allocate and fill dest image buffer */ + if (palette) { + image = (GLubyte *) malloc(num_texels * info->size); + paletted_to_color(info, palette, indices, num_texels, image); + } + + _mesa_TexImage2D(target, lvl, info->format, w, h, 0, + info->format, info->type, image); + if (image) + free(image); + + /* advance index pointer to point to next src mipmap */ + if (info->palette_size == 16) + indices += (num_texels + 1) / 2; + else + indices += num_texels; + } + + if (saved_align != align) + _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, saved_align); +} + + +void GL_APIENTRY +_es_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data) +{ + switch (internalFormat) { + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE4_RGBA4_OES: + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB8_OES: + case GL_PALETTE8_RGBA8_OES: + case GL_PALETTE8_R5_G6_B5_OES: + case GL_PALETTE8_RGBA4_OES: + case GL_PALETTE8_RGB5_A1_OES: + cpal_compressed_teximage2d(target, level, internalFormat, + width, height, imageSize, data); + break; + default: + _mesa_CompressedTexImage2DARB(target, level, internalFormat, + width, height, border, imageSize, data); + } +} diff --git a/src/mesa/es/main/es_enable.c b/src/mesa/es/main/es_enable.c new file mode 100644 index 0000000000..351caacd77 --- /dev/null +++ b/src/mesa/es/main/es_enable.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> + * + * 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. + */ + +#include "GLES/gl.h" +#include "GLES/glext.h" + +#include "main/compiler.h" /* for ASSERT */ + + +#ifndef GL_TEXTURE_GEN_S +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#endif + + +extern void GL_APIENTRY _es_Disable(GLenum cap); +extern void GL_APIENTRY _es_Enable(GLenum cap); +extern GLboolean GL_APIENTRY _es_IsEnabled(GLenum cap); + +extern void GL_APIENTRY _mesa_Disable(GLenum cap); +extern void GL_APIENTRY _mesa_Enable(GLenum cap); +extern GLboolean GL_APIENTRY _mesa_IsEnabled(GLenum cap); + + +void GL_APIENTRY +_es_Disable(GLenum cap) +{ + switch (cap) { + case GL_TEXTURE_GEN_STR_OES: + /* disable S, T, and R at the same time */ + _mesa_Disable(GL_TEXTURE_GEN_S); + _mesa_Disable(GL_TEXTURE_GEN_T); + _mesa_Disable(GL_TEXTURE_GEN_R); + break; + default: + _mesa_Disable(cap); + break; + } +} + + +void GL_APIENTRY +_es_Enable(GLenum cap) +{ + switch (cap) { + case GL_TEXTURE_GEN_STR_OES: + /* enable S, T, and R at the same time */ + _mesa_Enable(GL_TEXTURE_GEN_S); + _mesa_Enable(GL_TEXTURE_GEN_T); + _mesa_Enable(GL_TEXTURE_GEN_R); + break; + default: + _mesa_Enable(cap); + break; + } +} + + +GLboolean GL_APIENTRY +_es_IsEnabled(GLenum cap) +{ + switch (cap) { + case GL_TEXTURE_GEN_STR_OES: + cap = GL_TEXTURE_GEN_S; + default: + break; + } + + return _mesa_IsEnabled(cap); +} diff --git a/src/mesa/es/main/es_fbo.c b/src/mesa/es/main/es_fbo.c new file mode 100644 index 0000000000..1803637830 --- /dev/null +++ b/src/mesa/es/main/es_fbo.c @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + +#include "GLES2/gl2.h" +#include "GLES2/gl2ext.h" + + +#ifndef GL_RGB5 +#define GL_RGB5 0x8050 +#endif + + +extern void GL_APIENTRY _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); + +extern void GL_APIENTRY _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); + + +void GL_APIENTRY +_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height) +{ + switch (internalFormat) { + case GL_RGB565: + /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */ + /* choose a closest format */ + internalFormat = GL_RGB5; + break; + default: + break; + } + _mesa_RenderbufferStorageEXT(target, internalFormat, width, height); +} diff --git a/src/mesa/es/main/es_generator.py b/src/mesa/es/main/es_generator.py new file mode 100644 index 0000000000..590f5940a7 --- /dev/null +++ b/src/mesa/es/main/es_generator.py @@ -0,0 +1,685 @@ +#************************************************************************* +# Copyright 2008 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, 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 +# TUNGSTEN GRAPHICS 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. +#************************************************************************* + + +import sys, os +import APIspecutil as apiutil + +# These dictionary entries are used for automatic conversion. +# The string will be used as a format string with the conversion +# variable. +Converters = { + 'GLfloat': { + 'GLdouble': "(GLdouble) (%s)", + 'GLfixed' : "(GLint) (%s * 65536)", + }, + 'GLfixed': { + 'GLfloat': "(GLfloat) (%s / 65536.0f)", + 'GLdouble': "(GLdouble) (%s / 65536.0)", + }, + 'GLdouble': { + 'GLfloat': "(GLfloat) (%s)", + 'GLfixed': "(GLfixed) (%s * 65536)", + }, + 'GLclampf': { + 'GLclampd': "(GLclampd) (%s)", + 'GLclampx': "(GLclampx) (%s * 65536)", + }, + 'GLclampx': { + 'GLclampf': "(GLclampf) (%s / 65536.0f)", + 'GLclampd': "(GLclampd) (%s / 65536.0)", + }, + 'GLubyte': { + 'GLfloat': "(GLfloat) (%s / 255.0f)", + }, +} + +def GetBaseType(type): + typeTokens = type.split(' ') + baseType = None + typeModifiers = [] + for t in typeTokens: + if t in ['const', '*']: + typeModifiers.append(t) + else: + baseType = t + return (baseType, typeModifiers) + +def ConvertValue(value, fromType, toType): + """Returns a string that represents the given parameter string, + type-converted if necessary.""" + + if not Converters.has_key(fromType): + print >> sys.stderr, "No base converter for type '%s' found. Ignoring." % fromType + return value + + if not Converters[fromType].has_key(toType): + print >> sys.stderr, "No converter found for type '%s' to type '%s'. Ignoring." % (fromType, toType) + return value + + # This part is simple. Return the proper conversion. + conversionString = Converters[fromType][toType] + return conversionString % value + +FormatStrings = { + 'GLenum' : '0x%x', + 'GLfloat' : '%f', + 'GLint' : '%d', + 'GLbitfield' : '0x%x', +} +def GetFormatString(type): + if FormatStrings.has_key(type): + return FormatStrings[type] + else: + return None + + +###################################################################### +# Version-specific values to be used in the main script +# header: which header file to include +# api: what text specifies an API-level function +VersionSpecificValues = { + 'GLES1.1' : { + 'description' : 'GLES1.1 functions', + 'header' : 'GLES/gl.h', + 'extheader' : 'GLES/glext.h', + }, + 'GLES2.0': { + 'description' : 'GLES2.0 functions', + 'header' : 'GLES2/gl2.h', + 'extheader' : 'GLES2/gl2ext.h', + } +} + + +###################################################################### +# Main code for the script begins here. + +# Get the name of the program (without the directory part) for use in +# error messages. +program = os.path.basename(sys.argv[0]) + +# Set default values +verbose = 0 +functionList = "APIspec.xml" +version = "GLES1.1" + +# Allow for command-line switches +import getopt, time +options = "hvV:S:" +try: + optlist, args = getopt.getopt(sys.argv[1:], options) +except getopt.GetoptError, message: + sys.stderr.write("%s: %s. Use -h for help.\n" % (program, message)) + sys.exit(1) + +for option, optarg in optlist: + if option == "-h": + sys.stderr.write("Usage: %s [-%s]\n" % (program, options)) + sys.stderr.write("Parse an API specification file and generate wrapper functions for a given GLES version\n") + sys.stderr.write("-h gives help\n") + sys.stderr.write("-v is verbose\n") + sys.stderr.write("-V specifies GLES version to generate [%s]:\n" % version) + for key in VersionSpecificValues.keys(): + sys.stderr.write(" %s - %s\n" % (key, VersionSpecificValues[key]['description'])) + sys.stderr.write("-S specifies API specification file to use [%s]\n" % functionList) + sys.exit(1) + elif option == "-v": + verbose += 1 + elif option == "-V": + version = optarg + elif option == "-S": + functionList = optarg + +# Beyond switches, we support no further command-line arguments +if len(args) > 0: + sys.stderr.write("%s: only switch arguments are supported - use -h for help\n" % program) + sys.exit(1) + +# If we don't have a valid version, abort. +if not VersionSpecificValues.has_key(version): + sys.stderr.write("%s: version '%s' is not valid - use -h for help\n" % (program, version)) + sys.exit(1) + +# Grab the version-specific items we need to use +versionHeader = VersionSpecificValues[version]['header'] +versionExtHeader = VersionSpecificValues[version]['extheader'] + +# If we get to here, we're good to go. The "version" parameter +# directs GetDispatchedFunctions to only allow functions from +# that "category" (version in our parlance). This allows +# functions with different declarations in different categories +# to exist (glTexImage2D, for example, is different between +# GLES1 and GLES2). +keys = apiutil.GetAllFunctions(functionList, version) + +allSpecials = apiutil.AllSpecials() + +print """/* DO NOT EDIT ************************************************* + * THIS FILE AUTOMATICALLY GENERATED BY THE %s SCRIPT + * API specification file: %s + * GLES version: %s + * date: %s + */ +""" % (program, functionList, version, time.strftime("%Y-%m-%d %H:%M:%S")) + +# The headers we choose are version-specific. +print """ +#include "%s" +#include "%s" +""" % (versionHeader, versionExtHeader) + +# Everyone needs these types. +print """ +/* These types are needed for the Mesa veneer, but are not defined in + * the standard GLES headers. + */ +typedef double GLdouble; +typedef double GLclampd; + +/* This type is normally in glext.h, but needed here */ +typedef char GLchar; + +/* Mesa error handling requires these */ +extern void *_mesa_get_current_context(void); +extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... ); + +#include "main/compiler.h" +#include "main/api_exec.h" + +#include "glapi/dispatch.h" + +typedef void (*_glapi_proc)(void); /* generic function pointer */ +""" + +# Finally we get to the all-important functions +print """/************************************************************* + * Generated functions begin here + */ +""" +for funcName in keys: + if verbose > 0: sys.stderr.write("%s: processing function %s\n" % (program, funcName)) + + # start figuring out what this function will look like. + returnType = apiutil.ReturnType(funcName) + props = apiutil.Properties(funcName) + params = apiutil.Parameters(funcName) + declarationString = apiutil.MakeDeclarationString(params) + + # In case of error, a function may have to return. Make + # sure we have valid return values in this case. + if returnType == "void": + errorReturn = "return" + elif returnType == "GLboolean": + errorReturn = "return GL_FALSE" + else: + errorReturn = "return (%s) 0" % returnType + + # These are the output of this large calculation block. + # passthroughDeclarationString: a typed set of parameters that + # will be used to create the "extern" reference for the + # underlying Mesa or support function. Note that as generated + # these have an extra ", " at the beginning, which will be + # removed before use. + # + # passthroughDeclarationString: an untyped list of parameters + # that will be used to call the underlying Mesa or support + # function (including references to converted parameters). + # This will also be generated with an extra ", " at the + # beginning, which will be removed before use. + # + # variables: C code to create any local variables determined to + # be necessary. + # conversionCodeOutgoing: C code to convert application parameters + # to a necessary type before calling the underlying support code. + # May be empty if no conversion is required. + # conversionCodeIncoming: C code to do the converse: convert + # values returned by underlying Mesa code to the types needed + # by the application. + # Note that *either* the conversionCodeIncoming will be used (for + # generated query functions), *or* the conversionCodeOutgoing will + # be used (for generated non-query functions), never both. + passthroughFuncName = "" + passthroughDeclarationString = "" + passthroughCallString = "" + variables = [] + conversionCodeOutgoing = [] + conversionCodeIncoming = [] + switchCode = [] + + # Calculate the name of the underlying support function to call. + # By default, the passthrough function is named _mesa_<funcName>. + # We're allowed to override the prefix and/or the function name + # for each function record, though. The "ConversionFunction" + # utility is poorly named, BTW... + if funcName in allSpecials: + # perform checks and pass through + funcPrefix = "_check_" + aliasprefix = "_es_" + else: + funcPrefix = "_es_" + aliasprefix = apiutil.AliasPrefix(funcName) + alias = apiutil.ConversionFunction(funcName) + if not alias: + # There may still be a Mesa alias for the function + if apiutil.Alias(funcName): + passthroughFuncName = "%s%s" % (aliasprefix, apiutil.Alias(funcName)) + else: + passthroughFuncName = "%s%s" % (aliasprefix, funcName) + else: # a specific alias is provided + passthroughFuncName = "%s%s" % (aliasprefix, alias) + + # Look at every parameter: each one may have only specific + # allowed values, or dependent parameters to check, or + # variant-sized vector arrays to calculate + for (paramName, paramType, paramMaxVecSize, paramConvertToType, paramValidValues, paramValueConversion) in params: + # We'll need this below if we're doing conversions + (paramBaseType, paramTypeModifiers) = GetBaseType(paramType) + + # Conversion management. + # We'll handle three cases, easiest to hardest: a parameter + # that doesn't require conversion, a scalar parameter that + # requires conversion, and a vector parameter that requires + # conversion. + if paramConvertToType == None: + # Unconverted parameters are easy, whether they're vector + # or scalar - just add them to the call list. No conversions + # or anything to worry about. + passthroughDeclarationString += ", %s %s" % (paramType, paramName) + passthroughCallString += ", %s" % paramName + + elif paramMaxVecSize == 0: # a scalar parameter that needs conversion + # A scalar to hold a converted parameter + variables.append(" %s converted_%s;" % (paramConvertToType, paramName)) + + # Outgoing conversion depends on whether we have to conditionally + # perform value conversion. + if paramValueConversion == "none": + conversionCodeOutgoing.append(" converted_%s = (%s) %s;" % (paramName, paramConvertToType, paramName)) + elif paramValueConversion == "some": + # We'll need a conditional variable to keep track of + # whether we're converting values or not. + if (" int convert_%s_value = 1;" % paramName) not in variables: + variables.append(" int convert_%s_value = 1;" % paramName) + + # Write code based on that conditional. + conversionCodeOutgoing.append(" if (convert_%s_value) {" % paramName) + conversionCodeOutgoing.append(" converted_%s = %s;" % (paramName, ConvertValue(paramName, paramBaseType, paramConvertToType))) + conversionCodeOutgoing.append(" } else {") + conversionCodeOutgoing.append(" converted_%s = (%s) %s;" % (paramName, paramConvertToType, paramName)) + conversionCodeOutgoing.append(" }") + else: # paramValueConversion == "all" + conversionCodeOutgoing.append(" converted_%s = %s;" % (paramName, ConvertValue(paramName, paramBaseType, paramConvertToType))) + + # Note that there can be no incoming conversion for a + # scalar parameter; changing the scalar will only change + # the local value, and won't ultimately change anything + # that passes back to the application. + + # Call strings. The unusual " ".join() call will join the + # array of parameter modifiers with spaces as separators. + passthroughDeclarationString += ", %s %s %s" % (paramConvertToType, " ".join(paramTypeModifiers), paramName) + passthroughCallString += ", converted_%s" % paramName + + else: # a vector parameter that needs conversion + # We'll need an index variable for conversions + if " register unsigned int i;" not in variables: + variables.append(" register unsigned int i;") + + # This variable will hold the (possibly variant) size of + # this array needing conversion. By default, we'll set + # it to the maximal size (which is correct for functions + # with a constant-sized vector parameter); for true + # variant arrays, we'll modify it with other code. + variables.append(" unsigned int n_%s = %d;" % (paramName, paramMaxVecSize)) + + # This array will hold the actual converted values. + variables.append(" %s converted_%s[%d];" % (paramConvertToType, paramName, paramMaxVecSize)) + + # Again, we choose the conversion code based on whether we + # have to always convert values, never convert values, or + # conditionally convert values. + if paramValueConversion == "none": + conversionCodeOutgoing.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeOutgoing.append(" converted_%s[i] = (%s) %s[i];" % (paramName, paramConvertToType, paramName)) + conversionCodeOutgoing.append(" }") + elif paramValueConversion == "some": + # We'll need a conditional variable to keep track of + # whether we're converting values or not. + if (" int convert_%s_value = 1;" % paramName) not in variables: + variables.append(" int convert_%s_value = 1;" % paramName) + # Write code based on that conditional. + conversionCodeOutgoing.append(" if (convert_%s_value) {" % paramName) + conversionCodeOutgoing.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeOutgoing.append(" converted_%s[i] = %s;" % (paramName, ConvertValue("%s[i]" % paramName, paramBaseType, paramConvertToType))) + conversionCodeOutgoing.append(" }") + conversionCodeOutgoing.append(" } else {") + conversionCodeOutgoing.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeOutgoing.append(" converted_%s[i] = (%s) %s[i];" % (paramName, paramConvertToType, paramName)) + conversionCodeOutgoing.append(" }") + conversionCodeOutgoing.append(" }") + else: # paramValueConversion == "all" + conversionCodeOutgoing.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeOutgoing.append(" converted_%s[i] = %s;" % (paramName, ConvertValue("%s[i]" % paramName, paramBaseType, paramConvertToType))) + + conversionCodeOutgoing.append(" }") + + # If instead we need an incoming conversion (i.e. results + # from Mesa have to be converted before handing back + # to the application), this is it. Fortunately, we don't + # have to worry about conditional value conversion - the + # functions that do (e.g. glGetFixedv()) are handled + # specially, outside this code generation. + # + # Whether we use incoming conversion or outgoing conversion + # is determined later - we only ever use one or the other. + + if paramValueConversion == "none": + conversionCodeIncoming.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeIncoming.append(" %s[i] = (%s) converted_%s[i];" % (paramName, paramConvertToType, paramName)) + conversionCodeIncoming.append(" }") + elif paramValueConversion == "some": + # We'll need a conditional variable to keep track of + # whether we're converting values or not. + if (" int convert_%s_value = 1;" % paramName) not in variables: + variables.append(" int convert_%s_value = 1;" % paramName) + + # Write code based on that conditional. + conversionCodeIncoming.append(" if (convert_%s_value) {" % paramName) + conversionCodeIncoming.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeIncoming.append(" %s[i] = %s;" % (paramName, ConvertValue("converted_%s[i]" % paramName, paramConvertToType, paramBaseType))) + conversionCodeIncoming.append(" }") + conversionCodeIncoming.append(" } else {") + conversionCodeIncoming.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeIncoming.append(" %s[i] = (%s) converted_%s[i];" % (paramName, paramBaseType, paramName)) + conversionCodeIncoming.append(" }") + conversionCodeIncoming.append(" }") + else: # paramValueConversion == "all" + conversionCodeIncoming.append(" for (i = 0; i < n_%s; i++) {" % paramName) + conversionCodeIncoming.append(" %s[i] = %s;" % (paramName, ConvertValue("converted_%s[i]" % paramName, paramConvertToType, paramBaseType))) + conversionCodeIncoming.append(" }") + + # Call strings. The unusual " ".join() call will join the + # array of parameter modifiers with spaces as separators. + passthroughDeclarationString += ", %s %s %s" % (paramConvertToType, " ".join(paramTypeModifiers), paramName) + passthroughCallString += ", converted_%s" % paramName + + # endif conversion management + + # Parameter checking. If the parameter has a specific list of + # valid values, we have to make sure that the passed-in values + # match these, or we make an error. + if len(paramValidValues) > 0: + # We're about to make a big switch statement with an + # error at the end. By default, the error is GL_INVALID_ENUM, + # unless we find a "case" statement in the middle with a + # non-GLenum value. + errorDefaultCase = "GL_INVALID_ENUM" + + # This parameter has specific valid values. Make a big + # switch statement to handle it. Note that the original + # parameters are always what is checked, not the + # converted parameters. + switchCode.append(" switch(%s) {" % paramName) + + for valueIndex in range(len(paramValidValues)): + (paramValue, dependentVecSize, dependentParamName, dependentValidValues, errorCode, valueConvert) = paramValidValues[valueIndex] + + # We're going to need information on the dependent param + # as well. + if dependentParamName: + depParamIndex = apiutil.FindParamIndex(params, dependentParamName) + if depParamIndex == None: + sys.stderr.write("%s: can't find dependent param '%s' for function '%s'\n" % (program, dependentParamName, funcName)) + + (depParamName, depParamType, depParamMaxVecSize, depParamConvertToType, depParamValidValues, depParamValueConversion) = params[depParamIndex] + else: + (depParamName, depParamType, depParamMaxVecSize, depParamConvertToType, depParamValidValues, depParamValueConversion) = (None, None, None, None, [], None) + + # This is a sneaky trick. It's valid syntax for a parameter + # that is *not* going to be converted to be declared + # with a dependent vector size; but in this case, the + # dependent vector size is unused and unnecessary. + # So check for this and ignore the dependent vector size + # if the parameter is not going to be converted. + if depParamConvertToType: + usedDependentVecSize = dependentVecSize + else: + usedDependentVecSize = None + + # We'll peek ahead at the next parameter, to see whether + # we can combine cases + if valueIndex + 1 < len(paramValidValues) : + (nextParamValue, nextDependentVecSize, nextDependentParamName, nextDependentValidValues, nextErrorCode, nextValueConvert) = paramValidValues[valueIndex + 1] + if depParamConvertToType: + usedNextDependentVecSize = nextDependentVecSize + else: + usedNextDependentVecSize = None + + # Create a case for this value. As a mnemonic, + # if we have a dependent vector size that we're ignoring, + # add it as a comment. + if usedDependentVecSize == None and dependentVecSize != None: + switchCode.append(" case %s: /* size %s */" % (paramValue, dependentVecSize)) + else: + switchCode.append(" case %s:" % paramValue) + + # If this is not a GLenum case, then switch our error + # if no value is matched to be GL_INVALID_VALUE instead + # of GL_INVALID_ENUM. (Yes, this does get confused + # if there are both values and GLenums in the same + # switch statement, which shouldn't happen.) + if paramValue[0:3] != "GL_": + errorDefaultCase = "GL_INVALID_VALUE" + + # If all the remaining parameters are identical to the + # next set, then we're done - we'll just create the + # official code on the next pass through, and the two + # cases will share the code. + if valueIndex + 1 < len(paramValidValues) and usedDependentVecSize == usedNextDependentVecSize and dependentParamName == nextDependentParamName and dependentValidValues == nextDependentValidValues and errorCode == nextErrorCode and valueConvert == nextValueConvert: + continue + + # Otherwise, we'll have to generate code for this case. + # Start off with a check: if there is a dependent parameter, + # and a list of valid values for that parameter, we need + # to generate an error if something other than one + # of those values is passed. + if len(dependentValidValues) > 0: + conditional="" + + # If the parameter being checked is actually an array, + # check only its first element. + if depParamMaxVecSize == 0: + valueToCheck = dependentParamName + else: + valueToCheck = "%s[0]" % dependentParamName + + for v in dependentValidValues: + conditional += " && %s != %s" % (valueToCheck, v) + switchCode.append(" if (%s) {" % conditional[4:]) + if errorCode == None: + errorCode = "GL_INVALID_ENUM" + switchCode.append(' _mesa_error(_mesa_get_current_context(), %s, "gl%s(%s=0x%s)", %s);' % (errorCode, funcName, paramName, "%x", paramName)) + switchCode.append(" %s;" % errorReturn) + switchCode.append(" }") + # endif there are dependent valid values + + # The dependent parameter may require conditional + # value conversion. If it does, and we don't want + # to convert values, we'll have to generate code for that + if depParamValueConversion == "some" and valueConvert == "noconvert": + switchCode.append(" convert_%s_value = 0;" % dependentParamName) + + # If there's a dependent vector size for this parameter + # that we're actually going to use (i.e. we need conversion), + # mark it. + if usedDependentVecSize: + switchCode.append(" n_%s = %s;" % (dependentParamName, dependentVecSize)) + + # In all cases, break out of the switch if any valid + # value is found. + switchCode.append(" break;") + + + # Need a default case to catch all the other, invalid + # parameter values. These will all generate errors. + switchCode.append(" default:") + if errorCode == None: + errorCode = "GL_INVALID_ENUM" + formatString = GetFormatString(paramType) + if formatString == None: + switchCode.append(' _mesa_error(_mesa_get_current_context(), %s, "gl%s(%s)");' % (errorCode, funcName, paramName)) + else: + switchCode.append(' _mesa_error(_mesa_get_current_context(), %s, "gl%s(%s=%s)", %s);' % (errorCode, funcName, paramName, formatString, paramName)) + switchCode.append(" %s;" % errorReturn) + + # End of our switch code. + switchCode.append(" }") + + # endfor every recognized parameter value + + # endfor every param + + # Here, the passthroughDeclarationString and passthroughCallString + # are complete; remove the extra ", " at the front of each. + passthroughDeclarationString = passthroughDeclarationString[2:] + passthroughCallString = passthroughCallString[2:] + + # The Mesa functions are scattered across all the Mesa + # header files. The easiest way to manage declarations + # is to create them ourselves. + if funcName in allSpecials: + print "/* this function is special and is defined elsewhere */" + print "extern %s GLAPIENTRY %s(%s);" % (returnType, passthroughFuncName, passthroughDeclarationString) + + # A function may be a core function (i.e. it exists in + # the core specification), a core addition (extension + # functions added officially to the core), a required + # extension (usually an extension for an earlier version + # that has been officially adopted), or an optional extension. + # + # Core functions have a simple category (e.g. "GLES1.1"); + # we generate only a simple callback for them. + # + # Core additions have two category listings, one simple + # and one compound (e.g. ["GLES1.1", "GLES1.1:OES_fixed_point"]). + # We generate the core function, and also an extension function. + # + # Required extensions and implemented optional extensions + # have a single compound category "GLES1.1:OES_point_size_array". + # For these we generate just the extension function. + for categorySpec in apiutil.Categories(funcName): + compoundCategory = categorySpec.split(":") + + # This category isn't for us, if the base category doesn't match + # our version + if compoundCategory[0] != version: + continue + + # Otherwise, determine if we're writing code for a core + # function (no suffix) or an extension function. + if len(compoundCategory) == 1: + # This is a core function + extensionName = None + extensionSuffix = "" + else: + # This is an extension function. We'll need to append + # the extension suffix. + extensionName = compoundCategory[1] + extensionSuffix = extensionName.split("_")[0] + fullFuncName = funcPrefix + funcName + extensionSuffix + + # Now the generated function. The text used to mark an API-level + # function, oddly, is version-specific. + if extensionName: + print "/* Extension %s */" % extensionName + + if (not variables and + not switchCode and + not conversionCodeOutgoing and + not conversionCodeIncoming): + # pass through directly + print "#define %s %s" % (fullFuncName, passthroughFuncName) + print + continue + + print "static %s %s(%s)" % (returnType, fullFuncName, declarationString) + print "{" + + # Start printing our code pieces. Start with any local + # variables we need. This unusual syntax joins the + # lines in the variables[] array with the "\n" separator. + if len(variables) > 0: + print "\n".join(variables) + "\n" + + # If there's any sort of parameter checking or variable + # array sizing, the switch code will contain it. + if len(switchCode) > 0: + print "\n".join(switchCode) + "\n" + + # In the case of an outgoing conversion (i.e. parameters must + # be converted before calling the underlying Mesa function), + # use the appropriate code. + if "get" not in props and len(conversionCodeOutgoing) > 0: + print "\n".join(conversionCodeOutgoing) + "\n" + + # Call the Mesa function. Note that there are very few functions + # that return a value (i.e. returnType is not "void"), and that + # none of them require incoming translation; so we're safe + # to generate code that directly returns in those cases, + # even though it's not completely independent. + + if returnType == "void": + print " %s(%s);" % (passthroughFuncName, passthroughCallString) + else: + print " return %s(%s);" % (passthroughFuncName, passthroughCallString) + + # If the function is one that returns values (i.e. "get" in props), + # it might return values of a different type than we need, that + # require conversion before passing back to the application. + if "get" in props and len(conversionCodeIncoming) > 0: + print "\n".join(conversionCodeIncoming) + + # All done. + print "}" + print + # end for each category provided for a function + +# end for each function + +print "void" +print "_mesa_init_exec_table(struct _glapi_table *exec)" +print "{" +for func in keys: + prefix = "_es_" if func not in allSpecials else "_check_" + for spec in apiutil.Categories(func): + ext = spec.split(":") + # version does not match + if ext.pop(0) != version: + continue + entry = func + if ext: + suffix = ext[0].split("_")[0] + entry += suffix + print " SET_%s(exec, %s%s);" % (entry, prefix, entry) +print "}" diff --git a/src/mesa/es/main/es_query_matrix.c b/src/mesa/es/main/es_query_matrix.c new file mode 100644 index 0000000000..82b6fe7ab9 --- /dev/null +++ b/src/mesa/es/main/es_query_matrix.c @@ -0,0 +1,199 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + +/** + * Code to implement GL_OES_query_matrix. See the spec at: + * http://www.khronos.org/registry/gles/extensions/OES/OES_query_matrix.txt + */ + + +#include <stdlib.h> +#include <math.h> +#include "GLES/gl.h" +#include "GLES/glext.h" + + +/** + * This is from the GL_OES_query_matrix extension specification: + * + * GLbitfield glQueryMatrixxOES( GLfixed mantissa[16], + * GLint exponent[16] ) + * mantissa[16] contains the contents of the current matrix in GLfixed + * format. exponent[16] contains the unbiased exponents applied to the + * matrix components, so that the internal representation of component i + * is close to mantissa[i] * 2^exponent[i]. The function returns a status + * word which is zero if all the components are valid. If + * status & (1<<i) != 0, the component i is invalid (e.g., NaN, Inf). + * The implementations are not required to keep track of overflows. In + * that case, the invalid bits are never set. + */ + +#define INT_TO_FIXED(x) ((GLfixed) ((x) << 16)) +#define FLOAT_TO_FIXED(x) ((GLfixed) ((x) * 65536.0)) + +#if defined(WIN32) || defined(_WIN32_WCE) +/* Oddly, the fpclassify() function doesn't exist in such a form + * on Windows. This is an implementation using slightly different + * lower-level Windows functions. + */ +#include <float.h> + +enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL} +fpclassify(double x) +{ + switch(_fpclass(x)) { + case _FPCLASS_SNAN: /* signaling NaN */ + case _FPCLASS_QNAN: /* quiet NaN */ + return FP_NAN; + case _FPCLASS_NINF: /* negative infinity */ + case _FPCLASS_PINF: /* positive infinity */ + return FP_INFINITE; + case _FPCLASS_NN: /* negative normal */ + case _FPCLASS_PN: /* positive normal */ + return FP_NORMAL; + case _FPCLASS_ND: /* negative denormalized */ + case _FPCLASS_PD: /* positive denormalized */ + return FP_SUBNORMAL; + case _FPCLASS_NZ: /* negative zero */ + case _FPCLASS_PZ: /* positive zero */ + return FP_ZERO; + default: + /* Should never get here; but if we do, this will guarantee + * that the pattern is not treated like a number. + */ + return FP_NAN; + } +} +#endif + +extern GLbitfield GL_APIENTRY _es_QueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]); + +/* The Mesa functions we'll need */ +extern void GL_APIENTRY _mesa_GetIntegerv(GLenum pname, GLint *params); +extern void GL_APIENTRY _mesa_GetFloatv(GLenum pname, GLfloat *params); + +GLbitfield GL_APIENTRY _es_QueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]) +{ + GLfloat matrix[16]; + GLint tmp; + GLenum currentMode = GL_FALSE; + GLenum desiredMatrix = GL_FALSE; + /* The bitfield returns 1 for each component that is invalid (i.e. + * NaN or Inf). In case of error, everything is invalid. + */ + GLbitfield rv; + register unsigned int i; + unsigned int bit; + + /* This data structure defines the mapping between the current matrix + * mode and the desired matrix identifier. + */ + static struct { + GLenum currentMode; + GLenum desiredMatrix; + } modes[] = { + {GL_MODELVIEW, GL_MODELVIEW_MATRIX}, + {GL_PROJECTION, GL_PROJECTION_MATRIX}, + {GL_TEXTURE, GL_TEXTURE_MATRIX}, +#if 0 + /* this doesn't exist in GLES */ + {GL_COLOR, GL_COLOR_MATRIX}, +#endif + }; + + /* Call Mesa to get the current matrix in floating-point form. First, + * we have to figure out what the current matrix mode is. + */ + _mesa_GetIntegerv(GL_MATRIX_MODE, &tmp); + currentMode = (GLenum) tmp; + + /* The mode is either GL_FALSE, if for some reason we failed to query + * the mode, or a given mode from the above table. Search for the + * returned mode to get the desired matrix; if we don't find it, + * we can return immediately, as _mesa_GetInteger() will have + * logged the necessary error already. + */ + for (i = 0; i < sizeof(modes)/sizeof(modes[0]); i++) { + if (modes[i].currentMode == currentMode) { + desiredMatrix = modes[i].desiredMatrix; + break; + } + } + if (desiredMatrix == GL_FALSE) { + /* Early error means all values are invalid. */ + return 0xffff; + } + + /* Now pull the matrix itself. */ + _mesa_GetFloatv(desiredMatrix, matrix); + + rv = 0; + for (i = 0, bit = 1; i < 16; i++, bit<<=1) { + float normalizedFraction; + int exp; + + switch (fpclassify(matrix[i])) { + /* A "subnormal" or denormalized number is too small to be + * represented in normal format; but despite that it's a + * valid floating point number. FP_ZERO and FP_NORMAL + * are both valid as well. We should be fine treating + * these three cases as legitimate floating-point numbers. + */ + case FP_SUBNORMAL: + case FP_NORMAL: + case FP_ZERO: + normalizedFraction = (GLfloat)frexp(matrix[i], &exp); + mantissa[i] = FLOAT_TO_FIXED(normalizedFraction); + exponent[i] = (GLint) exp; + break; + + /* If the entry is not-a-number or an infinity, then the + * matrix component is invalid. The invalid flag for + * the component is already set; might as well set the + * other return values to known values. We'll set + * distinct values so that a savvy end user could determine + * whether the matrix component was a NaN or an infinity, + * but this is more useful for debugging than anything else + * since the standard doesn't specify any such magic + * values to return. + */ + case FP_NAN: + mantissa[i] = INT_TO_FIXED(0); + exponent[i] = (GLint) 0; + rv |= bit; + break; + + case FP_INFINITE: + /* Return +/- 1 based on whether it's a positive or + * negative infinity. + */ + if (matrix[i] > 0) { + mantissa[i] = INT_TO_FIXED(1); + } + else { + mantissa[i] = -INT_TO_FIXED(1); + } + exponent[i] = (GLint) 0; + rv |= bit; + break; + + /* We should never get here; but here's a catching case + * in case fpclassify() is returnings something unexpected. + */ + default: + mantissa[i] = INT_TO_FIXED(2); + exponent[i] = (GLint) 0; + rv |= bit; + break; + } + + } /* for each component */ + + /* All done */ + return rv; +} diff --git a/src/mesa/es/main/es_texgen.c b/src/mesa/es/main/es_texgen.c new file mode 100644 index 0000000000..c29a0a7f13 --- /dev/null +++ b/src/mesa/es/main/es_texgen.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> + * + * 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. + */ + +#include "GLES/gl.h" +#include "GLES/glext.h" + +#include "main/compiler.h" /* for ASSERT */ + + +#ifndef GL_S +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#endif + + +extern void GL_APIENTRY _es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); +extern void GL_APIENTRY _es_TexGenf(GLenum coord, GLenum pname, GLfloat param); +extern void GL_APIENTRY _es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params); + +extern void GL_APIENTRY _mesa_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); +extern void GL_APIENTRY _mesa_TexGenf(GLenum coord, GLenum pname, GLfloat param); +extern void GL_APIENTRY _mesa_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params); + + +void GL_APIENTRY +_es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) +{ + ASSERT(coord == GL_TEXTURE_GEN_STR_OES); + _mesa_GetTexGenfv(GL_S, pname, params); +} + + +void GL_APIENTRY +_es_TexGenf(GLenum coord, GLenum pname, GLfloat param) +{ + ASSERT(coord == GL_TEXTURE_GEN_STR_OES); + /* set S, T, and R at the same time */ + _mesa_TexGenf(GL_S, pname, param); + _mesa_TexGenf(GL_T, pname, param); + _mesa_TexGenf(GL_R, pname, param); +} + + +void GL_APIENTRY +_es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) +{ + ASSERT(coord == GL_TEXTURE_GEN_STR_OES); + /* set S, T, and R at the same time */ + _mesa_TexGenfv(GL_S, pname, params); + _mesa_TexGenfv(GL_T, pname, params); + _mesa_TexGenfv(GL_R, pname, params); +} diff --git a/src/mesa/es/main/get_gen.py b/src/mesa/es/main/get_gen.py new file mode 100644 index 0000000000..b820157be0 --- /dev/null +++ b/src/mesa/es/main/get_gen.py @@ -0,0 +1,810 @@ +#!/usr/bin/env python + +# Mesa 3-D graphics library +# +# Copyright (C) 1999-2006 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 +# BRIAN PAUL 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. + + +# This script is used to generate the get.c file: +# python get_gen.py > get.c + + +import string +import sys + + +GLint = 1 +GLenum = 2 +GLfloat = 3 +GLdouble = 4 +GLboolean = 5 +GLfloatN = 6 # A normalized value, such as a color or depth range +GLfixed = 7 + + +TypeStrings = { + GLint : "GLint", + GLenum : "GLenum", + GLfloat : "GLfloat", + GLdouble : "GLdouble", + GLboolean : "GLboolean", + GLfixed : "GLfixed" +} + + +# Each entry is a tuple of: +# - the GL state name, such as GL_CURRENT_COLOR +# - the state datatype, one of GLint, GLfloat, GLboolean or GLenum +# - list of code fragments to get the state, such as ["ctx->Foo.Bar"] +# - optional extra code or empty string +# - optional extensions to check, or None +# + +# Present in ES 1.x and 2.x: +StateVars_common = [ + ( "GL_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.alphaBits"], + "", None ), + ( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ), + ( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), + ( "GL_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.blueBits"], "", None ), + ( "GL_COLOR_CLEAR_VALUE", GLfloatN, + [ "ctx->Color.ClearColor[0]", + "ctx->Color.ClearColor[1]", + "ctx->Color.ClearColor[2]", + "ctx->Color.ClearColor[3]" ], "", None ), + ( "GL_COLOR_WRITEMASK", GLint, + [ "ctx->Color.ColorMask[RCOMP] ? 1 : 0", + "ctx->Color.ColorMask[GCOMP] ? 1 : 0", + "ctx->Color.ColorMask[BCOMP] ? 1 : 0", + "ctx->Color.ColorMask[ACOMP] ? 1 : 0" ], "", None ), + ( "GL_CULL_FACE", GLboolean, ["ctx->Polygon.CullFlag"], "", None ), + ( "GL_CULL_FACE_MODE", GLenum, ["ctx->Polygon.CullFaceMode"], "", None ), + ( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"], + "", None ), + ( "GL_DEPTH_CLEAR_VALUE", GLfloatN, ["ctx->Depth.Clear"], "", None ), + ( "GL_DEPTH_FUNC", GLenum, ["ctx->Depth.Func"], "", None ), + ( "GL_DEPTH_RANGE", GLfloatN, + [ "ctx->Viewport.Near", "ctx->Viewport.Far" ], "", None ), + ( "GL_DEPTH_TEST", GLboolean, ["ctx->Depth.Test"], "", None ), + ( "GL_DEPTH_WRITEMASK", GLboolean, ["ctx->Depth.Mask"], "", None ), + ( "GL_DITHER", GLboolean, ["ctx->Color.DitherFlag"], "", None ), + ( "GL_FRONT_FACE", GLenum, ["ctx->Polygon.FrontFace"], "", None ), + ( "GL_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.greenBits"], + "", None ), + ( "GL_LINE_WIDTH", GLfloat, ["ctx->Line.Width"], "", None ), + ( "GL_ALIASED_LINE_WIDTH_RANGE", GLfloat, + ["ctx->Const.MinLineWidth", + "ctx->Const.MaxLineWidth"], "", None ), + ( "GL_MAX_ELEMENTS_INDICES", GLint, ["ctx->Const.MaxArrayLockSize"], "", None ), + ( "GL_MAX_ELEMENTS_VERTICES", GLint, ["ctx->Const.MaxArrayLockSize"], "", None ), + + ( "GL_MAX_TEXTURE_SIZE", GLint, ["1 << (ctx->Const.MaxTextureLevels - 1)"], "", None ), + ( "GL_MAX_VIEWPORT_DIMS", GLint, + ["ctx->Const.MaxViewportWidth", "ctx->Const.MaxViewportHeight"], + "", None ), + ( "GL_PACK_ALIGNMENT", GLint, ["ctx->Pack.Alignment"], "", None ), + ( "GL_ALIASED_POINT_SIZE_RANGE", GLfloat, + ["ctx->Const.MinPointSize", + "ctx->Const.MaxPointSize"], "", None ), + ( "GL_POLYGON_OFFSET_FACTOR", GLfloat, ["ctx->Polygon.OffsetFactor "], "", None ), + ( "GL_POLYGON_OFFSET_UNITS", GLfloat, ["ctx->Polygon.OffsetUnits "], "", None ), + ( "GL_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.redBits"], "", None ), + ( "GL_SCISSOR_BOX", GLint, + ["ctx->Scissor.X", + "ctx->Scissor.Y", + "ctx->Scissor.Width", + "ctx->Scissor.Height"], "", None ), + ( "GL_SCISSOR_TEST", GLboolean, ["ctx->Scissor.Enabled"], "", None ), + ( "GL_STENCIL_BITS", GLint, ["ctx->DrawBuffer->Visual.stencilBits"], "", None ), + ( "GL_STENCIL_CLEAR_VALUE", GLint, ["ctx->Stencil.Clear"], "", None ), + ( "GL_STENCIL_FAIL", GLenum, + ["ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_FUNC", GLenum, + ["ctx->Stencil.Function[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_PASS_DEPTH_FAIL", GLenum, + ["ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_PASS_DEPTH_PASS", GLenum, + ["ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_REF", GLint, + ["ctx->Stencil.Ref[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_TEST", GLboolean, ["ctx->Stencil.Enabled"], "", None ), + ( "GL_STENCIL_VALUE_MASK", GLint, + ["ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_STENCIL_WRITEMASK", GLint, + ["ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]"], "", None ), + ( "GL_SUBPIXEL_BITS", GLint, ["ctx->Const.SubPixelBits"], "", None ), + ( "GL_TEXTURE_BINDING_2D", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_2D_INDEX]->Name"], "", None ), + ( "GL_UNPACK_ALIGNMENT", GLint, ["ctx->Unpack.Alignment"], "", None ), + ( "GL_VIEWPORT", GLint, [ "ctx->Viewport.X", "ctx->Viewport.Y", + "ctx->Viewport.Width", "ctx->Viewport.Height" ], "", None ), + + # GL_ARB_multitexture + ( "GL_ACTIVE_TEXTURE_ARB", GLint, + [ "GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit"], "", ["ARB_multitexture"] ), + + # Note that all the OES_* extensions require that the Mesa + # "struct gl_extensions" include a member with the name of + # the extension. That structure does not yet include OES + # extensions (and we're not sure whether it will). If + # it does, all the OES_* extensions below should mark the + # dependency. + + # OES_texture_cube_map + ( "GL_TEXTURE_BINDING_CUBE_MAP_ARB", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_CUBE_INDEX]->Name"], + "", None), + ( "GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB", GLint, + ["(1 << (ctx->Const.MaxCubeTextureLevels - 1))"], + "", None), + + # OES_blend_subtract + ( "GL_BLEND_SRC_RGB_EXT", GLenum, ["ctx->Color.BlendSrcRGB"], "", None), + ( "GL_BLEND_DST_RGB_EXT", GLenum, ["ctx->Color.BlendDstRGB"], "", None), + ( "GL_BLEND_SRC_ALPHA_EXT", GLenum, ["ctx->Color.BlendSrcA"], "", None), + ( "GL_BLEND_DST_ALPHA_EXT", GLenum, ["ctx->Color.BlendDstA"], "", None), + + # GL_BLEND_EQUATION_RGB, which is what we're really after, + # is defined identically to GL_BLEND_EQUATION. + ( "GL_BLEND_EQUATION", GLenum, ["ctx->Color.BlendEquationRGB "], "", None), + ( "GL_BLEND_EQUATION_ALPHA_EXT", GLenum, ["ctx->Color.BlendEquationA "], + "", None), + + # GL_ARB_texture_compression */ +# ( "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB", GLint, +# ["_mesa_get_compressed_formats(ctx, NULL, GL_FALSE)"], +# "", ["ARB_texture_compression"] ), +# ( "GL_COMPRESSED_TEXTURE_FORMATS_ARB", GLenum, +# [], +# """GLint formats[100]; +# GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE); +# ASSERT(n <= 100); +# for (i = 0; i < n; i++) +# params[i] = ENUM_TO_INT(formats[i]);""", +# ["ARB_texture_compression"] ), + + # GL_ARB_multisample + ( "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB", GLboolean, + ["ctx->Multisample.SampleAlphaToCoverage"], "", ["ARB_multisample"] ), + ( "GL_SAMPLE_COVERAGE_ARB", GLboolean, + ["ctx->Multisample.SampleCoverage"], "", ["ARB_multisample"] ), + ( "GL_SAMPLE_COVERAGE_VALUE_ARB", GLfloat, + ["ctx->Multisample.SampleCoverageValue"], "", ["ARB_multisample"] ), + ( "GL_SAMPLE_COVERAGE_INVERT_ARB", GLboolean, + ["ctx->Multisample.SampleCoverageInvert"], "", ["ARB_multisample"] ), + ( "GL_SAMPLE_BUFFERS_ARB", GLint, + ["ctx->DrawBuffer->Visual.sampleBuffers"], "", ["ARB_multisample"] ), + ( "GL_SAMPLES_ARB", GLint, + ["ctx->DrawBuffer->Visual.samples"], "", ["ARB_multisample"] ), + + + # GL_SGIS_generate_mipmap + ( "GL_GENERATE_MIPMAP_HINT_SGIS", GLenum, ["ctx->Hint.GenerateMipmap"], + "", ["SGIS_generate_mipmap"] ), + + # GL_ARB_vertex_buffer_object + ( "GL_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayBufferObj->Name"], "", ["ARB_vertex_buffer_object"] ), + # GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB - not supported + ( "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ElementArrayBufferObj->Name"], + "", ["ARB_vertex_buffer_object"] ), + + # GL_OES_read_format + ( "GL_IMPLEMENTATION_COLOR_READ_TYPE_OES", GLint, + ["_mesa_get_color_read_type(ctx)"], "", ["OES_read_format"] ), + ( "GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES", GLint, + ["_mesa_get_color_read_format(ctx)"], "", ["OES_read_format"] ), + + # GL_OES_framebuffer_object + ( "GL_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->DrawBuffer->Name"], "", + None), + ( "GL_RENDERBUFFER_BINDING_EXT", GLint, + ["ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0"], "", + None), + ( "GL_MAX_RENDERBUFFER_SIZE_EXT", GLint, + ["ctx->Const.MaxRenderbufferSize"], "", + None), + + # OpenGL ES 1/2 special: + ( "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB", GLint, + [ "ARRAY_SIZE(compressed_formats)" ], + "", + None ), + + ("GL_COMPRESSED_TEXTURE_FORMATS_ARB", GLint, + [], + """ + int i; + for (i = 0; i < ARRAY_SIZE(compressed_formats); i++) { + params[i] = compressed_formats[i]; + }""", + None ), + + ( "GL_POLYGON_OFFSET_FILL", GLboolean, ["ctx->Polygon.OffsetFill"], "", None ), + +] + +# Only present in ES 1.x: +StateVars_es1 = [ + ( "GL_MAX_LIGHTS", GLint, ["ctx->Const.MaxLights"], "", None ), + ( "GL_LIGHT0", GLboolean, ["ctx->Light.Light[0].Enabled"], "", None ), + ( "GL_LIGHT1", GLboolean, ["ctx->Light.Light[1].Enabled"], "", None ), + ( "GL_LIGHT2", GLboolean, ["ctx->Light.Light[2].Enabled"], "", None ), + ( "GL_LIGHT3", GLboolean, ["ctx->Light.Light[3].Enabled"], "", None ), + ( "GL_LIGHT4", GLboolean, ["ctx->Light.Light[4].Enabled"], "", None ), + ( "GL_LIGHT5", GLboolean, ["ctx->Light.Light[5].Enabled"], "", None ), + ( "GL_LIGHT6", GLboolean, ["ctx->Light.Light[6].Enabled"], "", None ), + ( "GL_LIGHT7", GLboolean, ["ctx->Light.Light[7].Enabled"], "", None ), + ( "GL_LIGHTING", GLboolean, ["ctx->Light.Enabled"], "", None ), + ( "GL_LIGHT_MODEL_AMBIENT", GLfloatN, + ["ctx->Light.Model.Ambient[0]", + "ctx->Light.Model.Ambient[1]", + "ctx->Light.Model.Ambient[2]", + "ctx->Light.Model.Ambient[3]"], "", None ), + ( "GL_LIGHT_MODEL_TWO_SIDE", GLboolean, ["ctx->Light.Model.TwoSide"], "", None ), + ( "GL_ALPHA_TEST", GLboolean, ["ctx->Color.AlphaEnabled"], "", None ), + ( "GL_ALPHA_TEST_FUNC", GLenum, ["ctx->Color.AlphaFunc"], "", None ), + ( "GL_ALPHA_TEST_REF", GLfloatN, ["ctx->Color.AlphaRef"], "", None ), + ( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ), + ( "GL_MAX_CLIP_PLANES", GLint, ["ctx->Const.MaxClipPlanes"], "", None ), + ( "GL_CLIP_PLANE0", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 0) & 1" ], "", None ), + ( "GL_CLIP_PLANE1", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 1) & 1" ], "", None ), + ( "GL_CLIP_PLANE2", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 2) & 1" ], "", None ), + ( "GL_CLIP_PLANE3", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 3) & 1" ], "", None ), + ( "GL_CLIP_PLANE4", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 4) & 1" ], "", None ), + ( "GL_CLIP_PLANE5", GLboolean, + [ "(ctx->Transform.ClipPlanesEnabled >> 5) & 1" ], "", None ), + ( "GL_COLOR_MATERIAL", GLboolean, + ["ctx->Light.ColorMaterialEnabled"], "", None ), + ( "GL_CURRENT_COLOR", GLfloatN, + [ "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]", + "ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]" ], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_CURRENT_NORMAL", GLfloatN, + [ "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]", + "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]", + "ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]"], + "FLUSH_CURRENT(ctx, 0);", None ), + ( "GL_CURRENT_TEXTURE_COORDS", GLfloat, + ["ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"], + "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ), + ( "GL_DISTANCE_ATTENUATION_EXT", GLfloat, + ["ctx->Point.Params[0]", + "ctx->Point.Params[1]", + "ctx->Point.Params[2]"], "", None ), + ( "GL_FOG", GLboolean, ["ctx->Fog.Enabled"], "", None ), + ( "GL_FOG_COLOR", GLfloatN, + [ "ctx->Fog.Color[0]", + "ctx->Fog.Color[1]", + "ctx->Fog.Color[2]", + "ctx->Fog.Color[3]" ], "", None ), + ( "GL_FOG_DENSITY", GLfloat, ["ctx->Fog.Density"], "", None ), + ( "GL_FOG_END", GLfloat, ["ctx->Fog.End"], "", None ), + ( "GL_FOG_HINT", GLenum, ["ctx->Hint.Fog"], "", None ), + ( "GL_FOG_MODE", GLenum, ["ctx->Fog.Mode"], "", None ), + ( "GL_FOG_START", GLfloat, ["ctx->Fog.Start"], "", None ), + ( "GL_LINE_SMOOTH", GLboolean, ["ctx->Line.SmoothFlag"], "", None ), + ( "GL_LINE_SMOOTH_HINT", GLenum, ["ctx->Hint.LineSmooth"], "", None ), + ( "GL_LINE_WIDTH_RANGE", GLfloat, + ["ctx->Const.MinLineWidthAA", + "ctx->Const.MaxLineWidthAA"], "", None ), + ( "GL_COLOR_LOGIC_OP", GLboolean, ["ctx->Color.ColorLogicOpEnabled"], "", None ), + ( "GL_LOGIC_OP_MODE", GLenum, ["ctx->Color.LogicOp"], "", None ), + ( "GL_MATRIX_MODE", GLenum, ["ctx->Transform.MatrixMode"], "", None ), + + ( "GL_MAX_MODELVIEW_STACK_DEPTH", GLint, ["MAX_MODELVIEW_STACK_DEPTH"], "", None ), + ( "GL_MAX_PROJECTION_STACK_DEPTH", GLint, ["MAX_PROJECTION_STACK_DEPTH"], "", None ), + ( "GL_MAX_TEXTURE_STACK_DEPTH", GLint, ["MAX_TEXTURE_STACK_DEPTH"], "", None ), + ( "GL_MODELVIEW_MATRIX", GLfloat, + [ "matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;", None ), + ( "GL_MODELVIEW_STACK_DEPTH", GLint, ["ctx->ModelviewMatrixStack.Depth + 1"], "", None ), + ( "GL_NORMALIZE", GLboolean, ["ctx->Transform.Normalize"], "", None ), + ( "GL_PACK_SKIP_IMAGES_EXT", GLint, ["ctx->Pack.SkipImages"], "", None ), + ( "GL_PERSPECTIVE_CORRECTION_HINT", GLenum, + ["ctx->Hint.PerspectiveCorrection"], "", None ), + ( "GL_POINT_SIZE", GLfloat, ["ctx->Point.Size"], "", None ), + ( "GL_POINT_SIZE_RANGE", GLfloat, + ["ctx->Const.MinPointSizeAA", + "ctx->Const.MaxPointSizeAA"], "", None ), + ( "GL_POINT_SMOOTH", GLboolean, ["ctx->Point.SmoothFlag"], "", None ), + ( "GL_POINT_SMOOTH_HINT", GLenum, ["ctx->Hint.PointSmooth"], "", None ), + ( "GL_POINT_SIZE_MIN_EXT", GLfloat, ["ctx->Point.MinSize"], "", None ), + ( "GL_POINT_SIZE_MAX_EXT", GLfloat, ["ctx->Point.MaxSize"], "", None ), + ( "GL_POINT_FADE_THRESHOLD_SIZE_EXT", GLfloat, + ["ctx->Point.Threshold"], "", None ), + ( "GL_PROJECTION_MATRIX", GLfloat, + [ "matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;", None ), + ( "GL_PROJECTION_STACK_DEPTH", GLint, + ["ctx->ProjectionMatrixStack.Depth + 1"], "", None ), + ( "GL_RESCALE_NORMAL", GLboolean, + ["ctx->Transform.RescaleNormals"], "", None ), + ( "GL_SHADE_MODEL", GLenum, ["ctx->Light.ShadeModel"], "", None ), + ( "GL_TEXTURE_2D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_2D)"], "", None ), + ( "GL_TEXTURE_MATRIX", GLfloat, + ["matrix[0]", "matrix[1]", "matrix[2]", "matrix[3]", + "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", + "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", + "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], + "const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;", None ), + ( "GL_TEXTURE_STACK_DEPTH", GLint, + ["ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1"], "", None ), + ( "GL_VERTEX_ARRAY", GLboolean, ["ctx->Array.ArrayObj->Vertex.Enabled"], "", None ), + ( "GL_VERTEX_ARRAY_SIZE", GLint, ["ctx->Array.ArrayObj->Vertex.Size"], "", None ), + ( "GL_VERTEX_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Vertex.Type"], "", None ), + ( "GL_VERTEX_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Vertex.Stride"], "", None ), + ( "GL_NORMAL_ARRAY", GLenum, ["ctx->Array.ArrayObj->Normal.Enabled"], "", None ), + ( "GL_NORMAL_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Normal.Type"], "", None ), + ( "GL_NORMAL_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Normal.Stride"], "", None ), + ( "GL_COLOR_ARRAY", GLboolean, ["ctx->Array.ArrayObj->Color.Enabled"], "", None ), + ( "GL_COLOR_ARRAY_SIZE", GLint, ["ctx->Array.ArrayObj->Color.Size"], "", None ), + ( "GL_COLOR_ARRAY_TYPE", GLenum, ["ctx->Array.ArrayObj->Color.Type"], "", None ), + ( "GL_COLOR_ARRAY_STRIDE", GLint, ["ctx->Array.ArrayObj->Color.Stride"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY", GLboolean, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_SIZE", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_TYPE", GLenum, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type"], "", None ), + ( "GL_TEXTURE_COORD_ARRAY_STRIDE", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride"], "", None ), + # GL_ARB_multitexture + ( "GL_MAX_TEXTURE_UNITS_ARB", GLint, + ["ctx->Const.MaxTextureUnits"], "", ["ARB_multitexture"] ), + ( "GL_CLIENT_ACTIVE_TEXTURE_ARB", GLint, + ["GL_TEXTURE0_ARB + ctx->Array.ActiveTexture"], "", ["ARB_multitexture"] ), + # OES_texture_cube_map + ( "GL_TEXTURE_CUBE_MAP_ARB", GLboolean, + ["_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB)"], "", None), + ( "GL_TEXTURE_GEN_STR_OES", GLboolean, + # S, T, and R are always set at the same time + ["((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0)"], "", None), + # ARB_multisample + ( "GL_MULTISAMPLE_ARB", GLboolean, + ["ctx->Multisample.Enabled"], "", ["ARB_multisample"] ), + ( "GL_SAMPLE_ALPHA_TO_ONE_ARB", GLboolean, + ["ctx->Multisample.SampleAlphaToOne"], "", ["ARB_multisample"] ), + + ( "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Vertex.BufferObj->Name"], "", ["ARB_vertex_buffer_object"] ), + ( "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Normal.BufferObj->Name"], "", ["ARB_vertex_buffer_object"] ), + ( "GL_COLOR_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->Color.BufferObj->Name"], "", ["ARB_vertex_buffer_object"] ), + ( "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB", GLint, + ["ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name"], + "", ["ARB_vertex_buffer_object"] ), + + # OES_point_sprite + ( "GL_POINT_SPRITE_NV", GLboolean, ["ctx->Point.PointSprite"], # == GL_POINT_SPRITE_ARB + "", None), + + # GL_ARB_fragment_shader + ( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint, + ["ctx->Const.FragmentProgram.MaxUniformComponents"], "", + ["ARB_fragment_shader"] ), + + # GL_ARB_vertex_shader + ( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB", GLint, + ["ctx->Const.VertexProgram.MaxUniformComponents"], "", + ["ARB_vertex_shader"] ), + ( "GL_MAX_VARYING_FLOATS_ARB", GLint, + ["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ), + + # OES_matrix_get + ( "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES", GLint, [], + """ + /* See GL_OES_matrix_get */ + { + const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m; + memcpy(params, matrix, 16 * sizeof(GLint)); + }""", + None), + + ( "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES", GLint, [], + """ + /* See GL_OES_matrix_get */ + { + const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m; + memcpy(params, matrix, 16 * sizeof(GLint)); + }""", + None), + + ( "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES", GLint, [], + """ + /* See GL_OES_matrix_get */ + { + const GLfloat *matrix = + ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; + memcpy(params, matrix, 16 * sizeof(GLint)); + }""", + None), + + # OES_point_size_array + ("GL_POINT_SIZE_ARRAY_OES", GLboolean, + ["ctx->Array.ArrayObj->PointSize.Enabled"], "", None), + ("GL_POINT_SIZE_ARRAY_TYPE_OES", GLenum, + ["ctx->Array.ArrayObj->PointSize.Type"], "", None), + ("GL_POINT_SIZE_ARRAY_STRIDE_OES", GLint, + ["ctx->Array.ArrayObj->PointSize.Stride"], "", None), + ("GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES", GLint, + ["ctx->Array.ArrayObj->PointSize.BufferObj->Name"], "", None), + + # GL_EXT_texture_lod_bias + ( "GL_MAX_TEXTURE_LOD_BIAS_EXT", GLfloat, + ["ctx->Const.MaxTextureLodBias"], "", ["EXT_texture_lod_bias"]), + + # GL_EXT_texture_filter_anisotropic + ( "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT", GLfloat, + ["ctx->Const.MaxTextureMaxAnisotropy"], "", ["EXT_texture_filter_anisotropic"]), + +] + +# Only present in ES 2.x: +StateVars_es2 = [ + # XXX These entries are not spec'ed for GLES 2, but are + # needed for Mesa's GLSL: + ( "GL_MAX_LIGHTS", GLint, ["ctx->Const.MaxLights"], "", None ), + ( "GL_MAX_CLIP_PLANES", GLint, ["ctx->Const.MaxClipPlanes"], "", None ), + ( "GL_MAX_TEXTURE_COORDS_ARB", GLint, # == GL_MAX_TEXTURE_COORDS_NV + ["ctx->Const.MaxTextureCoordUnits"], "", + ["ARB_fragment_program", "NV_fragment_program"] ), + ( "GL_MAX_DRAW_BUFFERS_ARB", GLint, + ["ctx->Const.MaxDrawBuffers"], "", ["ARB_draw_buffers"] ), + ( "GL_BLEND_COLOR_EXT", GLfloatN, + [ "ctx->Color.BlendColor[0]", + "ctx->Color.BlendColor[1]", + "ctx->Color.BlendColor[2]", + "ctx->Color.BlendColor[3]"], "", None ), + + # This is required for GLES2, but also needed for GLSL: + ( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB", GLint, # == GL_MAX_TEXTURE_IMAGE_UNI + ["ctx->Const.MaxTextureImageUnits"], "", + ["ARB_fragment_program", "NV_fragment_program"] ), + + ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, + ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), + ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, + ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + + # GL_ARB_shader_objects + # Actually, this token isn't part of GL_ARB_shader_objects, but is + # close enough for now. + ( "GL_CURRENT_PROGRAM", GLint, + ["ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0"], + "", ["ARB_shader_objects"] ), + + # OpenGL 2.0 + ( "GL_STENCIL_BACK_FUNC", GLenum, ["ctx->Stencil.Function[1]"], "", None ), + ( "GL_STENCIL_BACK_VALUE_MASK", GLint, ["ctx->Stencil.ValueMask[1]"], "", None ), + ( "GL_STENCIL_BACK_WRITEMASK", GLint, ["ctx->Stencil.WriteMask[1]"], "", None ), + ( "GL_STENCIL_BACK_REF", GLint, ["ctx->Stencil.Ref[1]"], "", None ), + ( "GL_STENCIL_BACK_FAIL", GLenum, ["ctx->Stencil.FailFunc[1]"], "", None ), + ( "GL_STENCIL_BACK_PASS_DEPTH_FAIL", GLenum, ["ctx->Stencil.ZFailFunc[1]"], "", None ), + ( "GL_STENCIL_BACK_PASS_DEPTH_PASS", GLenum, ["ctx->Stencil.ZPassFunc[1]"], "", None ), + + ( "GL_MAX_VERTEX_ATTRIBS_ARB", GLint, + ["ctx->Const.VertexProgram.MaxAttribs"], "", ["ARB_vertex_program"] ), + + # OES_texture_3D + ( "GL_TEXTURE_BINDING_3D", GLint, + ["ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_3D_INDEX]->Name"], "", None), + ( "GL_MAX_3D_TEXTURE_SIZE", GLint, ["1 << (ctx->Const.Max3DTextureLevels - 1)"], "", None), + + # OES_standard_derivatives + ( "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB", GLenum, + ["ctx->Hint.FragmentShaderDerivative"], "", ["ARB_fragment_shader"] ), + + # Unique to ES 2 (not in full GL) + ( "GL_MAX_FRAGMENT_UNIFORM_VECTORS", GLint, + ["ctx->Const.FragmentProgram.MaxUniformComponents / 4"], "", None), + ( "GL_MAX_VARYING_VECTORS", GLint, + ["ctx->Const.MaxVarying"], "", None), + ( "GL_MAX_VERTEX_UNIFORM_VECTORS", GLint, + ["ctx->Const.VertexProgram.MaxUniformComponents / 4"], "", None), + ( "GL_SHADER_COMPILER", GLint, ["1"], "", None), + # OES_get_program_binary + ( "GL_NUM_SHADER_BINARY_FORMATS", GLint, ["0"], "", None), + ( "GL_SHADER_BINARY_FORMATS", GLint, [], "", None), +] + + + +def ConversionFunc(fromType, toType): + """Return the name of the macro to convert between two data types.""" + if fromType == toType: + return "" + elif fromType == GLfloat and toType == GLint: + return "IROUND" + elif fromType == GLfloatN and toType == GLfloat: + return "" + elif fromType == GLint and toType == GLfloat: # but not GLfloatN! + return "(GLfloat)" + else: + if fromType == GLfloatN: + fromType = GLfloat + fromStr = TypeStrings[fromType] + fromStr = string.upper(fromStr[2:]) + toStr = TypeStrings[toType] + toStr = string.upper(toStr[2:]) + return fromStr + "_TO_" + toStr + + +def EmitGetFunction(stateVars, returnType): + """Emit the code to implement glGetBooleanv, glGetIntegerv or glGetFloatv.""" + assert (returnType == GLboolean or + returnType == GLint or + returnType == GLfloat or + returnType == GLfixed) + + strType = TypeStrings[returnType] + # Capitalize first letter of return type + if returnType == GLint: + function = "_mesa_GetIntegerv" + elif returnType == GLboolean: + function = "_mesa_GetBooleanv" + elif returnType == GLfloat: + function = "_mesa_GetFloatv" + elif returnType == GLfixed: + function = "_mesa_GetFixedv" + else: + abort() + + print "void GLAPIENTRY" + print "%s( GLenum pname, %s *params )" % (function, strType) + print "{" + print " GET_CURRENT_CONTEXT(ctx);" + print " ASSERT_OUTSIDE_BEGIN_END(ctx);" + print "" + print " if (!params)" + print " return;" + print "" + print " if (ctx->NewState)" + print " _mesa_update_state(ctx);" + print "" + print " switch (pname) {" + + for (name, varType, state, optionalCode, extensions) in stateVars: + print " case " + name + ":" + if extensions: + if len(extensions) == 1: + print (' CHECK_EXT1(%s, "%s");' % + (extensions[0], function)) + elif len(extensions) == 2: + print (' CHECK_EXT2(%s, %s, "%s");' % + (extensions[0], extensions[1], function)) + elif len(extensions) == 3: + print (' CHECK_EXT3(%s, %s, %s, "%s");' % + (extensions[0], extensions[1], extensions[2], function)) + else: + assert len(extensions) == 4 + print (' CHECK_EXT4(%s, %s, %s, %s, "%s");' % + (extensions[0], extensions[1], extensions[2], extensions[3], function)) + if optionalCode: + print " {" + print " " + optionalCode + conversion = ConversionFunc(varType, returnType) + n = len(state) + for i in range(n): + if conversion: + print " params[%d] = %s(%s);" % (i, conversion, state[i]) + else: + print " params[%d] = %s;" % (i, state[i]) + if optionalCode: + print " }" + print " break;" + + print " default:" + print ' _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(pname=0x%%x)", pname);' % function + print " }" + print "}" + print "" + return + + + +def EmitHeader(): + """Print the get.c file header.""" + print """ +/*** + *** NOTE!!! DO NOT EDIT THIS FILE!!! IT IS GENERATED BY get_gen.py + ***/ + +#include "main/glheader.h" +#include "main/context.h" +#include "main/enable.h" +#include "main/extensions.h" +#include "main/fbobject.h" +#include "main/get.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/state.h" +#include "main/texcompress.h" +#include "main/framebuffer.h" + + +/* ES1 tokens that should be in gl.h but aren't */ +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 + + +/* ES2 special tokens */ +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_SHADER_COMPILER 0x8DFA +#define GL_PLATFORM_BINARY 0x8D63 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + + +#ifndef GL_OES_matrix_get +#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D +#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E +#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F +#endif + +#ifndef GL_OES_compressed_paletted_texture +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif + +/* GL_OES_texture_cube_map */ +#ifndef GL_OES_texture_cube_map +#define GL_TEXTURE_GEN_STR_OES 0x8D60 +#endif + +#define FLOAT_TO_BOOLEAN(X) ( (X) ? GL_TRUE : GL_FALSE ) +#define FLOAT_TO_FIXED(F) ( ((F) * 65536.0f > INT_MAX) ? INT_MAX : \\ + ((F) * 65536.0f < INT_MIN) ? INT_MIN : \\ + (GLint) ((F) * 65536.0f) ) + +#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE ) +#define INT_TO_FIXED(I) ( ((I) > SHRT_MAX) ? INT_MAX : \\ + ((I) < SHRT_MIN) ? INT_MIN : \\ + (GLint) ((I) * 65536) ) + +#define BOOLEAN_TO_INT(B) ( (GLint) (B) ) +#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F ) +#define BOOLEAN_TO_FIXED(B) ( (GLint) ((B) ? 1 : 0) << 16 ) + +#define ENUM_TO_FIXED(E) (E) + + +/* + * Check if named extension is enabled, if not generate error and return. + */ +#define CHECK_EXT1(EXT1, FUNC) \\ + if (!ctx->Extensions.EXT1) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of two extensions is enabled. + */ +#define CHECK_EXT2(EXT1, EXT2, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of three extensions is enabled. + */ +#define CHECK_EXT3(EXT1, EXT2, EXT3, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \\ + !ctx->Extensions.EXT3) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + +/* + * Check if either of four extensions is enabled. + */ +#define CHECK_EXT4(EXT1, EXT2, EXT3, EXT4, FUNC) \\ + if (!ctx->Extensions.EXT1 && !ctx->Extensions.EXT2 && \\ + !ctx->Extensions.EXT3 && !ctx->Extensions.EXT4) { \\ + _mesa_error(ctx, GL_INVALID_ENUM, FUNC "(0x%x)", (int) pname); \\ + return; \\ + } + + + +/** + * List of compressed texture formats supported by ES. + */ +static GLenum compressed_formats[] = { + GL_PALETTE4_RGB8_OES, + GL_PALETTE4_RGBA8_OES, + GL_PALETTE4_R5_G6_B5_OES, + GL_PALETTE4_RGBA4_OES, + GL_PALETTE4_RGB5_A1_OES, + GL_PALETTE8_RGB8_OES, + GL_PALETTE8_RGBA8_OES, + GL_PALETTE8_R5_G6_B5_OES, + GL_PALETTE8_RGBA4_OES, + GL_PALETTE8_RGB5_A1_OES +}; + +#define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0])) + +void GLAPIENTRY +_mesa_GetFixedv( GLenum pname, GLfixed *params ); + +""" + return + + +def EmitAll(stateVars, API): + EmitHeader() + EmitGetFunction(stateVars, GLboolean) + EmitGetFunction(stateVars, GLfloat) + EmitGetFunction(stateVars, GLint) + if API == 1: + EmitGetFunction(stateVars, GLfixed) + + +def main(args): + # Determine whether to generate ES1 or ES2 queries + if len(args) > 1 and args[1] == "1": + API = 1 + elif len(args) > 1 and args[1] == "2": + API = 2 + else: + API = 1 + #print "len args = %d API = %d" % (len(args), API) + + if API == 1: + vars = StateVars_common + StateVars_es1 + else: + vars = StateVars_common + StateVars_es2 + + EmitAll(vars, API) + + +main(sys.argv) diff --git a/src/mesa/es/main/mfeatures_es1.h b/src/mesa/es/main/mfeatures_es1.h new file mode 100644 index 0000000000..6c2ece2608 --- /dev/null +++ b/src/mesa/es/main/mfeatures_es1.h @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2008 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. + * + **************************************************************************/ + +/** + * \file mfeatures.h + * + * The #defines in this file enable/disable Mesa features needed + * for OpenGL ES 1.1. + */ + + +#ifndef MFEATURES_ES1_H +#define MFEATURES_ES1_H + +/* this file replaces main/mfeatures.h */ +#ifdef FEATURES_H +#error "main/mfeatures.h was wrongly included" +#endif +#define FEATURES_H + +#define ASSERT_NO_FEATURE() ASSERT(0) + +/* + * Enable/disable features (blocks of code) by setting FEATURE_xyz to 0 or 1. + */ +#ifndef _HAVE_FULL_GL +#define _HAVE_FULL_GL 1 +#endif + +#ifdef IN_DRI_DRIVER +#define FEATURE_remap_table 1 +#else +#define FEATURE_remap_table 0 +#endif + +#define FEATURE_accum 0 +#define FEATURE_arrayelt 0 +#define FEATURE_attrib 0 +#define FEATURE_beginend 0 +#define FEATURE_colortable 0 +#define FEATURE_convolve 0 +#define FEATURE_dispatch 1 +#define FEATURE_dlist 0 +#define FEATURE_draw_read_buffer 0 +#define FEATURE_drawpix 0 +#define FEATURE_eval 0 +#define FEATURE_feedback 0 +#define FEATURE_fixedpt 1 +#define FEATURE_histogram 0 +#define FEATURE_pixel 0 +#define FEATURE_point_size_array 1 +#define FEATURE_queryobj 0 +#define FEATURE_rastpos 0 +#define FEATURE_texgen 1 +#define FEATURE_texture_fxt1 0 +#define FEATURE_texture_s3tc 0 +#define FEATURE_userclip 1 +#define FEATURE_vertex_array_byte 1 +#define FEATURE_es2_glsl 0 + +#define FEATURE_ARB_fragment_program _HAVE_FULL_GL +#define FEATURE_ARB_vertex_buffer_object _HAVE_FULL_GL +#define FEATURE_ARB_vertex_program _HAVE_FULL_GL + +#define FEATURE_ARB_vertex_shader _HAVE_FULL_GL +#define FEATURE_ARB_fragment_shader _HAVE_FULL_GL +#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader) +#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects +#define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects + +#define FEATURE_EXT_framebuffer_blit 0 +#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL +#define FEATURE_EXT_pixel_buffer_object _HAVE_FULL_GL +#define FEATURE_EXT_texture_sRGB 0 +#define FEATURE_ATI_fragment_shader 0 +#define FEATURE_MESA_program_debug _HAVE_FULL_GL +#define FEATURE_NV_fence 0 +#define FEATURE_NV_fragment_program 0 +#define FEATURE_NV_vertex_program 0 + +#define FEATURE_OES_framebuffer_object 1 +#define FEATURE_OES_draw_texture 1 +#define FEATURE_OES_mapbuffer 1 + +#define FEATURE_extra_context_init 1 + +/*@}*/ + + + + +#endif /* MFEATURES_ES1_H */ diff --git a/src/mesa/es/main/mfeatures_es2.h b/src/mesa/es/main/mfeatures_es2.h new file mode 100644 index 0000000000..f34782fedb --- /dev/null +++ b/src/mesa/es/main/mfeatures_es2.h @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2008 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. + * + **************************************************************************/ + +/** + * \file mfeatures.h + * + * The #defines in this file enable/disable Mesa features needed + * for OpenGL ES 2.0. + */ + + +#ifndef MFEATURES_ES2_H +#define MFEATURES_ES2_H + +/* this file replaces main/mfeatures.h */ +#ifdef FEATURES_H +#error "main/mfeatures.h was wrongly included" +#endif +#define FEATURES_H + +#define ASSERT_NO_FEATURE() ASSERT(0) + +/* + * Enable/disable features (blocks of code) by setting FEATURE_xyz to 0 or 1. + */ +#ifndef _HAVE_FULL_GL +#define _HAVE_FULL_GL 1 +#endif + +#ifdef IN_DRI_DRIVER +#define FEATURE_remap_table 1 +#else +#define FEATURE_remap_table 0 +#endif + +#define FEATURE_accum 0 +#define FEATURE_arrayelt 0 +#define FEATURE_attrib 0 +#define FEATURE_beginend 0 +#define FEATURE_colortable 0 +#define FEATURE_convolve 0 +#define FEATURE_dispatch 1 +#define FEATURE_dlist 0 +#define FEATURE_draw_read_buffer 0 +#define FEATURE_drawpix 0 +#define FEATURE_eval 0 +#define FEATURE_feedback 0 +#define FEATURE_fixedpt 1 +#define FEATURE_histogram 0 +#define FEATURE_pixel 0 +#define FEATURE_point_size_array 1 +#define FEATURE_queryobj 0 +#define FEATURE_rastpos 0 +#define FEATURE_texgen 1 +#define FEATURE_texture_fxt1 0 +#define FEATURE_texture_s3tc 0 +#define FEATURE_userclip 1 +#define FEATURE_vertex_array_byte 1 +#define FEATURE_es2_glsl 1 + +#define FEATURE_ARB_fragment_program _HAVE_FULL_GL +#define FEATURE_ARB_vertex_buffer_object _HAVE_FULL_GL +#define FEATURE_ARB_vertex_program _HAVE_FULL_GL + +#define FEATURE_ARB_vertex_shader _HAVE_FULL_GL +#define FEATURE_ARB_fragment_shader _HAVE_FULL_GL +#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader) +#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects +#define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects + +#define FEATURE_EXT_framebuffer_blit 0 +#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL +#define FEATURE_EXT_pixel_buffer_object _HAVE_FULL_GL +#define FEATURE_EXT_texture_sRGB 0 +#define FEATURE_ATI_fragment_shader 0 +#define FEATURE_MESA_program_debug _HAVE_FULL_GL +#define FEATURE_NV_fence 0 +#define FEATURE_NV_fragment_program 0 +#define FEATURE_NV_vertex_program 0 + +#define FEATURE_OES_framebuffer_object 1 +#define FEATURE_OES_draw_texture 0 +#define FEATURE_OES_mapbuffer 1 + +#define FEATURE_extra_context_init 1 + +/*@}*/ + + + + +#endif /* MFEATURES_ES2_H */ diff --git a/src/mesa/es/main/specials_es1.c b/src/mesa/es/main/specials_es1.c new file mode 100644 index 0000000000..a4f14490f3 --- /dev/null +++ b/src/mesa/es/main/specials_es1.c @@ -0,0 +1,213 @@ +/************************************************************************** + * + * Copyright 2008 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, 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 + * TUNGSTEN GRAPHICS 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/mtypes.h" +#include "main/context.h" +#include "main/imports.h" +#include "main/get.h" + + +extern const GLubyte * GLAPIENTRY _es_GetString(GLenum name); + + +static const GLubyte * +compute_es_version(void) +{ + GET_CURRENT_CONTEXT(ctx); + static const char es_1_0[] = "OpenGL ES-CM 1.0"; + static const char es_1_1[] = "OpenGL ES-CM 1.1"; + /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ + const GLboolean ver_1_0 = (ctx->Extensions.ARB_multisample && + ctx->Extensions.ARB_multitexture && + ctx->Extensions.ARB_texture_compression && + ctx->Extensions.EXT_texture_env_add && + ctx->Extensions.ARB_texture_env_combine && + ctx->Extensions.ARB_texture_env_dot3); + /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ + const GLboolean ver_1_1 = (ver_1_0 && + ctx->Extensions.EXT_point_parameters && + ctx->Extensions.SGIS_generate_mipmap && + ctx->Extensions.ARB_vertex_buffer_object); + if (ver_1_1) + return (const GLubyte *) es_1_1; + + if (!ver_1_0) + _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); + return (const GLubyte *) es_1_0; +} + + +static size_t +append_extension(char **str, const char *ext) +{ + char *s = *str; + size_t len = strlen(ext); + + if (s) { + memcpy(s, ext, len); + s[len++] = ' '; + s[len] = '\0'; + + *str += len; + } + else { + len++; + } + + return len; +} + + +static size_t +make_extension_string(const GLcontext *ctx, char *str) +{ + size_t len = 0; + + /* Core additions */ + len += append_extension(&str, "GL_OES_byte_coordinates"); + len += append_extension(&str, "GL_OES_fixed_point"); + len += append_extension(&str, "GL_OES_single_precision"); + len += append_extension(&str, "GL_OES_matrix_get"); + + /* 1.1 required extensions */ + len += append_extension(&str, "GL_OES_read_format"); + len += append_extension(&str, "GL_OES_compressed_paletted_texture"); + len += append_extension(&str, "GL_OES_point_size_array"); + len += append_extension(&str, "GL_OES_point_sprite"); + + /* 1.1 deprecated extensions */ + len += append_extension(&str, "GL_OES_query_matrix"); + +#if FEATURE_OES_draw_texture + if (ctx->Extensions.OES_draw_texture) + len += append_extension(&str, "GL_OES_draw_texture"); +#endif + + if (ctx->Extensions.EXT_blend_equation_separate) + len += append_extension(&str, "GL_OES_blend_equation_separate"); + if (ctx->Extensions.EXT_blend_func_separate) + len += append_extension(&str, "GL_OES_blend_func_separate"); + if (ctx->Extensions.EXT_blend_subtract) + len += append_extension(&str, "GL_OES_blend_subtract"); + + if (ctx->Extensions.EXT_stencil_wrap) + len += append_extension(&str, "GL_OES_stencil_wrap"); + + if (ctx->Extensions.ARB_texture_cube_map) + len += append_extension(&str, "GL_OES_texture_cube_map"); + if (ctx->Extensions.ARB_texture_env_crossbar) + len += append_extension(&str, "GL_OES_texture_env_crossbar"); + if (ctx->Extensions.ARB_texture_mirrored_repeat) + len += append_extension(&str, "GL_OES_texture_mirrored_repeat"); + + if (ctx->Extensions.ARB_framebuffer_object) { + len += append_extension(&str, "GL_OES_framebuffer_object"); + len += append_extension(&str, "GL_OES_depth24"); + len += append_extension(&str, "GL_OES_depth32"); + len += append_extension(&str, "GL_OES_fbo_render_mipmap"); + len += append_extension(&str, "GL_OES_rgb8_rgba8"); + len += append_extension(&str, "GL_OES_stencil1"); + len += append_extension(&str, "GL_OES_stencil4"); + len += append_extension(&str, "GL_OES_stencil8"); + } + + if (ctx->Extensions.EXT_vertex_array) + len += append_extension(&str, "GL_OES_element_index_uint"); + if (ctx->Extensions.ARB_vertex_buffer_object) + len += append_extension(&str, "GL_OES_mapbuffer"); + if (ctx->Extensions.EXT_texture_filter_anisotropic) + len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); + + /* some applications check this for NPOT support */ + if (ctx->Extensions.ARB_texture_non_power_of_two) + len += append_extension(&str, "GL_ARB_texture_non_power_of_two"); + + if (ctx->Extensions.EXT_texture_compression_s3tc) + len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); + if (ctx->Extensions.EXT_texture_lod_bias) + len += append_extension(&str, "GL_EXT_texture_lod_bias"); + if (ctx->Extensions.EXT_blend_minmax) + len += append_extension(&str, "GL_EXT_blend_minmax"); + if (ctx->Extensions.EXT_multi_draw_arrays) + len += append_extension(&str, "GL_EXT_multi_draw_arrays"); + + return len; +} + + +static const GLubyte * +compute_es_extensions(void) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.String) { + char *s; + unsigned int len; + + len = make_extension_string(ctx, NULL); + s = (char *) _mesa_malloc(len + 1); + if (!s) + return NULL; + make_extension_string(ctx, s); + ctx->Extensions.String = (const GLubyte *) s; + } + + return ctx->Extensions.String; +} + + +const GLubyte * GLAPIENTRY +_es_GetString(GLenum name) +{ + switch (name) { + case GL_VERSION: + return compute_es_version(); + case GL_EXTENSIONS: + return compute_es_extensions(); + default: + return _mesa_GetString(name); + } +} + + +void +_mesa_initialize_context_extra(GLcontext *ctx) +{ + GLuint i; + + /** + * 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; + } +} diff --git a/src/mesa/es/main/specials_es2.c b/src/mesa/es/main/specials_es2.c new file mode 100644 index 0000000000..e11ade9b94 --- /dev/null +++ b/src/mesa/es/main/specials_es2.c @@ -0,0 +1,174 @@ +/************************************************************************** + * + * Copyright 2008 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, 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 + * TUNGSTEN GRAPHICS 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/mtypes.h" +#include "main/context.h" +#include "main/imports.h" +#include "main/get.h" + + +const GLubyte * GLAPIENTRY _es_GetString(GLenum name); + + +static const GLubyte * +compute_es_version(void) +{ + GET_CURRENT_CONTEXT(ctx); + static const char es_2_0[] = "OpenGL ES 2.0"; + /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ + const GLboolean ver_2_0 = (ctx->Extensions.ARB_multisample && + ctx->Extensions.ARB_multitexture && + ctx->Extensions.ARB_texture_compression && + ctx->Extensions.ARB_texture_cube_map && + ctx->Extensions.ARB_texture_mirrored_repeat && + ctx->Extensions.EXT_blend_color && + ctx->Extensions.EXT_blend_func_separate && + ctx->Extensions.EXT_blend_minmax && + ctx->Extensions.EXT_blend_subtract && + ctx->Extensions.EXT_stencil_wrap && + ctx->Extensions.ARB_vertex_buffer_object && + ctx->Extensions.ARB_shader_objects && + ctx->Extensions.ARB_vertex_shader && + ctx->Extensions.ARB_fragment_shader && + ctx->Extensions.ARB_texture_non_power_of_two && + ctx->Extensions.EXT_blend_equation_separate); + if (!ver_2_0) + _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); + return (const GLubyte *) es_2_0; +} + + +static size_t +append_extension(char **str, const char *ext) +{ + char *s = *str; + size_t len = strlen(ext); + + if (s) { + memcpy(s, ext, len); + s[len++] = ' '; + s[len] = '\0'; + + *str += len; + } + else { + len++; + } + + return len; +} + + +static size_t +make_extension_string(const GLcontext *ctx, char *str) +{ + size_t len = 0; + + len += append_extension(&str, "GL_OES_compressed_paletted_texture"); + + if (ctx->Extensions.ARB_framebuffer_object) { + len += append_extension(&str, "GL_OES_depth24"); + len += append_extension(&str, "GL_OES_depth32"); + len += append_extension(&str, "GL_OES_fbo_render_mipmap"); + len += append_extension(&str, "GL_OES_rgb8_rgba8"); + len += append_extension(&str, "GL_OES_stencil1"); + len += append_extension(&str, "GL_OES_stencil4"); + } + + if (ctx->Extensions.EXT_vertex_array) + len += append_extension(&str, "GL_OES_element_index_uint"); + if (ctx->Extensions.ARB_vertex_buffer_object) + len += append_extension(&str, "GL_OES_mapbuffer"); + + if (ctx->Extensions.EXT_texture3D) + len += append_extension(&str, "GL_OES_texture_3D"); + if (ctx->Extensions.ARB_texture_non_power_of_two) + len += append_extension(&str, "GL_OES_texture_npot"); + if (ctx->Extensions.EXT_texture_filter_anisotropic) + len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); + + len += append_extension(&str, "GL_EXT_texture_type_2_10_10_10_REV"); + if (ctx->Extensions.ARB_depth_texture) + len += append_extension(&str, "GL_OES_depth_texture"); + if (ctx->Extensions.EXT_packed_depth_stencil) + len += append_extension(&str, "GL_OES_packed_depth_stencil"); + if (ctx->Extensions.ARB_fragment_shader) + len += append_extension(&str, "GL_OES_standard_derivatives"); + + if (ctx->Extensions.EXT_texture_compression_s3tc) + len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); + if (ctx->Extensions.EXT_blend_minmax) + len += append_extension(&str, "GL_EXT_blend_minmax"); + if (ctx->Extensions.EXT_multi_draw_arrays) + len += append_extension(&str, "GL_EXT_multi_draw_arrays"); + + return len; +} + + +static const GLubyte * +compute_es_extensions(void) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.String) { + char *s; + unsigned int len; + + len = make_extension_string(ctx, NULL); + s = (char *) _mesa_malloc(len + 1); + if (!s) + return NULL; + make_extension_string(ctx, s); + ctx->Extensions.String = (const GLubyte *) s; + } + + return ctx->Extensions.String; +} + +const GLubyte * GLAPIENTRY +_es_GetString(GLenum name) +{ + switch (name) { + case GL_VERSION: + return compute_es_version(); + case GL_SHADING_LANGUAGE_VERSION: + return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; + case GL_EXTENSIONS: + return compute_es_extensions(); + default: + return _mesa_GetString(name); + } +} + + +void +_mesa_initialize_context_extra(GLcontext *ctx) +{ + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; + + ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */ +} diff --git a/src/mesa/es/main/stubs.c b/src/mesa/es/main/stubs.c new file mode 100644 index 0000000000..e7b8bc780f --- /dev/null +++ b/src/mesa/es/main/stubs.c @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2008 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, 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 + * TUNGSTEN GRAPHICS 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. + **************************************************************************/ + + +/** + * Temporary stubs for "missing" mesa functions. + */ + + +#include "main/mtypes.h" +#include "main/imports.h" +#include "vbo/vbo.h" + +#define NEED_IMPLEMENT() do { \ + GET_CURRENT_CONTEXT(ctx); \ + _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); \ + } while (0) + +#if FEATURE_accum +/* This is a sanity check that to be sure we're using the correct mfeatures.h + * header. We don't want to accidentally use the one from mainline Mesa. + */ +#error "The wrong mfeatures.h file is being included!" +#endif + + +/* silence compiler warnings */ +extern void GLAPIENTRY _vbo_Materialf(GLenum face, GLenum pname, GLfloat param); +extern void GLAPIENTRY _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +extern void GLAPIENTRY _mesa_ReleaseShaderCompiler(void); +extern void GLAPIENTRY _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length); +extern void GLAPIENTRY _vbo_VertexAttrib1f(GLuint indx, GLfloat x); +extern void GLAPIENTRY _vbo_VertexAttrib1fv(GLuint indx, const GLfloat* values); +extern void GLAPIENTRY _vbo_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y); +extern void GLAPIENTRY _vbo_VertexAttrib2fv(GLuint indx, const GLfloat* values); +extern void GLAPIENTRY _vbo_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY _vbo_VertexAttrib3fv(GLuint indx, const GLfloat* values); +extern void GLAPIENTRY _vbo_VertexAttrib4fv(GLuint indx, const GLfloat* values); + + +void GLAPIENTRY +_vbo_Materialf(GLenum face, GLenum pname, GLfloat param) +{ + _vbo_Materialfv(face, pname, ¶m); +} + + +void GLAPIENTRY +_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, + GLint* range, GLint* precision) +{ + NEED_IMPLEMENT(); +} + + +void GLAPIENTRY +_mesa_ReleaseShaderCompiler(void) +{ + NEED_IMPLEMENT(); +} + + +void GLAPIENTRY +_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, + const void* binary, GLint length) +{ + NEED_IMPLEMENT(); +} + + +void GLAPIENTRY +_vbo_VertexAttrib1f(GLuint indx, GLfloat x) +{ + _vbo_VertexAttrib4f(indx, x, 0.0, 0.0, 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib1fv(GLuint indx, const GLfloat* values) +{ + _vbo_VertexAttrib4f(indx, values[0], 0.0, 0.0, 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) +{ + _vbo_VertexAttrib4f(indx, x, y, 0.0, 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib2fv(GLuint indx, const GLfloat* values) +{ + _vbo_VertexAttrib4f(indx, values[0], values[1], 0.0, 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) +{ + _vbo_VertexAttrib4f(indx, x, y, z, 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib3fv(GLuint indx, const GLfloat* values) +{ + _vbo_VertexAttrib4f(indx, values[0], values[1], values[2], 1.0f); +} + + +void GLAPIENTRY +_vbo_VertexAttrib4fv(GLuint indx, const GLfloat* values) +{ + _vbo_VertexAttrib4f(indx, values[0], values[1], values[2], values[3]); +} diff --git a/src/mesa/es/sources.mak b/src/mesa/es/sources.mak new file mode 100644 index 0000000000..55bb31b80d --- /dev/null +++ b/src/mesa/es/sources.mak @@ -0,0 +1,166 @@ +include $(MESA)/sources.mak + +# LOCAL sources + +LOCAL_ES1_SOURCES := \ + main/api_exec_es1.c \ + main/get_es1.c \ + main/specials_es1.c \ + main/drawtex.c \ + main/es_cpaltex.c \ + main/es_enable.c \ + main/es_fbo.c \ + main/es_query_matrix.c \ + main/es_texgen.c \ + main/stubs.c \ + glapi/glapi-es1/main/enums.c + +LOCAL_ES1_GALLIUM_SOURCES := \ + $(LOCAL_ES1_SOURCES) \ + state_tracker/st_cb_drawtex.c + +# always use local version of GLAPI_ASM_SOURCES +LOCAL_ES1_API_ASM := $(addprefix glapi/glapi-es1/, $(GLAPI_ASM_SOURCES)) + +LOCAL_ES1_INCLUDES := \ + -I. \ + -I./glapi/glapi-es1 \ + -I./state_tracker \ + -I$(MESA)/state_tracker + +LOCAL_ES2_SOURCES := \ + main/api_exec_es2.c \ + main/get_es2.c \ + main/specials_es2.c \ + main/es_cpaltex.c \ + main/es_fbo.c \ + main/stubs.c \ + glapi/glapi-es2/main/enums.c + +LOCAL_ES2_GALLIUM_SOURCES := \ + $(LOCAL_ES2_SOURCES) + +LOCAL_ES2_API_ASM := $(subst es1,es2, $(LOCAL_ES1_API_ASM)) +LOCAL_ES2_INCLUDES := $(subst es1,es2, $(LOCAL_ES1_INCLUDES)) + +# MESA sources +# Ideally, the omit list should be replaced by features. + +MAIN_OMITTED := \ + main/api_exec.c \ + main/condrender.c \ + main/dlopen.c \ + main/enums.c \ + main/get.c +MAIN_SOURCES := $(filter-out $(MAIN_OMITTED), $(MAIN_SOURCES)) + +VBO_OMITTED := \ + vbo/vbo_save.c \ + vbo/vbo_save_api.c \ + vbo/vbo_save_draw.c \ + vbo/vbo_save_loopback.c +VBO_SOURCES := $(filter-out $(VBO_OMITTED), $(VBO_SOURCES)) + +STATETRACKER_OMITTED := \ + state_tracker/st_api.c \ + state_tracker/st_cb_drawpixels.c \ + state_tracker/st_cb_feedback.c \ + state_tracker/st_cb_rasterpos.c \ + state_tracker/st_draw_feedback.c +STATETRACKER_SOURCES := $(filter-out $(STATETRACKER_OMITTED), $(STATETRACKER_SOURCES)) + +SHADER_OMITTED := \ + shader/atifragshader.c +SHADER_SOURCES := $(filter-out $(SHADER_OMITTED), $(SHADER_SOURCES)) + +MESA_ES1_SOURCES := \ + $(MAIN_SOURCES) \ + $(MATH_SOURCES) \ + $(MATH_XFORM_SOURCES) \ + $(VBO_SOURCES) \ + $(TNL_SOURCES) \ + $(SHADER_SOURCES) \ + $(SWRAST_SOURCES) \ + $(SWRAST_SETUP_SOURCES) \ + $(COMMON_DRIVER_SOURCES) \ + $(ASM_C_SOURCES) \ + $(SLANG_SOURCES) + +MESA_ES1_GALLIUM_SOURCES := \ + $(MAIN_SOURCES) \ + $(MATH_SOURCES) \ + $(VBO_SOURCES) \ + $(STATETRACKER_SOURCES) \ + $(SHADER_SOURCES) \ + ppc/common_ppc.c \ + x86/common_x86.c \ + $(SLANG_SOURCES) + +MESA_ES1_API_SOURCES := \ + $(GLAPI_SOURCES) + +MESA_ES1_INCLUDES := $(INCLUDE_DIRS) + +# remove LOCAL sources from MESA sources +MESA_ES1_SOURCES := $(filter-out $(LOCAL_ES1_SOURCES), $(MESA_ES1_SOURCES)) +MESA_ES1_GALLIUM_SOURCES := $(filter-out $(LOCAL_ES1_GALLIUM_SOURCES), $(MESA_ES1_GALLIUM_SOURCES)) + +# right now es2 and es1 share MESA sources +MESA_ES2_SOURCES := $(MESA_ES1_SOURCES) +MESA_ES2_GALLIUM_SOURCES := $(MESA_ES1_GALLIUM_SOURCES) +MESA_ES2_API_SOURCES := $(MESA_ES1_API_SOURCES) + +MESA_ES2_INCLUDES := $(MESA_ES1_INCLUDES) + +# asm is shared by any ES version and any library +MESA_ES_ASM := $(MESA_ASM_SOURCES) + +# collect sources, adjust the pathes +ES1_SOURCES := $(LOCAL_ES1_SOURCES) $(addprefix $(MESA)/,$(MESA_ES1_SOURCES)) +ES1_GALLIUM_SOURCES := $(LOCAL_ES1_GALLIUM_SOURCES) $(addprefix $(MESA)/,$(MESA_ES1_GALLIUM_SOURCES)) +ES1_API_SOURCES := $(addprefix $(MESA)/,$(MESA_ES1_API_SOURCES)) + +ES2_SOURCES := $(LOCAL_ES2_SOURCES) $(addprefix $(MESA)/,$(MESA_ES2_SOURCES)) +ES2_GALLIUM_SOURCES := $(LOCAL_ES2_GALLIUM_SOURCES) $(addprefix $(MESA)/,$(MESA_ES2_GALLIUM_SOURCES)) +ES2_API_SOURCES := $(addprefix $(MESA)/,$(MESA_ES2_API_SOURCES)) + +# collect includes +ES1_INCLUDES := $(LOCAL_ES1_INCLUDES) $(MESA_ES1_INCLUDES) +ES2_INCLUDES := $(LOCAL_ES2_INCLUDES) $(MESA_ES2_INCLUDES) + +# collect objects, including asm +ES1_OBJECTS := \ + $(LOCAL_ES1_SOURCES:.c=.o) \ + $(MESA_ES1_SOURCES:.c=.o) \ + $(MESA_ES_ASM:.S=.o) + +ES1_GALLIUM_OBJECTS := \ + $(LOCAL_ES1_GALLIUM_SOURCES:.c=.o) \ + $(MESA_ES1_GALLIUM_SOURCES:.c=.o) \ + $(MESA_ES_ASM:.S=.o) + +ES1_API_OBJECTS := \ + $(LOCAL_ES1_API_ASM:.S=.o) \ + $(MESA_ES1_API_SOURCES:.c=.o) + +ES2_OBJECTS := \ + $(LOCAL_ES2_SOURCES:.c=.o) \ + $(MESA_ES2_SOURCES:.c=.o) \ + $(MESA_ES_ASM:.S=.o) + +ES2_GALLIUM_OBJECTS := \ + $(LOCAL_ES2_GALLIUM_SOURCES:.c=.o) \ + $(MESA_ES2_GALLIUM_SOURCES:.c=.o) \ + $(MESA_ES_ASM:.S=.o) + +ES2_API_OBJECTS := \ + $(LOCAL_ES2_API_ASM:.S=.o) \ + $(MESA_ES2_API_SOURCES:.c=.o) + +# collect sources for makedepend +ES1_ALL_SOURCES := $(ES1_SOURCES) $(ES1_GALLIUM_SOURCES) $(ES1_API_SOURCES) +ES2_ALL_SOURCES := $(ES2_SOURCES) $(ES2_GALLIUM_SOURCES) $(ES2_API_SOURCES) + +# sort to remove duplicates +ES1_ALL_SOURCES := $(sort $(ES1_ALL_SOURCES)) +ES2_ALL_SOURCES := $(sort $(ES2_ALL_SOURCES)) diff --git a/src/mesa/es/state_tracker/st_cb_drawtex.c b/src/mesa/es/state_tracker/st_cb_drawtex.c new file mode 100644 index 0000000000..0a5cba9d92 --- /dev/null +++ b/src/mesa/es/state_tracker/st_cb_drawtex.c @@ -0,0 +1,297 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + +/** + * Implementation of glDrawTex() for GL_OES_draw_tex + */ + + + +#include "main/imports.h" +#include "main/image.h" +#include "main/bufferobj.h" +#include "main/drawtex.h" +#include "main/macros.h" +#include "main/state.h" +#include "main/texformat.h" +#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" + +#include "st_context.h" +#include "st_atom.h" +#include "st_atom_constbuf.h" +#include "st_draw.h" +#include "st_cb_drawtex.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "util/u_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "util/u_tile.h" +#include "util/u_draw_quad.h" +#include "util/u_simple_shaders.h" + +#include "cso_cache/cso_context.h" + + +struct cached_shader +{ + //struct pipe_shader_state shader; + void *handle; + + uint num_attribs; + uint semantic_names[2 + MAX_TEXTURE_UNITS]; + uint semantic_indexes[2 + MAX_TEXTURE_UNITS]; +}; + +#define MAX_SHADERS (2 * MAX_TEXTURE_UNITS) + +/** + * Simple linear list cache. + * Most of the time there'll only be one cached shader. + */ +static struct cached_shader CachedShaders[MAX_SHADERS]; +static GLuint NumCachedShaders = 0; + + +#if FEATURE_OES_draw_texture + + +static void * +lookup_shader(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes) +{ + GLuint i, j; + + /* look for existing shader with same attributes */ + for (i = 0; i < NumCachedShaders; i++) { + if (CachedShaders[i].num_attribs == num_attribs) { + GLboolean match = GL_TRUE; + for (j = 0; j < num_attribs; j++) { + if (semantic_names[j] != CachedShaders[i].semantic_names[j] || + semantic_indexes[j] != CachedShaders[i].semantic_indexes[j]) { + match = GL_FALSE; + break; + } + } + if (match) + return CachedShaders[i].handle; + } + } + + /* not found - create new one now */ + if (NumCachedShaders >= MAX_SHADERS) { + return NULL; + } + + CachedShaders[i].num_attribs = num_attribs; + for (j = 0; j < num_attribs; j++) { + CachedShaders[i].semantic_names[j] = semantic_names[j]; + CachedShaders[i].semantic_indexes[j] = semantic_indexes[j]; + } + + CachedShaders[i].handle = + util_make_vertex_passthrough_shader(pipe, + num_attribs, + semantic_names, + semantic_indexes); + NumCachedShaders++; + + return CachedShaders[i].handle; +} + +static void +st_DrawTex(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, + GLfloat width, GLfloat height) +{ + struct st_context *st = ctx->st; + struct pipe_context *pipe = st->pipe; + struct cso_context *cso = ctx->st->cso_context; + struct pipe_buffer *vbuffer; + GLuint i, numTexCoords, numAttribs; + GLboolean emitColor; + uint semantic_names[2 + MAX_TEXTURE_UNITS]; + uint semantic_indexes[2 + MAX_TEXTURE_UNITS]; + GLbitfield inputs = VERT_BIT_POS; + + /* determine if we need vertex color */ + if (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_COL0) + emitColor = GL_TRUE; + else + emitColor = GL_FALSE; + + /* determine how many enabled sets of texcoords */ + numTexCoords = 0; + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_2D_BIT) { + inputs |= VERT_BIT_TEX(i); + numTexCoords++; + } + } + + /* total number of attributes per vertex */ + numAttribs = 1 + emitColor + numTexCoords; + + + /* create the vertex buffer */ + vbuffer = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX, + numAttribs * 4 * 4 * sizeof(GLfloat)); + + /* load vertex buffer */ + { +#define SET_ATTRIB(VERT, ATTR, X, Y, Z, W) \ + do { \ + GLuint k = (((VERT) * numAttribs + (ATTR)) * 4); \ + assert(k < 4 * 4 * numAttribs); \ + vbuf[k + 0] = X; \ + vbuf[k + 1] = Y; \ + vbuf[k + 2] = Z; \ + vbuf[k + 3] = W; \ + } while (0) + + const GLfloat x0 = x, y0 = y, x1 = x + width, y1 = y + height; + GLfloat *vbuf = (GLfloat *) pipe_buffer_map(pipe->screen, vbuffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + GLuint attr; + + z = CLAMP(z, 0.0f, 1.0f); + + /* positions (in clip coords) */ + { + const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const GLfloat fb_width = (GLfloat)fb->Width; + const GLfloat fb_height = (GLfloat)fb->Height; + + const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0); + const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0); + const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0); + const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0); + + SET_ATTRIB(0, 0, clip_x0, clip_y0, z, 1.0f); /* lower left */ + SET_ATTRIB(1, 0, clip_x1, clip_y0, z, 1.0f); /* lower right */ + SET_ATTRIB(2, 0, clip_x1, clip_y1, z, 1.0f); /* upper right */ + SET_ATTRIB(3, 0, clip_x0, clip_y1, z, 1.0f); /* upper left */ + + semantic_names[0] = TGSI_SEMANTIC_POSITION; + semantic_indexes[0] = 0; + } + + /* colors */ + if (emitColor) { + const GLfloat *c = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; + SET_ATTRIB(0, 1, c[0], c[1], c[2], c[3]); + SET_ATTRIB(1, 1, c[0], c[1], c[2], c[3]); + SET_ATTRIB(2, 1, c[0], c[1], c[2], c[3]); + SET_ATTRIB(3, 1, c[0], c[1], c[2], c[3]); + semantic_names[1] = TGSI_SEMANTIC_COLOR; + semantic_indexes[1] = 0; + attr = 2; + } + else { + attr = 1; + } + + /* texcoords */ + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled & TEXTURE_2D_BIT) { + struct gl_texture_object *obj = ctx->Texture.Unit[i]._Current; + struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + const GLfloat wt = (GLfloat) img->Width; + const GLfloat ht = (GLfloat) img->Height; + const GLfloat s0 = obj->CropRect[0] / wt; + const GLfloat t0 = obj->CropRect[1] / ht; + const GLfloat s1 = (obj->CropRect[0] + obj->CropRect[2]) / wt; + const GLfloat t1 = (obj->CropRect[1] + obj->CropRect[3]) / ht; + + /*printf("crop texcoords: %g, %g .. %g, %g\n", s0, t0, s1, t1);*/ + SET_ATTRIB(0, attr, s0, t0, 0.0f, 1.0f); /* lower left */ + SET_ATTRIB(1, attr, s1, t0, 0.0f, 1.0f); /* lower right */ + SET_ATTRIB(2, attr, s1, t1, 0.0f, 1.0f); /* upper right */ + SET_ATTRIB(3, attr, s0, t1, 0.0f, 1.0f); /* upper left */ + + semantic_names[attr] = TGSI_SEMANTIC_GENERIC; + semantic_indexes[attr] = 0; + + attr++; + } + } + + pipe_buffer_unmap(pipe->screen, vbuffer); + +#undef SET_ATTRIB + } + + + cso_save_viewport(cso); + cso_save_vertex_shader(cso); + + { + void *vs = lookup_shader(pipe, numAttribs, + semantic_names, semantic_indexes); + cso_set_vertex_shader_handle(cso, vs); + } + + /* viewport state: viewport matching window dims */ + { + const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + const GLfloat width = (GLfloat)fb->Width; + const GLfloat height = (GLfloat)fb->Height; + struct pipe_viewport_state vp; + vp.scale[0] = 0.5f * width; + vp.scale[1] = height * (invert ? -0.5f : 0.5f); + vp.scale[2] = 1.0f; + vp.scale[3] = 1.0f; + vp.translate[0] = 0.5f * width; + vp.translate[1] = 0.5f * height; + vp.translate[2] = 0.0f; + vp.translate[3] = 0.0f; + cso_set_viewport(cso, &vp); + } + + + util_draw_vertex_buffer(pipe, vbuffer, + 0, /* offset */ + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + numAttribs); /* attribs/vert */ + + + pipe_buffer_reference(&vbuffer, NULL); + + /* restore state */ + cso_restore_viewport(cso); + cso_restore_vertex_shader(cso); +} + + +#endif /* FEATURE_OES_draw_texture */ + + +void +st_init_drawtex_functions(struct dd_function_table *functions) +{ + _MESA_INIT_DRAWTEX_FUNCTIONS(functions, st_); +} + + +/** + * Free any cached shaders + */ +void +st_destroy_drawtex(struct st_context *st) +{ + GLuint i; + for (i = 0; i < NumCachedShaders; i++) { + cso_delete_vertex_shader(st->cso_context, CachedShaders[i].handle); + } + NumCachedShaders = 0; +} diff --git a/src/mesa/es/state_tracker/st_cb_drawtex.h b/src/mesa/es/state_tracker/st_cb_drawtex.h new file mode 100644 index 0000000000..7b0da70279 --- /dev/null +++ b/src/mesa/es/state_tracker/st_cb_drawtex.h @@ -0,0 +1,18 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + **************************************************************************/ + + +#ifndef ST_CB_DRAWTEX_H +#define ST_CB_DRAWTEX_H + +extern void +st_init_drawtex_functions(struct dd_function_table *functions); + +extern void +st_destroy_drawtex(struct st_context *st); + +#endif /* ST_CB_DRAWTEX_H */ diff --git a/src/mesa/glapi/Makefile b/src/mesa/glapi/Makefile index 4db0ff1425..da679607d7 100644 --- a/src/mesa/glapi/Makefile +++ b/src/mesa/glapi/Makefile @@ -13,11 +13,11 @@ OUTPUTS = glprocs.h glapitemp.h glapioffsets.h glapitable.h glapidispatch.h \ ../x86/glapi_x86.S \ ../x86-64/glapi_x86-64.S \ ../sparc/glapi_sparc.S \ - ../../glx/x11/indirect.c \ - ../../glx/x11/indirect.h \ - ../../glx/x11/indirect_init.c \ - ../../glx/x11/indirect_size.h \ - ../../glx/x11/indirect_size.c + ../../glx/indirect.c \ + ../../glx/indirect.h \ + ../../glx/indirect_init.c \ + ../../glx/indirect_size.h \ + ../../glx/indirect_size.c GLX_DIR = $(XORG_BASE)/glx @@ -25,6 +25,7 @@ GLX_DIR = $(XORG_BASE)/glx SERVER_GLAPI_FILES = \ $(GLX_DIR)/glapi.h \ $(GLX_DIR)/glapi.c \ + $(GLX_DIR)/glapi_nop.c \ $(GLX_DIR)/glthread.c \ $(GLX_DIR)/glthread.h @@ -43,7 +44,6 @@ SERVER_OUTPUTS = \ $(GLX_DIR)/glapioffsets.h \ $(GLX_DIR)/glapidispatch.h \ $(GLX_DIR)/glprocs.h \ - $(GLX_DIR)/dispatch.h \ $(SERVER_GLAPI_FILES) API_XML = gl_API.xml \ @@ -110,20 +110,20 @@ glapidispatch.h $(GLX_DIR)/glapidispatch.h: gl_table.py $(COMMON) ../sparc/glapi_sparc.S: gl_SPARC_asm.py $(COMMON) $(PYTHON2) $(PYTHON_FLAGS) $< > $@ -../../glx/x11/indirect.c: glX_proto_send.py $(COMMON_GLX) +../../glx/indirect.c: glX_proto_send.py $(COMMON_GLX) $(PYTHON2) $(PYTHON_FLAGS) $< -m proto | $(INDENT) $(INDENT_FLAGS) > $@ -../../glx/x11/indirect.h: glX_proto_send.py $(COMMON_GLX) +../../glx/indirect.h: glX_proto_send.py $(COMMON_GLX) $(PYTHON2) $(PYTHON_FLAGS) $< -m init_h > $@ -../../glx/x11/indirect_init.c: glX_proto_send.py $(COMMON_GLX) +../../glx/indirect_init.c: glX_proto_send.py $(COMMON_GLX) $(PYTHON2) $(PYTHON_FLAGS) $< -m init_c > $@ -../../glx/x11/indirect_size.h $(GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX) +../../glx/indirect_size.h $(GLX_DIR)/indirect_size.h: glX_proto_size.py $(COMMON_GLX) $(PYTHON2) $(PYTHON_FLAGS) $< -m size_h --only-set -h _INDIRECT_SIZE_H_ \ | $(INDENT) $(INDENT_FLAGS) > $@ -../../glx/x11/indirect_size.c: glX_proto_size.py $(COMMON_GLX) +../../glx/indirect_size.c: glX_proto_size.py $(COMMON_GLX) $(PYTHON2) $(PYTHON_FLAGS) $< -m size_c --only-set \ | $(INDENT) $(INDENT_FLAGS) > $@ diff --git a/src/mesa/glapi/dispatch.h b/src/mesa/glapi/dispatch.h index 6623d52469..27f80a5062 100644 --- a/src/mesa/glapi/dispatch.h +++ b/src/mesa/glapi/dispatch.h @@ -30,8 +30,8 @@ #define _GLAPI_USE_REMAP_TABLE #endif -#include "glapitable.h" -#include "glapioffsets.h" -#include "glapidispatch.h" +#include "glapi/glapitable.h" +#include "glapi/glapioffsets.h" +#include "glapi/glapidispatch.h" #endif /* _DISPATCH_H */ diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 75d2f3c438..fbf8b0c3e4 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -866,6 +866,9 @@ <enum name="4_BYTES" count="4" value="0x1409"> <size name="CallLists"/> </enum> + <enum name="HALF_FLOAT" count="2" value="0x140B"> + <size name="CallLists"/> + </enum> <enum name="CLEAR" value="0x1500"/> <enum name="AND" value="0x1501"/> <enum name="AND_REVERSE" value="0x1502"/> diff --git a/src/mesa/glapi/gl_XML.py b/src/mesa/glapi/gl_XML.py index b98919134f..a10a35e513 100644 --- a/src/mesa/glapi/gl_XML.py +++ b/src/mesa/glapi/gl_XML.py @@ -184,7 +184,7 @@ class gl_print_base: The name is also added to the file's undef_list. """ self.undef_list.append("PURE") - print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) + print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PURE __attribute__((pure)) # else # define PURE @@ -224,7 +224,7 @@ class gl_print_base: """ self.undef_list.append(S) - print """# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) + print """# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined(__ELF__) # define %s __attribute__((visibility("%s"))) # else # define %s @@ -244,7 +244,7 @@ class gl_print_base: """ self.undef_list.append("NOINLINE") - print """# if defined(__GNUC__) + print """# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define NOINLINE __attribute__((noinline)) # else # define NOINLINE @@ -738,6 +738,9 @@ class gl_function( gl_item ): return p_string + def is_abi(self): + return (self.offset >= 0 and not self.assign_offset) + def is_static_entry_point(self, name): return name in self.static_entry_points diff --git a/src/mesa/glapi/gl_apitemp.py b/src/mesa/glapi/gl_apitemp.py index a37c08d6ce..41a40fbeb6 100644 --- a/src/mesa/glapi/gl_apitemp.py +++ b/src/mesa/glapi/gl_apitemp.py @@ -30,7 +30,7 @@ import license import sys, getopt class PrintGlOffsets(gl_XML.gl_print_base): - def __init__(self): + def __init__(self, es=False): gl_XML.gl_print_base.__init__(self) self.name = "gl_apitemp.py (from Mesa)" @@ -38,6 +38,8 @@ class PrintGlOffsets(gl_XML.gl_print_base): """Copyright (C) 1999-2001 Brian Paul All Rights Reserved. (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + self.es = es + self.undef_list.append( "KEYWORD1" ) self.undef_list.append( "KEYWORD1_ALT" ) self.undef_list.append( "KEYWORD2" ) @@ -82,10 +84,14 @@ class PrintGlOffsets(gl_XML.gl_print_base): else: dispatch = "DISPATCH" - if f.has_different_protocol(name): - print '#ifndef GLX_INDIRECT_RENDERING' - + need_proto = False if not f.is_static_entry_point(name): + need_proto = True + elif self.es: + cat, num = api.get_category_for_name(name) + if (cat.startswith("es") or cat.startswith("GL_OES")): + need_proto = True + if need_proto: print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name)) print '' @@ -98,8 +104,6 @@ class PrintGlOffsets(gl_XML.gl_print_base): print ' %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \ % (dispatch, f.name, p_string, name, t_string, o_string) print '}' - if f.has_different_protocol(name): - print '#endif /* GLX_INDIRECT_RENDERING */' print '' return @@ -172,7 +176,11 @@ class PrintGlOffsets(gl_XML.gl_print_base): #error TABLE_ENTRY must be defined #endif -static _glapi_proc DISPATCH_TABLE_NAME[] = {""" +#ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS +#error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined +#endif + +_glapi_proc DISPATCH_TABLE_NAME[] = {""" for f in api.functionIterateByOffset(): print ' TABLE_ENTRY(%s),' % (f.dispatch_name()) @@ -196,35 +204,90 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {""" * We list the functions which are not otherwise used. */ #ifdef UNUSED_TABLE_NAME -static _glapi_proc UNUSED_TABLE_NAME[] = {""" +_glapi_proc UNUSED_TABLE_NAME[] = {""" + normal_entries = [] + proto_entries = [] for f in api.functionIterateByOffset(): - for n in f.entry_points: - if n != f.name: - if f.is_static_entry_point(n): - text = ' TABLE_ENTRY(%s),' % (n) - - if f.has_different_protocol(n): - print '#ifndef GLX_INDIRECT_RENDERING' - print text - print '#endif' - else: - print text + normal_ents, proto_ents = self.classifyEntryPoints(f) + + # exclude f.name + if f.name in normal_ents: + normal_ents.remove(f.name) + elif f.name in proto_ents: + proto_ents.remove(f.name) + + normal_ents = [f.static_name(ent) for ent in normal_ents] + proto_ents = [f.static_name(ent) for ent in proto_ents] + + normal_entries.extend(normal_ents) + proto_entries.extend(proto_ents) + + print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' + for ent in normal_entries: + print ' TABLE_ENTRY(%s),' % (ent) + print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' + print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' + for ent in proto_entries: + print ' TABLE_ENTRY(%s),' % (ent) + print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' + print '};' print '#endif /*UNUSED_TABLE_NAME*/' print '' return + def classifyEntryPoints(self, func): + normal_names = [] + normal_stubs = [] + proto_names = [] + proto_stubs = [] + # classify the entry points + for name in func.entry_points: + if func.has_different_protocol(name): + if func.is_static_entry_point(name): + proto_names.append(name) + else: + proto_stubs.append(name) + else: + if func.is_static_entry_point(name): + normal_names.append(name) + else: + normal_stubs.append(name) + # there can be at most one stub for a function + if normal_stubs: + normal_names.append(normal_stubs[0]) + elif proto_stubs: + proto_names.append(proto_stubs[0]) + + return (normal_names, proto_names) + def printBody(self, api): + normal_entry_points = [] + proto_entry_points = [] for func in api.functionIterateByOffset(): - got_stub = 0 - for n in func.entry_points: - if func.is_static_entry_point(n): - self.printFunction(func, n) - elif not got_stub: - self.printFunction(func, n) - got_stub = 1 + normal_ents, proto_ents = self.classifyEntryPoints(func) + normal_entry_points.append((func, normal_ents)) + proto_entry_points.append((func, proto_ents)) + + print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS' + print '' + for func, ents in normal_entry_points: + for ent in ents: + self.printFunction(func, ent) + print '' + print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */' + print '' + print '/* these entry points might require different protocols */' + print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS' + print '' + for func, ents in proto_entry_points: + for ent in ents: + self.printFunction(func, ent) + print '' + print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */' + print '' self.printInitDispatch(api) self.printAliasedTable(api) @@ -232,22 +295,26 @@ static _glapi_proc UNUSED_TABLE_NAME[] = {""" def show_usage(): - print "Usage: %s [-f input_file_name]" % sys.argv[0] + print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0] + print "-c Enable compatibility with OpenGL ES." sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: - (args, trail) = getopt.getopt(sys.argv[1:], "f:") + (args, trail) = getopt.getopt(sys.argv[1:], "f:c") except Exception,e: show_usage() + es = False for (arg,val) in args: if arg == "-f": file_name = val + elif arg == "-c": + es = True api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) - printer = PrintGlOffsets() + printer = PrintGlOffsets(es) printer.Print(api) diff --git a/src/mesa/glapi/gl_enums.py b/src/mesa/glapi/gl_enums.py index 27ab119537..acaa06ab37 100644 --- a/src/mesa/glapi/gl_enums.py +++ b/src/mesa/glapi/gl_enums.py @@ -42,10 +42,10 @@ class PrintGlEnums(gl_XML.gl_print_base): def printRealHeader(self): - print '#include "glheader.h"' - print '#include "mfeatures.h"' - print '#include "enums.h"' - print '#include "imports.h"' + print '#include "main/glheader.h"' + print '#include "main/mfeatures.h"' + print '#include "main/enums.h"' + print '#include "main/imports.h"' print '' print 'typedef struct {' print ' size_t offset;' diff --git a/src/mesa/glapi/gl_offsets.py b/src/mesa/glapi/gl_offsets.py index ca6c90ffd8..54867b3463 100644 --- a/src/mesa/glapi/gl_offsets.py +++ b/src/mesa/glapi/gl_offsets.py @@ -30,9 +30,10 @@ import license import sys, getopt class PrintGlOffsets(gl_XML.gl_print_base): - def __init__(self): + def __init__(self, es=False): gl_XML.gl_print_base.__init__(self) + self.es = es self.name = "gl_offsets.py (from Mesa)" self.header_tag = '_GLAPI_OFFSETS_H_' self.license = license.bsd_license_template % ( \ @@ -41,22 +42,24 @@ class PrintGlOffsets(gl_XML.gl_print_base): return def printBody(self, api): - abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] - print '/* this file should not be included directly in mesa */' print '' functions = [] abi_functions = [] + alias_functions = [] count = 0 for f in api.functionIterateByOffset(): - [category, num] = api.get_category_for_name( f.name ) - if category not in abi: + if not f.is_abi(): functions.append( [f, count] ) count += 1 else: abi_functions.append( f ) + if self.es: + # remember functions with aliases + if len(f.entry_points) > 1: + alias_functions.append(f) for f in abi_functions: print '#define _gloffset_%s %d' % (f.name, f.offset) @@ -81,26 +84,37 @@ class PrintGlOffsets(gl_XML.gl_print_base): print '' print '#endif /* !defined(_GLAPI_USE_REMAP_TABLE) */' + if alias_functions: + print '' + print '/* define aliases for compatibility */' + for f in alias_functions: + for name in f.entry_points: + if name != f.name: + print '#define _gloffset_%s _gloffset_%s' % (name, f.name) return def show_usage(): - print "Usage: %s [-f input_file_name]" % sys.argv[0] + print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0] + print " -c Enable compatibility with OpenGL ES." sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: - (args, trail) = getopt.getopt(sys.argv[1:], "f:") + (args, trail) = getopt.getopt(sys.argv[1:], "f:c") except Exception,e: show_usage() + es = False for (arg,val) in args: if arg == "-f": file_name = val + elif arg == "-c": + es = True api = gl_XML.parse_GL_API( file_name ) - printer = PrintGlOffsets() + printer = PrintGlOffsets(es) printer.Print( api ) diff --git a/src/mesa/glapi/gl_procs.py b/src/mesa/glapi/gl_procs.py index cd1a68cee1..5de61fbdfe 100644 --- a/src/mesa/glapi/gl_procs.py +++ b/src/mesa/glapi/gl_procs.py @@ -30,9 +30,10 @@ import gl_XML, glX_XML import sys, getopt class PrintGlProcs(gl_XML.gl_print_base): - def __init__(self, long_strings): + def __init__(self, long_strings, es=False): gl_XML.gl_print_base.__init__(self) + self.es = es self.long_strings = long_strings self.name = "gl_procs.py (from Mesa)" self.license = license.bsd_license_template % ( \ @@ -141,6 +142,28 @@ typedef struct { print '%s GLAPIENTRY gl_dispatch_stub_%u(%s);' % (func.return_type, func.offset, func.get_parameter_string()) break + if self.es: + categories = {} + for func in api.functionIterateByOffset(): + for n in func.entry_points: + cat, num = api.get_category_for_name(n) + if (cat.startswith("es") or cat.startswith("GL_OES")): + if not categories.has_key(cat): + categories[cat] = [] + proto = 'GLAPI %s GLAPIENTRY %s(%s);' \ + % (func.return_type, "gl" + n, func.get_parameter_string(n)) + categories[cat].append(proto) + if categories: + print '' + print '/* OpenGL ES specific prototypes */' + print '' + keys = categories.keys() + keys.sort() + for key in keys: + print '/* category %s */' % key + print "\n".join(categories[key]) + print '' + print '#endif /* defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) */' print '' @@ -155,8 +178,9 @@ typedef struct { def show_usage(): - print "Usage: %s [-f input_file_name] [-m mode]" % sys.argv[0] - print "mode can be one of:" + print "Usage: %s [-f input_file_name] [-m mode] [-c]" % sys.argv[0] + print "-c Enable compatibility with OpenGL ES." + print "-m mode mode can be one of:" print " long - Create code for compilers that can handle very" print " long string constants. (default)" print " short - Create code for compilers that can only handle" @@ -167,11 +191,12 @@ if __name__ == '__main__': file_name = "gl_API.xml" try: - (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:c") except Exception,e: show_usage() long_string = 1 + es = False for (arg,val) in args: if arg == "-f": file_name = val @@ -182,7 +207,9 @@ if __name__ == '__main__': long_string = 1 else: show_usage() + elif arg == "-c": + es = True api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory()) - printer = PrintGlProcs(long_string) + printer = PrintGlProcs(long_string, es) printer.Print(api) diff --git a/src/mesa/glapi/gl_table.py b/src/mesa/glapi/gl_table.py index 0e05b3431a..3bd7569e92 100644 --- a/src/mesa/glapi/gl_table.py +++ b/src/mesa/glapi/gl_table.py @@ -30,9 +30,10 @@ import license import sys, getopt class PrintGlTable(gl_XML.gl_print_base): - def __init__(self): + def __init__(self, es=False): gl_XML.gl_print_base.__init__(self) + self.es = es self.header_tag = '_GLAPI_TABLE_H_' self.name = "gl_table.py (from Mesa)" self.license = license.bsd_license_template % ( \ @@ -68,9 +69,10 @@ class PrintGlTable(gl_XML.gl_print_base): class PrintRemapTable(gl_XML.gl_print_base): - def __init__(self): + def __init__(self, es=False): gl_XML.gl_print_base.__init__(self) + self.es = es self.header_tag = '_GLAPI_DISPATCH_H_' self.name = "gl_table.py (from Mesa)" self.license = license.bsd_license_template % ("(C) Copyright IBM Corporation 2005", "IBM") @@ -113,19 +115,22 @@ class PrintRemapTable(gl_XML.gl_print_base): print ' } while(0)' print '' - abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] - functions = [] abi_functions = [] + alias_functions = [] count = 0 for f in api.functionIterateByOffset(): - [category, num] = api.get_category_for_name( f.name ) - if category not in abi: + if not f.is_abi(): functions.append( [f, count] ) count += 1 else: abi_functions.append( f ) + if self.es: + # remember functions with aliases + if len(f.entry_points) > 1: + alias_functions.append(f) + for f in abi_functions: print '#define CALL_%s(disp, parameters) (*((disp)->%s)) parameters' % (f.name, f.name) @@ -165,33 +170,57 @@ class PrintRemapTable(gl_XML.gl_print_base): print '' print '#endif /* !defined(_GLAPI_USE_REMAP_TABLE) */' + + if alias_functions: + print '' + print '/* define aliases for compatibility */' + for f in alias_functions: + for name in f.entry_points: + if name != f.name: + print '#define CALL_%s(disp, parameters) CALL_%s(disp, parameters)' % (name, f.name) + print '#define GET_%s(disp) GET_%s(disp)' % (name, f.name) + print '#define SET_%s(disp, fn) SET_%s(disp, fn)' % (name, f.name) + print '' + + print '#if defined(_GLAPI_USE_REMAP_TABLE)' + for f in alias_functions: + for name in f.entry_points: + if name != f.name: + print '#define %s_remap_index %s_remap_index' % (name, f.name) + print '#endif /* defined(_GLAPI_USE_REMAP_TABLE) */' + print '' + return def show_usage(): - print "Usage: %s [-f input_file_name] [-m mode]" % sys.argv[0] + print "Usage: %s [-f input_file_name] [-m mode] [-c]" % sys.argv[0] print " -m mode Mode can be 'table' or 'remap_table'." + print " -c Enable compatibility with OpenGL ES." sys.exit(1) if __name__ == '__main__': file_name = "gl_API.xml" try: - (args, trail) = getopt.getopt(sys.argv[1:], "f:m:") + (args, trail) = getopt.getopt(sys.argv[1:], "f:m:c") except Exception,e: show_usage() mode = "table" + es = False for (arg,val) in args: if arg == "-f": file_name = val elif arg == "-m": mode = val + elif arg == "-c": + es = True if mode == "table": - printer = PrintGlTable() + printer = PrintGlTable(es) elif mode == "remap_table": - printer = PrintRemapTable() + printer = PrintRemapTable(es) else: show_usage() diff --git a/src/mesa/glapi/gl_x86-64_asm.py b/src/mesa/glapi/gl_x86-64_asm.py index f36ad3a5d8..31c1a2b93a 100644 --- a/src/mesa/glapi/gl_x86-64_asm.py +++ b/src/mesa/glapi/gl_x86-64_asm.py @@ -122,7 +122,7 @@ class PrintGenericStubs(gl_XML.gl_print_base): print " * the symbol visibility mode to 'default'." print ' */' print '' - print '#include "../x86/assyntax.h"' + print '#include "x86/assyntax.h"' print '' print '#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303' print '# pragma GCC visibility push(default)' diff --git a/src/mesa/glapi/gl_x86_asm.py b/src/mesa/glapi/gl_x86_asm.py index 36f0e31fe2..d210f3a248 100644 --- a/src/mesa/glapi/gl_x86_asm.py +++ b/src/mesa/glapi/gl_x86_asm.py @@ -53,7 +53,7 @@ class PrintGenericStubs(gl_XML.gl_print_base): def printRealHeader(self): - print '#include "assyntax.h"' + print '#include "x86/assyntax.h"' print '#include "glapi/glapioffsets.h"' print '' print '#if defined(STDCALL_API)' @@ -73,7 +73,7 @@ class PrintGenericStubs(gl_XML.gl_print_base): print '' print '#define GL_OFFSET(x) CODEPTR(REGOFF(4 * x, EAX))' print '' - print '#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__)' + print '#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__)' print '#define GLOBL_FN(x) GLOBL x ; .type x, function' print '#else' print '#define GLOBL_FN(x) GLOBL x' diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c index 84e5a8270a..469523d57c 100644 --- a/src/mesa/glapi/glapi.c +++ b/src/mesa/glapi/glapi.c @@ -69,89 +69,11 @@ #include <assert.h> #endif -#include "glapi.h" -#include "glapioffsets.h" -#include "glapitable.h" - -/***** BEGIN NO-OP DISPATCH *****/ - -static GLboolean WarnFlag = GL_FALSE; -static _glapi_warning_func warning_func; - -/* - * Enable/disable printing of warning messages. - */ -PUBLIC void -_glapi_noop_enable_warnings(GLboolean enable) -{ - WarnFlag = enable; -} - -/* - * Register a callback function for reporting errors. - */ -PUBLIC void -_glapi_set_warning_func( _glapi_warning_func func ) -{ - warning_func = func; -} - -static int -warn(const char *func) -{ -#if !defined(_WIN32_WCE) - if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) - && warning_func) { - warning_func(NULL, "GL User Error: called without context: %s", func); - } -#endif - return 0; -} - -#ifdef DEBUG - -#define KEYWORD1 static -#define KEYWORD1_ALT static -#define KEYWORD2 GLAPIENTRY -#define NAME(func) NoOp##func - -#define F NULL - -#define DISPATCH(func, args, msg) \ - warn(#func); - -#define RETURN_DISPATCH(func, args, msg) \ - return warn(#func); - -#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name - -#else - -static void -NoOpGeneric(void) -{ - if ((WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) - && warning_func) { - warning_func(NULL, "GL User Error: calling GL function"); - } -} - -#define TABLE_ENTRY(name) (_glapi_proc) NoOpGeneric - -#endif - -#define DISPATCH_TABLE_NAME __glapi_noop_table -#define UNUSED_TABLE_NAME __unused_noop_functions - -static GLint NoOpUnused(void) -{ - return warn("extension function"); -} - -#include "glapitemp.h" - -/***** END NO-OP DISPATCH *****/ +#include "glapi/glapi.h" +#include "glapi/glapioffsets.h" +#include "glapi/glapitable.h" +extern _glapi_proc __glapi_noop_table[]; /** @@ -278,7 +200,6 @@ _glapi_check_multithread(void) PUBLIC void _glapi_set_context(void *context) { - (void) __unused_noop_functions; /* silence a warning */ #if defined(GLX_USE_TLS) _glapi_tls_Context = context; #elif defined(THREADS) diff --git a/src/mesa/glapi/glapi.h b/src/mesa/glapi/glapi.h index 5fb5401229..47ea23e92b 100644 --- a/src/mesa/glapi/glapi.h +++ b/src/mesa/glapi/glapi.h @@ -55,8 +55,6 @@ struct _glapi_table; typedef void (*_glapi_proc)(void); /* generic function pointer */ -typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); - #if defined(USE_MGL_NAMESPACE) #define _glapi_set_dispatch _mglapi_set_dispatch @@ -107,12 +105,6 @@ extern struct _glapi_table *_glapi_Dispatch; **/ extern void -_glapi_noop_enable_warnings(GLboolean enable); - -extern void -_glapi_set_warning_func(_glapi_warning_func func); - -extern void _glapi_check_multithread(void); diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c index 1401c1cb58..eecfb9c1ae 100644 --- a/src/mesa/glapi/glapi_getproc.c +++ b/src/mesa/glapi/glapi_getproc.c @@ -34,9 +34,9 @@ #include <string.h> #include "main/glheader.h" #include "main/compiler.h" -#include "glapi.h" -#include "glapioffsets.h" -#include "glapitable.h" +#include "glapi/glapi.h" +#include "glapi/glapioffsets.h" +#include "glapi/glapitable.h" static void @@ -75,7 +75,7 @@ str_dup(const char *str) #endif /* The code in this file is auto-generated with Python */ -#include "glprocs.h" +#include "glapi/glprocs.h" /** diff --git a/src/mesa/glapi/glapi_nop.c b/src/mesa/glapi/glapi_nop.c new file mode 100644 index 0000000000..aa84b9a169 --- /dev/null +++ b/src/mesa/glapi/glapi_nop.c @@ -0,0 +1,107 @@ +/* + * Mesa 3-D graphics library + * Version: 7.8 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2010 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 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. + */ + + +/** + * No-op dispatch table. + * + * This file defines a special dispatch table which is loaded with no-op + * functions. + * + * When there's no current rendering context, calling a GL function like + * glBegin() is a no-op. Apps should never normally do this. So as a + * debugging aid, each of the no-op functions will emit a warning to + * stderr if the MESA_DEBUG or LIBGL_DEBUG env var is set. + */ + + + +#include "main/compiler.h" +#include "main/glheader.h" +#include "glapi/glapi.h" + +#ifdef DEBUG + +/** + * Called by each of the no-op GL entrypoints. + */ +static int +Warn(const char *func) +{ +#if !defined(_WIN32_WCE) + if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { + fprintf(stderr, "GL User Error: gl%s called without a rendering context\n", + func); + } +#endif + return 0; +} + + +/** + * This is called if the user somehow calls an unassigned GL dispatch function. + */ +static GLint +NoOpUnused(void) +{ + return Warn(" function"); +} + +/* + * Defines for the glapitemp.h functions. + */ +#define KEYWORD1 static +#define KEYWORD1_ALT static +#define KEYWORD2 GLAPIENTRY +#define NAME(func) NoOp##func +#define DISPATCH(func, args, msg) Warn(#func); +#define RETURN_DISPATCH(func, args, msg) Warn(#func); return 0 + + +/* + * Defines for the table of no-op entry points. + */ +#define TABLE_ENTRY(name) (_glapi_proc) NoOp##name + +#else + +static void +NoOpGeneric(void) +{ +#if !defined(_WIN32_WCE) + if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { + fprintf(stderr, "GL User Error: calling GL function without a rendering context\n"); + } +#endif +} + +#define TABLE_ENTRY(name) (_glapi_proc) NoOpGeneric + +#endif + +#define DISPATCH_TABLE_NAME __glapi_noop_table +#define UNUSED_TABLE_NAME __unused_noop_functions + +#include "glapi/glapitemp.h" diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h index 96b2ac7268..2540ef6465 100644 --- a/src/mesa/glapi/glapitemp.h +++ b/src/mesa/glapi/glapitemp.h @@ -27,7 +27,7 @@ */ -# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(__ELF__) +# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined(__ELF__) # define HIDDEN __attribute__((visibility("hidden"))) # else # define HIDDEN @@ -80,6 +80,8 @@ #endif +#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS + KEYWORD1 void KEYWORD2 NAME(NewList)(GLuint list, GLenum mode) { DISPATCH(NewList, (list, mode), (F, "glNewList(%d, 0x%x);\n", list, mode)); @@ -1710,13 +1712,6 @@ KEYWORD1 GLboolean KEYWORD2 NAME(AreTexturesResident)(GLsizei n, const GLuint * RETURN_DISPATCH(AreTexturesResident, (n, textures, residences), (F, "glAreTexturesResident(%d, %p, %p);\n", n, (const void *) textures, (const void *) residences)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 GLboolean KEYWORD2 NAME(AreTexturesResidentEXT)(GLsizei n, const GLuint * textures, GLboolean * residences) -{ - RETURN_DISPATCH(AreTexturesResident, (n, textures, residences), (F, "glAreTexturesResidentEXT(%d, %p, %p);\n", n, (const void *) textures, (const void *) residences)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { DISPATCH(CopyTexImage1D, (target, level, internalformat, x, y, width, border), (F, "glCopyTexImage1D(0x%x, %d, 0x%x, %d, %d, %d, %d);\n", target, level, internalformat, x, y, width, border)); @@ -1762,25 +1757,11 @@ KEYWORD1 void KEYWORD2 NAME(DeleteTextures)(GLsizei n, const GLuint * textures) DISPATCH(DeleteTextures, (n, textures), (F, "glDeleteTextures(%d, %p);\n", n, (const void *) textures)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 void KEYWORD2 NAME(DeleteTexturesEXT)(GLsizei n, const GLuint * textures) -{ - DISPATCH(DeleteTextures, (n, textures), (F, "glDeleteTexturesEXT(%d, %p);\n", n, (const void *) textures)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GenTextures)(GLsizei n, GLuint * textures) { DISPATCH(GenTextures, (n, textures), (F, "glGenTextures(%d, %p);\n", n, (const void *) textures)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 void KEYWORD2 NAME(GenTexturesEXT)(GLsizei n, GLuint * textures) -{ - DISPATCH(GenTextures, (n, textures), (F, "glGenTexturesEXT(%d, %p);\n", n, (const void *) textures)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetPointerv)(GLenum pname, GLvoid ** params) { DISPATCH(GetPointerv, (pname, params), (F, "glGetPointerv(0x%x, %p);\n", pname, (const void *) params)); @@ -1796,13 +1777,6 @@ KEYWORD1 GLboolean KEYWORD2 NAME(IsTexture)(GLuint texture) RETURN_DISPATCH(IsTexture, (texture), (F, "glIsTexture(%d);\n", texture)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 GLboolean KEYWORD2 NAME(IsTextureEXT)(GLuint texture) -{ - RETURN_DISPATCH(IsTexture, (texture), (F, "glIsTextureEXT(%d);\n", texture)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(PrioritizeTextures)(GLsizei n, const GLuint * textures, const GLclampf * priorities) { DISPATCH(PrioritizeTextures, (n, textures, priorities), (F, "glPrioritizeTextures(%d, %p, %p);\n", n, (const void *) textures, (const void *) priorities)); @@ -1878,6 +1852,11 @@ KEYWORD1 void KEYWORD2 NAME(ColorTable)(GLenum target, GLenum internalformat, GL DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, "glColorTable(0x%x, 0x%x, %d, 0x%x, 0x%x, %p);\n", target, internalformat, width, format, type, (const void *) table)); } +KEYWORD1 void KEYWORD2 NAME(ColorTableEXT)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) +{ + DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, "glColorTableEXT(0x%x, 0x%x, %d, 0x%x, 0x%x, %p);\n", target, internalformat, width, format, type, (const void *) table)); +} + KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_339)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table); KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_339)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) @@ -1885,11 +1864,6 @@ KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_339)(GLenum target, GLenum intern DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, "glColorTableSGI(0x%x, 0x%x, %d, 0x%x, 0x%x, %p);\n", target, internalformat, width, format, type, (const void *) table)); } -KEYWORD1 void KEYWORD2 NAME(ColorTableEXT)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) -{ - DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, "glColorTableEXT(0x%x, 0x%x, %d, 0x%x, 0x%x, %p);\n", target, internalformat, width, format, type, (const void *) table)); -} - KEYWORD1 void KEYWORD2 NAME(ColorTableParameterfv)(GLenum target, GLenum pname, const GLfloat * params) { DISPATCH(ColorTableParameterfv, (target, pname, params), (F, "glColorTableParameterfv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); @@ -1931,64 +1905,16 @@ KEYWORD1 void KEYWORD2 NAME(GetColorTable)(GLenum target, GLenum format, GLenum DISPATCH(GetColorTable, (target, format, type, table), (F, "glGetColorTable(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) table)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_343)(GLenum target, GLenum format, GLenum type, GLvoid * table); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_343)(GLenum target, GLenum format, GLenum type, GLvoid * table) -{ - DISPATCH(GetColorTable, (target, format, type, table), (F, "glGetColorTableSGI(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) table)); -} -#endif /* GLX_INDIRECT_RENDERING */ - -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 void KEYWORD2 NAME(GetColorTableEXT)(GLenum target, GLenum format, GLenum type, GLvoid * table) -{ - DISPATCH(GetColorTable, (target, format, type, table), (F, "glGetColorTableEXT(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) table)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfv)(GLenum target, GLenum pname, GLfloat * params) { DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, "glGetColorTableParameterfv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_344)(GLenum target, GLenum pname, GLfloat * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_344)(GLenum target, GLenum pname, GLfloat * params) -{ - DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, "glGetColorTableParameterfvSGI(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params) -{ - DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, "glGetColorTableParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetColorTableParameteriv)(GLenum target, GLenum pname, GLint * params) { DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, "glGetColorTableParameteriv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_345)(GLenum target, GLenum pname, GLint * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_345)(GLenum target, GLenum pname, GLint * params) -{ - DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, "glGetColorTableParameterivSGI(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterivEXT)(GLenum target, GLenum pname, GLint * params) -{ - DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, "glGetColorTableParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(ColorSubTable)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data) { DISPATCH(ColorSubTable, (target, start, count, format, type, data), (F, "glColorSubTable(0x%x, %d, %d, 0x%x, 0x%x, %p);\n", target, start, count, format, type, (const void *) data)); @@ -2114,57 +2040,21 @@ KEYWORD1 void KEYWORD2 NAME(GetConvolutionFilter)(GLenum target, GLenum format, DISPATCH(GetConvolutionFilter, (target, format, type, image), (F, "glGetConvolutionFilter(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) image)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_356)(GLenum target, GLenum format, GLenum type, GLvoid * image); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_356)(GLenum target, GLenum format, GLenum type, GLvoid * image) -{ - DISPATCH(GetConvolutionFilter, (target, format, type, image), (F, "glGetConvolutionFilterEXT(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) image)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameterfv)(GLenum target, GLenum pname, GLfloat * params) { DISPATCH(GetConvolutionParameterfv, (target, pname, params), (F, "glGetConvolutionParameterfv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_357)(GLenum target, GLenum pname, GLfloat * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_357)(GLenum target, GLenum pname, GLfloat * params) -{ - DISPATCH(GetConvolutionParameterfv, (target, pname, params), (F, "glGetConvolutionParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameteriv)(GLenum target, GLenum pname, GLint * params) { DISPATCH(GetConvolutionParameteriv, (target, pname, params), (F, "glGetConvolutionParameteriv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_358)(GLenum target, GLenum pname, GLint * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_358)(GLenum target, GLenum pname, GLint * params) -{ - DISPATCH(GetConvolutionParameteriv, (target, pname, params), (F, "glGetConvolutionParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetSeparableFilter)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) { DISPATCH(GetSeparableFilter, (target, format, type, row, column, span), (F, "glGetSeparableFilter(0x%x, 0x%x, 0x%x, %p, %p, %p);\n", target, format, type, (const void *) row, (const void *) column, (const void *) span)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_359)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_359)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) -{ - DISPATCH(GetSeparableFilter, (target, format, type, row, column, span), (F, "glGetSeparableFilterEXT(0x%x, 0x%x, 0x%x, %p, %p, %p);\n", target, format, type, (const void *) row, (const void *) column, (const void *) span)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(SeparableFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column) { DISPATCH(SeparableFilter2D, (target, internalformat, width, height, format, type, row, column), (F, "glSeparableFilter2D(0x%x, 0x%x, %d, %d, 0x%x, 0x%x, %p, %p);\n", target, internalformat, width, height, format, type, (const void *) row, (const void *) column)); @@ -2182,85 +2072,31 @@ KEYWORD1 void KEYWORD2 NAME(GetHistogram)(GLenum target, GLboolean reset, GLenum DISPATCH(GetHistogram, (target, reset, format, type, values), (F, "glGetHistogram(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_361)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_361)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) -{ - DISPATCH(GetHistogram, (target, reset, format, type, values), (F, "glGetHistogramEXT(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetHistogramParameterfv)(GLenum target, GLenum pname, GLfloat * params) { DISPATCH(GetHistogramParameterfv, (target, pname, params), (F, "glGetHistogramParameterfv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_362)(GLenum target, GLenum pname, GLfloat * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_362)(GLenum target, GLenum pname, GLfloat * params) -{ - DISPATCH(GetHistogramParameterfv, (target, pname, params), (F, "glGetHistogramParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetHistogramParameteriv)(GLenum target, GLenum pname, GLint * params) { DISPATCH(GetHistogramParameteriv, (target, pname, params), (F, "glGetHistogramParameteriv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_363)(GLenum target, GLenum pname, GLint * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_363)(GLenum target, GLenum pname, GLint * params) -{ - DISPATCH(GetHistogramParameteriv, (target, pname, params), (F, "glGetHistogramParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetMinmax)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) { DISPATCH(GetMinmax, (target, reset, format, type, values), (F, "glGetMinmax(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_364)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_364)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) -{ - DISPATCH(GetMinmax, (target, reset, format, type, values), (F, "glGetMinmaxEXT(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameterfv)(GLenum target, GLenum pname, GLfloat * params) { DISPATCH(GetMinmaxParameterfv, (target, pname, params), (F, "glGetMinmaxParameterfv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_365)(GLenum target, GLenum pname, GLfloat * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_365)(GLenum target, GLenum pname, GLfloat * params) -{ - DISPATCH(GetMinmaxParameterfv, (target, pname, params), (F, "glGetMinmaxParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameteriv)(GLenum target, GLenum pname, GLint * params) { DISPATCH(GetMinmaxParameteriv, (target, pname, params), (F, "glGetMinmaxParameteriv(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); } -#ifndef GLX_INDIRECT_RENDERING -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_366)(GLenum target, GLenum pname, GLint * params); - -KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_366)(GLenum target, GLenum pname, GLint * params) -{ - DISPATCH(GetMinmaxParameteriv, (target, pname, params), (F, "glGetMinmaxParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); -} -#endif /* GLX_INDIRECT_RENDERING */ - KEYWORD1 void KEYWORD2 NAME(Histogram)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) { DISPATCH(Histogram, (target, width, internalformat, sink), (F, "glHistogram(0x%x, %d, 0x%x, %d);\n", target, width, internalformat, sink)); @@ -5777,6 +5613,141 @@ KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_802)(GLuint id, GLenum pname, GLu } +#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */ + +/* these entry points might require different protocols */ +#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS + +KEYWORD1 GLboolean KEYWORD2 NAME(AreTexturesResidentEXT)(GLsizei n, const GLuint * textures, GLboolean * residences) +{ + RETURN_DISPATCH(AreTexturesResident, (n, textures, residences), (F, "glAreTexturesResidentEXT(%d, %p, %p);\n", n, (const void *) textures, (const void *) residences)); +} + +KEYWORD1 void KEYWORD2 NAME(DeleteTexturesEXT)(GLsizei n, const GLuint * textures) +{ + DISPATCH(DeleteTextures, (n, textures), (F, "glDeleteTexturesEXT(%d, %p);\n", n, (const void *) textures)); +} + +KEYWORD1 void KEYWORD2 NAME(GenTexturesEXT)(GLsizei n, GLuint * textures) +{ + DISPATCH(GenTextures, (n, textures), (F, "glGenTexturesEXT(%d, %p);\n", n, (const void *) textures)); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(IsTextureEXT)(GLuint texture) +{ + RETURN_DISPATCH(IsTexture, (texture), (F, "glIsTextureEXT(%d);\n", texture)); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableEXT)(GLenum target, GLenum format, GLenum type, GLvoid * table) +{ + DISPATCH(GetColorTable, (target, format, type, table), (F, "glGetColorTableEXT(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) table)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_343)(GLenum target, GLenum format, GLenum type, GLvoid * table); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_343)(GLenum target, GLenum format, GLenum type, GLvoid * table) +{ + DISPATCH(GetColorTable, (target, format, type, table), (F, "glGetColorTableSGI(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) table)); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params) +{ + DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, "glGetColorTableParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_344)(GLenum target, GLenum pname, GLfloat * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_344)(GLenum target, GLenum pname, GLfloat * params) +{ + DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, "glGetColorTableParameterfvSGI(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterivEXT)(GLenum target, GLenum pname, GLint * params) +{ + DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, "glGetColorTableParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_345)(GLenum target, GLenum pname, GLint * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_345)(GLenum target, GLenum pname, GLint * params) +{ + DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, "glGetColorTableParameterivSGI(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_356)(GLenum target, GLenum format, GLenum type, GLvoid * image); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_356)(GLenum target, GLenum format, GLenum type, GLvoid * image) +{ + DISPATCH(GetConvolutionFilter, (target, format, type, image), (F, "glGetConvolutionFilterEXT(0x%x, 0x%x, 0x%x, %p);\n", target, format, type, (const void *) image)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_357)(GLenum target, GLenum pname, GLfloat * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_357)(GLenum target, GLenum pname, GLfloat * params) +{ + DISPATCH(GetConvolutionParameterfv, (target, pname, params), (F, "glGetConvolutionParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_358)(GLenum target, GLenum pname, GLint * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_358)(GLenum target, GLenum pname, GLint * params) +{ + DISPATCH(GetConvolutionParameteriv, (target, pname, params), (F, "glGetConvolutionParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_359)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_359)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) +{ + DISPATCH(GetSeparableFilter, (target, format, type, row, column, span), (F, "glGetSeparableFilterEXT(0x%x, 0x%x, 0x%x, %p, %p, %p);\n", target, format, type, (const void *) row, (const void *) column, (const void *) span)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_361)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_361)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) +{ + DISPATCH(GetHistogram, (target, reset, format, type, values), (F, "glGetHistogramEXT(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_362)(GLenum target, GLenum pname, GLfloat * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_362)(GLenum target, GLenum pname, GLfloat * params) +{ + DISPATCH(GetHistogramParameterfv, (target, pname, params), (F, "glGetHistogramParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_363)(GLenum target, GLenum pname, GLint * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_363)(GLenum target, GLenum pname, GLint * params) +{ + DISPATCH(GetHistogramParameteriv, (target, pname, params), (F, "glGetHistogramParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_364)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_364)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) +{ + DISPATCH(GetMinmax, (target, reset, format, type, values), (F, "glGetMinmaxEXT(0x%x, %d, 0x%x, 0x%x, %p);\n", target, reset, format, type, (const void *) values)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_365)(GLenum target, GLenum pname, GLfloat * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_365)(GLenum target, GLenum pname, GLfloat * params) +{ + DISPATCH(GetMinmaxParameterfv, (target, pname, params), (F, "glGetMinmaxParameterfvEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_366)(GLenum target, GLenum pname, GLint * params); + +KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_366)(GLenum target, GLenum pname, GLint * params) +{ + DISPATCH(GetMinmaxParameteriv, (target, pname, params), (F, "glGetMinmaxParameterivEXT(0x%x, 0x%x, %p);\n", target, pname, (const void *) params)); +} + + +#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */ + + #endif /* defined( NAME ) */ /* @@ -5789,7 +5760,11 @@ KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_802)(GLuint id, GLenum pname, GLu #error TABLE_ENTRY must be defined #endif -static _glapi_proc DISPATCH_TABLE_NAME[] = { +#ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS +#error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined +#endif + +_glapi_proc DISPATCH_TABLE_NAME[] = { TABLE_ENTRY(NewList), TABLE_ENTRY(EndList), TABLE_ENTRY(CallList), @@ -6705,27 +6680,16 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = { * We list the functions which are not otherwise used. */ #ifdef UNUSED_TABLE_NAME -static _glapi_proc UNUSED_TABLE_NAME[] = { +_glapi_proc UNUSED_TABLE_NAME[] = { +#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS TABLE_ENTRY(ArrayElementEXT), TABLE_ENTRY(BindTextureEXT), TABLE_ENTRY(DrawArraysEXT), -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(AreTexturesResidentEXT), -#endif TABLE_ENTRY(CopyTexImage1DEXT), TABLE_ENTRY(CopyTexImage2DEXT), TABLE_ENTRY(CopyTexSubImage1DEXT), TABLE_ENTRY(CopyTexSubImage2DEXT), -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(DeleteTexturesEXT), -#endif -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(GenTexturesEXT), -#endif TABLE_ENTRY(GetPointervEXT), -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(IsTextureEXT), -#endif TABLE_ENTRY(PrioritizeTexturesEXT), TABLE_ENTRY(TexSubImage1DEXT), TABLE_ENTRY(TexSubImage2DEXT), @@ -6733,15 +6697,25 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(BlendEquationEXT), TABLE_ENTRY(DrawRangeElementsEXT), TABLE_ENTRY(ColorTableEXT), -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(GetColorTableEXT), -#endif -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(GetColorTableParameterfvEXT), -#endif -#ifndef GLX_INDIRECT_RENDERING - TABLE_ENTRY(GetColorTableParameterivEXT), -#endif + TABLE_ENTRY(_dispatch_stub_339), + TABLE_ENTRY(_dispatch_stub_340), + TABLE_ENTRY(_dispatch_stub_341), + TABLE_ENTRY(_dispatch_stub_342), + TABLE_ENTRY(_dispatch_stub_346), + TABLE_ENTRY(_dispatch_stub_347), + TABLE_ENTRY(_dispatch_stub_348), + TABLE_ENTRY(_dispatch_stub_349), + TABLE_ENTRY(_dispatch_stub_350), + TABLE_ENTRY(_dispatch_stub_351), + TABLE_ENTRY(_dispatch_stub_352), + TABLE_ENTRY(_dispatch_stub_353), + TABLE_ENTRY(_dispatch_stub_354), + TABLE_ENTRY(_dispatch_stub_355), + TABLE_ENTRY(_dispatch_stub_360), + TABLE_ENTRY(_dispatch_stub_367), + TABLE_ENTRY(_dispatch_stub_368), + TABLE_ENTRY(_dispatch_stub_369), + TABLE_ENTRY(_dispatch_stub_370), TABLE_ENTRY(TexImage3DEXT), TABLE_ENTRY(TexSubImage3DEXT), TABLE_ENTRY(CopyTexSubImage3DEXT), @@ -6779,6 +6753,7 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(MultiTexCoord4iv), TABLE_ENTRY(MultiTexCoord4s), TABLE_ENTRY(MultiTexCoord4sv), + TABLE_ENTRY(_dispatch_stub_423), TABLE_ENTRY(LoadTransposeMatrixd), TABLE_ENTRY(LoadTransposeMatrixf), TABLE_ENTRY(MultTransposeMatrixd), @@ -6893,8 +6868,10 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(RenderbufferStorageMultisampleEXT), TABLE_ENTRY(PointParameterf), TABLE_ENTRY(PointParameterfARB), + TABLE_ENTRY(_dispatch_stub_592), TABLE_ENTRY(PointParameterfv), TABLE_ENTRY(PointParameterfvARB), + TABLE_ENTRY(_dispatch_stub_593), TABLE_ENTRY(SecondaryColor3b), TABLE_ENTRY(SecondaryColor3bv), TABLE_ENTRY(SecondaryColor3d), @@ -6920,6 +6897,7 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(FogCoordf), TABLE_ENTRY(FogCoordfv), TABLE_ENTRY(BlendFuncSeparate), + TABLE_ENTRY(_dispatch_stub_623), TABLE_ENTRY(WindowPos2d), TABLE_ENTRY(WindowPos2dARB), TABLE_ENTRY(WindowPos2dv), @@ -6983,6 +6961,29 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(BlitFramebuffer), TABLE_ENTRY(FramebufferTextureLayer), TABLE_ENTRY(ProvokingVertex), +#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */ +#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS + TABLE_ENTRY(AreTexturesResidentEXT), + TABLE_ENTRY(DeleteTexturesEXT), + TABLE_ENTRY(GenTexturesEXT), + TABLE_ENTRY(IsTextureEXT), + TABLE_ENTRY(GetColorTableEXT), + TABLE_ENTRY(_dispatch_stub_343), + TABLE_ENTRY(GetColorTableParameterfvEXT), + TABLE_ENTRY(_dispatch_stub_344), + TABLE_ENTRY(GetColorTableParameterivEXT), + TABLE_ENTRY(_dispatch_stub_345), + TABLE_ENTRY(_dispatch_stub_356), + TABLE_ENTRY(_dispatch_stub_357), + TABLE_ENTRY(_dispatch_stub_358), + TABLE_ENTRY(_dispatch_stub_359), + TABLE_ENTRY(_dispatch_stub_361), + TABLE_ENTRY(_dispatch_stub_362), + TABLE_ENTRY(_dispatch_stub_363), + TABLE_ENTRY(_dispatch_stub_364), + TABLE_ENTRY(_dispatch_stub_365), + TABLE_ENTRY(_dispatch_stub_366), +#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */ }; #endif /*UNUSED_TABLE_NAME*/ diff --git a/src/mesa/glapi/glthread.c b/src/mesa/glapi/glthread.c index f480edff4e..1c2c386571 100644 --- a/src/mesa/glapi/glthread.c +++ b/src/mesa/glapi/glthread.c @@ -33,7 +33,7 @@ #endif #include "main/compiler.h" -#include "glthread.h" +#include "glapi/glthread.h" /* diff --git a/src/mesa/glapi/remap_helper.py b/src/mesa/glapi/remap_helper.py index e47583a5d3..d93c7a4285 100644 --- a/src/mesa/glapi/remap_helper.py +++ b/src/mesa/glapi/remap_helper.py @@ -123,18 +123,26 @@ class PrintGlRemap(gl_XML.gl_print_base): print '};' print '' - abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ] + # collect functions by versions/extensions extension_functions = {} - - # collect non-ABI functions + abi_extensions = [] for f in api.functionIterateAll(): for n in f.entry_points: category, num = api.get_category_for_name(n) - if category not in abi: - c = gl_XML.real_category_name(category) + # consider only GL_VERSION_X_Y or extensions + c = gl_XML.real_category_name(category) + if c.startswith("GL_"): if not extension_functions.has_key(c): extension_functions[c] = [] extension_functions[c].append(f) + # remember the ext names of the ABI + if (f.is_abi() and n == f.name and + c not in abi_extensions): + abi_extensions.append(c) + # ignore the ABI itself + for ext in abi_extensions: + extension_functions.pop(ext) + extensions = extension_functions.keys() extensions.sort() @@ -144,8 +152,8 @@ class PrintGlRemap(gl_XML.gl_print_base): for ext in extensions: funcs = [] for f in extension_functions[ext]: - # test if the function is in the ABI - if not f.assign_offset and f.offset >= 0: + # test if the function is in the ABI and has alt names + if f.is_abi() and len(f.entry_points) > 1: funcs.append(f) if not funcs: continue @@ -171,7 +179,7 @@ class PrintGlRemap(gl_XML.gl_print_base): remapped.append(f) else: # these functions are either in the - # abi, or have offset -1 + # abi, or have offset -1 funcs.append(f) print '#if defined(need_%s)' % (ext) diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index c2d8a7fb97..e62c7aa572 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c @@ -66,14 +66,12 @@ #if FEATURE_EXT_framebuffer_object #include "fbobject.h" #endif -#include "ffvertex_prog.h" #include "framebuffer.h" #include "hint.h" #include "histogram.h" #include "imports.h" #include "light.h" #include "lines.h" -#include "macros.h" #include "matrix.h" #include "multisample.h" #include "pixel.h" @@ -83,7 +81,6 @@ #include "queryobj.h" #include "readpix.h" #include "scissor.h" -#include "state.h" #include "stencil.h" #include "texenv.h" #include "texgetimage.h" @@ -100,8 +97,6 @@ #endif #if FEATURE_NV_fragment_program #include "shader/nvprogram.h" -#include "shader/program.h" -#include "texenvprogram.h" #endif #if FEATURE_ARB_shader_objects #include "shaders.h" @@ -109,7 +104,6 @@ #if FEATURE_ARB_sync #include "syncobj.h" #endif -#include "debug.h" #include "glapi/dispatch.h" diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index e71e5a6ce8..326ad6f909 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -28,7 +28,6 @@ #include "context.h" #include "imports.h" #include "mtypes.h" -#include "state.h" #include "vbo/vbo.h" @@ -190,9 +189,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawElements")) return GL_FALSE; @@ -254,9 +250,6 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawRangeElements")) return GL_FALSE; @@ -304,9 +297,6 @@ _mesa_validate_DrawArrays(GLcontext *ctx, return GL_FALSE; } - if (ctx->NewState) - _mesa_update_state(ctx); - if (!check_valid_to_render(ctx, "glDrawArrays")) return GL_FALSE; diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index fd35d4e38c..e36137d378 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -95,6 +95,10 @@ unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) for (i = 0; i < Elements(obj->VertexAttrib); i++) _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL); + +#if FEATURE_point_size_array + _mesa_reference_buffer_object(ctx, &obj->PointSize.BufferObj, NULL); +#endif } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 0641b98b3b..3fbdba2b3f 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -33,7 +33,6 @@ #include "bufferobj.h" #include "clear.h" #include "colormac.h" -#include "colortab.h" #include "context.h" #include "depth.h" #include "enable.h" diff --git a/src/mesa/main/bitset.h b/src/mesa/main/bitset.h index 8bd4526cb6..f2709abc9f 100644 --- a/src/mesa/main/bitset.h +++ b/src/mesa/main/bitset.h @@ -27,7 +27,12 @@ * \brief Bitset of arbitrary size definitions. * \author Michal Krol */ - + +#ifndef BITSET_H +#define BITSET_H + +#include "imports.h" + /**************************************************************************** * generic bitset implementation */ @@ -74,6 +79,23 @@ ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \ (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0)) +/* Get first bit set in a bitset. + */ +static INLINE int +__bitset_ffs(const BITSET_WORD *x, int n) +{ + int i; + + for (i = 0; i < n; i++) { + if (x[i]) + return _mesa_ffs(x[i]) + BITSET_WORDBITS * i; + } + + return 0; +} + +#define BITSET_FFS(x) __bitset_ffs(x, Elements(x)) + /**************************************************************************** * 64-bit bitset implementation */ @@ -120,3 +142,4 @@ ((x)[BITSET64_BITWORD(b)] &= ~BITSET64_RANGE(b, e)) : \ (assert (!"BITSET64_CLEAR_RANGE: bit range crosses word boundary"), 0)) +#endif diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index b8170dd468..de60031cc8 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -35,7 +35,6 @@ #include "enums.h" #include "macros.h" #include "mtypes.h" -#include "glapi/glapitable.h" /** diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 9e765b21d2..dabb1386ca 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -214,6 +214,7 @@ _mesa_delete_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) bufObj->RefCount = -1000; bufObj->Name = ~0; + _glthread_DESTROY_MUTEX(bufObj->Mutex); _mesa_free(bufObj); } @@ -235,7 +236,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, GLboolean deleteFlag = GL_FALSE; struct gl_buffer_object *oldObj = *ptr; - /*_glthread_LOCK_MUTEX(oldObj->Mutex);*/ + _glthread_LOCK_MUTEX(oldObj->Mutex); ASSERT(oldObj->RefCount > 0); oldObj->RefCount--; #if 0 @@ -243,7 +244,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, (void *) oldObj, oldObj->Name, oldObj->RefCount); #endif deleteFlag = (oldObj->RefCount == 0); - /*_glthread_UNLOCK_MUTEX(oldObj->Mutex);*/ + _glthread_UNLOCK_MUTEX(oldObj->Mutex); if (deleteFlag) { @@ -265,7 +266,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, if (bufObj) { /* reference new buffer */ - /*_glthread_LOCK_MUTEX(tex->Mutex);*/ + _glthread_LOCK_MUTEX(bufObj->Mutex); if (bufObj->RefCount == 0) { /* this buffer's being deleted (look just above) */ /* Not sure this can every really happen. Warn if it does. */ @@ -280,7 +281,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, #endif *ptr = bufObj; } - /*_glthread_UNLOCK_MUTEX(tex->Mutex);*/ + _glthread_UNLOCK_MUTEX(bufObj->Mutex); } } @@ -295,6 +296,7 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj, (void) target; _mesa_bzero(obj, sizeof(struct gl_buffer_object)); + _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Usage = GL_STATIC_DRAW_ARB; @@ -554,6 +556,17 @@ _mesa_init_buffer_objects( GLcontext *ctx ) } +void +_mesa_free_buffer_objects( GLcontext *ctx ) +{ + _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); + _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL); + + _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL); + _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL); +} + + /** * Bind the specified target to buffer for the specified context. * Called by glBindBuffer() and other functions. diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 2931962ac0..f8bca5ff71 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -60,6 +60,9 @@ extern void _mesa_init_buffer_objects( GLcontext *ctx ); extern void +_mesa_free_buffer_objects( GLcontext *ctx ); + +extern void _mesa_update_default_objects_buffer_objects(GLcontext *ctx); diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 97f0659758..fb30b59960 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -35,8 +35,6 @@ #include "colormac.h" #include "context.h" #include "enums.h" -#include "fbobject.h" -#include "state.h" #define BAD_MASK ~0u diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h index 4eb249b4af..9cef99f67a 100644 --- a/src/mesa/main/compiler.h +++ b/src/mesa/main/compiler.h @@ -173,7 +173,8 @@ extern "C" { * We also need to define a USED attribute, so the optimizer doesn't * inline a static function that we later use in an alias. - ajax */ -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 +#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) # define PUBLIC __attribute__((visibility("default"))) # define USED __attribute__((used)) #else @@ -222,8 +223,8 @@ extern "C" { /** - * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN. - * Do not use them unless absolutely necessary! + * Either define MESA_BIG_ENDIAN or MESA_LITTLE_ENDIAN, and CPU_TO_LE32. + * Do not use these unless absolutely necessary! * Try to use a runtime test instead. * For now, only used by some DRI hardware drivers for color/texel packing. */ @@ -235,10 +236,13 @@ extern "C" { #include <CoreFoundation/CFByteOrder.h> #define CPU_TO_LE32( x ) CFSwapInt32HostToLittle( x ) #elif (defined(_AIX) || defined(__blrts)) -#define CPU_TO_LE32( x ) x = ((x & 0x000000ff) << 24) | \ - ((x & 0x0000ff00) << 8) | \ - ((x & 0x00ff0000) >> 8) | \ - ((x & 0xff000000) >> 24); +static INLINE GLuint CPU_TO_LE32(GLuint x) +{ + return (((x & 0x000000ff) << 24) | + ((x & 0x0000ff00) << 8) | + ((x & 0x00ff0000) >> 8) | + ((x & 0xff000000) >> 24)); +} #else /*__linux__ */ #include <sys/endian.h> #define CPU_TO_LE32( x ) bswap32( x ) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 320c59068c..591aa1121d 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -93,13 +93,11 @@ #include "depth.h" #include "dlist.h" #include "eval.h" -#include "enums.h" #include "extensions.h" #include "fbobject.h" #include "feedback.h" #include "fog.h" #include "framebuffer.h" -#include "get.h" #include "histogram.h" #include "hint.h" #include "hash.h" @@ -124,8 +122,6 @@ #include "state.h" #include "stencil.h" #include "texcompress_s3tc.h" -#include "teximage.h" -#include "texobj.h" #include "texstate.h" #include "mtypes.h" #include "varray.h" @@ -137,9 +133,6 @@ #include "shader/program.h" #include "shader/prog_print.h" #include "shader/shader_api.h" -#if FEATURE_ATI_fragment_shader -#include "shader/atifragshader.h" -#endif #if _HAVE_FULL_GL #include "math/m_matrix.h" #endif @@ -415,14 +408,6 @@ one_time_init( GLcontext *ctx ) _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; } - if (_mesa_getenv("MESA_DEBUG")) { - _glapi_noop_enable_warnings(GL_TRUE); - _glapi_set_warning_func( (_glapi_warning_func) _mesa_warning ); - } - else { - _glapi_noop_enable_warnings(GL_FALSE); - } - #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", MESA_VERSION_STRING, __DATE__, __TIME__); @@ -592,6 +577,9 @@ _mesa_init_constants(GLcontext *ctx) ctx->Const.MaxTextureCoordUnits)); ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + ASSERT(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); + ASSERT(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); + ASSERT(MAX_COMBINED_TEXTURE_IMAGE_UNITS <= 32); /* GLbitfield size limit */ ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); @@ -847,7 +835,7 @@ _mesa_initialize_context(GLcontext *ctx, _glthread_UNLOCK_MUTEX(shared->Mutex); if (!init_attrib_groups( ctx )) { - _mesa_free_shared_state(ctx, ctx->Shared); + _mesa_release_shared_state(ctx, ctx->Shared); return GL_FALSE; } @@ -855,7 +843,7 @@ _mesa_initialize_context(GLcontext *ctx, ctx->Exec = alloc_dispatch_table(); ctx->Save = alloc_dispatch_table(); if (!ctx->Exec || !ctx->Save) { - _mesa_free_shared_state(ctx, ctx->Shared); + _mesa_release_shared_state(ctx, ctx->Shared); if (ctx->Exec) _mesa_free(ctx->Exec); return GL_FALSE; @@ -945,8 +933,6 @@ _mesa_create_context(const GLvisual *visual, void _mesa_free_context_data( GLcontext *ctx ) { - GLint RefCount; - 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. @@ -969,6 +955,7 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, 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 ); @@ -988,6 +975,7 @@ _mesa_free_context_data( GLcontext *ctx ) #if FEATURE_ARB_pixel_buffer_object _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); #endif #if FEATURE_ARB_vertex_buffer_object @@ -1000,14 +988,7 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free(ctx->Save); /* Shared context state (display lists, textures, etc) */ - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - RefCount = --ctx->Shared->RefCount; - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - assert(RefCount >= 0); - if (RefCount == 0) { - /* free shared state */ - _mesa_free_shared_state( ctx, ctx->Shared ); - } + _mesa_release_shared_state( ctx, ctx->Shared ); /* needs to be after freeing shared state */ _mesa_free_display_list_data(ctx); @@ -1409,7 +1390,6 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { struct gl_shared_state *oldSharedState = ctx->Shared; - GLint RefCount; ctx->Shared = ctxToShare->Shared; @@ -1419,13 +1399,7 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) update_default_objects(ctx); - _glthread_LOCK_MUTEX(oldSharedState->Mutex); - RefCount = --oldSharedState->RefCount; - _glthread_UNLOCK_MUTEX(oldSharedState->Mutex); - - if (RefCount == 0) { - _mesa_free_shared_state(ctx, oldSharedState); - } + _mesa_release_shared_state(ctx, oldSharedState); return GL_TRUE; } @@ -1586,6 +1560,10 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx, GLboolean _mesa_valid_to_render(GLcontext *ctx, const char *where) { + /* This depends on having up to date derived state (shaders) */ + if (ctx->NewState) + _mesa_update_state(ctx); + if (ctx->Shader.CurrentProgram) { /* using shaders */ if (!ctx->Shader.CurrentProgram->LinkStatus) { diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c index 8db3e79d38..5ed93e0c60 100644 --- a/src/mesa/main/convolve.c +++ b/src/mesa/main/convolve.c @@ -38,7 +38,6 @@ #include "context.h" #include "image.h" #include "mtypes.h" -#include "pixel.h" #include "state.h" #include "glapi/dispatch.h" diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index e99e87d905..d98a14e09c 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -581,9 +581,13 @@ struct dd_function_table { struct gl_program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id); /** Delete a program */ void (*DeleteProgram)(GLcontext *ctx, struct gl_program *prog); - /** Notify driver that a program string has been specified. */ - void (*ProgramStringNotify)(GLcontext *ctx, GLenum target, - struct gl_program *prog); + /** + * Notify driver that a program string (and GPU code) has been specified + * or modified. Return GL_TRUE or GL_FALSE to indicate if the program is + * supported by the driver. + */ + GLboolean (*ProgramStringNotify)(GLcontext *ctx, GLenum target, + struct gl_program *prog); /** Query if program can be loaded onto hardware */ GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target, @@ -1021,6 +1025,16 @@ struct dd_function_table { void (*BeginConditionalRender)(GLcontext *ctx, struct gl_query_object *q, GLenum mode); void (*EndConditionalRender)(GLcontext *ctx, struct gl_query_object *q); + +#if FEATURE_OES_draw_texture + /** + * \name GL_OES_draw_texture interface + */ + /*@{*/ + void (*DrawTex)(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, + GLfloat width, GLfloat height); + /*@}*/ +#endif }; diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index a42113edca..9bad83487f 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -26,7 +26,6 @@ #include "mtypes.h" #include "attrib.h" #include "colormac.h" -#include "context.h" #include "enums.h" #include "formats.h" #include "hash.h" @@ -35,7 +34,6 @@ #include "get.h" #include "pixelstore.h" #include "readpix.h" -#include "texgetimage.h" #include "texobj.h" @@ -54,7 +52,7 @@ const char *_mesa_prim_name[GL_POLYGON+4] = { "GL_QUAD_STRIP", "GL_POLYGON", "outside begin/end", - "inside unkown primitive", + "inside unknown primitive", "unknown state" }; diff --git a/src/mesa/main/depthstencil.c b/src/mesa/main/depthstencil.c index 193c7f8255..49946a6506 100644 --- a/src/mesa/main/depthstencil.c +++ b/src/mesa/main/depthstencil.c @@ -25,7 +25,6 @@ #include "glheader.h" #include "imports.h" #include "context.h" -#include "fbobject.h" #include "formats.h" #include "mtypes.h" #include "depthstencil.h" diff --git a/src/mesa/main/dispatch.c b/src/mesa/main/dispatch.c index eb0d1ff8a7..b9b726b001 100644 --- a/src/mesa/main/dispatch.c +++ b/src/mesa/main/dispatch.c @@ -32,7 +32,7 @@ * * \note * This file is also used to build the client-side libGL that loads DRI-based - * device drivers. At build-time it is symlinked to src/glx/x11. + * device drivers. At build-time it is symlinked to src/glx. * * \author Brian Paul <brian@precisioninsight.com> */ @@ -87,6 +87,10 @@ #define GLAPIENTRY #endif +#ifdef GLX_INDIRECT_RENDERING +/* those link to libglapi.a should provide the entry points */ +#define _GLAPI_SKIP_PROTO_ENTRY_POINTS +#endif #include "glapi/glapitemp.h" #endif /* USE_X86_ASM */ diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 21a8216254..683d062bb9 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -35,53 +35,30 @@ #include "api_loopback.h" #include "config.h" #include "mfeatures.h" -#include "attrib.h" -#include "blend.h" -#include "buffers.h" #if FEATURE_ARB_vertex_buffer_object #include "bufferobj.h" #endif #include "arrayobj.h" -#include "clip.h" -#include "colortab.h" #include "context.h" -#include "convolve.h" -#include "depth.h" #include "dlist.h" -#include "enable.h" #include "enums.h" #include "eval.h" -#include "extensions.h" -#include "feedback.h" #include "framebuffer.h" -#include "get.h" #include "glapi/glapi.h" #include "hash.h" -#include "histogram.h" #include "image.h" #include "light.h" -#include "lines.h" #include "dlist.h" #include "macros.h" -#include "matrix.h" -#include "pixel.h" -#include "points.h" -#include "polygon.h" #include "queryobj.h" -#include "state.h" -#include "texobj.h" #include "teximage.h" -#include "texstate.h" #include "mtypes.h" #include "varray.h" -#include "vtxfmt.h" #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program #include "shader/arbprogram.h" -#include "shader/program.h" #endif #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program #include "shader/nvprogram.h" -#include "shader/program.h" #endif #if FEATURE_ATI_fragment_shader #include "shader/atifragshader.h" @@ -3750,7 +3727,7 @@ save_TexEnvi(GLenum target, GLenum pname, GLint param) { GLfloat p[4]; p[0] = (GLfloat) param; - p[1] = p[2] = p[3] = 0.0; + p[1] = p[2] = p[3] = 0.0F; save_TexEnvfv(target, pname, p); } @@ -3884,7 +3861,7 @@ save_TexParameteri(GLenum target, GLenum pname, GLint param) { GLfloat fparam[4]; fparam[0] = (GLfloat) param; - fparam[1] = fparam[2] = fparam[3] = 0.0; + fparam[1] = fparam[2] = fparam[3] = 0.0F; save_TexParameterfv(target, pname, fparam); } @@ -3894,7 +3871,7 @@ save_TexParameteriv(GLenum target, GLenum pname, const GLint *params) { GLfloat fparam[4]; fparam[0] = (GLfloat) params[0]; - fparam[1] = fparam[2] = fparam[3] = 0.0; + fparam[1] = fparam[2] = fparam[3] = 0.0F; save_TexParameterfv(target, pname, fparam); } diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 5d4b53af4c..0afd47b797 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -30,7 +30,6 @@ #include "enums.h" #include "feedback.h" #include "framebuffer.h" -#include "image.h" #include "readpix.h" #include "state.h" #include "glapi/dispatch.h" diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index cd6e881ad2..f5c88a63e6 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -32,7 +32,6 @@ #include "context.h" #include "enable.h" #include "light.h" -#include "macros.h" #include "simple_list.h" #include "mtypes.h" #include "enums.h" diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index 2273138d23..1d495b7ae5 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -25,10 +25,10 @@ * SOFTWARE. */ -#include "glheader.h" -#include "mfeatures.h" -#include "enums.h" -#include "imports.h" +#include "main/glheader.h" +#include "main/mfeatures.h" +#include "main/enums.h" +#include "main/imports.h" typedef struct { size_t offset; @@ -640,6 +640,7 @@ LONGSTRING static const char enum_string_table[] = "GL_GREEN_BIAS\0" "GL_GREEN_BITS\0" "GL_GREEN_SCALE\0" + "GL_HALF_FLOAT\0" "GL_HINT_BIT\0" "GL_HISTOGRAM\0" "GL_HISTOGRAM_ALPHA_SIZE\0" @@ -1922,7 +1923,7 @@ LONGSTRING static const char enum_string_table[] = "GL_ZOOM_Y\0" ; -static const enum_elt all_enums[1884] = +static const enum_elt all_enums[1885] = { { 0, 0x00000600 }, /* GL_2D */ { 6, 0x00001407 }, /* GL_2_BYTES */ @@ -2528,1365 +2529,1366 @@ static const enum_elt all_enums[1884] = { 12769, 0x00000D19 }, /* GL_GREEN_BIAS */ { 12783, 0x00000D53 }, /* GL_GREEN_BITS */ { 12797, 0x00000D18 }, /* GL_GREEN_SCALE */ - { 12812, 0x00008000 }, /* GL_HINT_BIT */ - { 12824, 0x00008024 }, /* GL_HISTOGRAM */ - { 12837, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */ - { 12861, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */ - { 12889, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */ - { 12912, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */ - { 12939, 0x00008024 }, /* GL_HISTOGRAM_EXT */ - { 12956, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */ - { 12976, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */ - { 13000, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */ - { 13024, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */ - { 13052, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */ - { 13080, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */ - { 13112, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */ - { 13134, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */ - { 13160, 0x0000802D }, /* GL_HISTOGRAM_SINK */ - { 13178, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */ - { 13200, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */ - { 13219, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */ - { 13242, 0x0000862A }, /* GL_IDENTITY_NV */ - { 13257, 0x00008150 }, /* GL_IGNORE_BORDER_HP */ - { 13277, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ - { 13317, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ - { 13355, 0x00001E02 }, /* GL_INCR */ - { 13363, 0x00008507 }, /* GL_INCR_WRAP */ - { 13376, 0x00008507 }, /* GL_INCR_WRAP_EXT */ - { 13393, 0x00008222 }, /* GL_INDEX */ - { 13402, 0x00008077 }, /* GL_INDEX_ARRAY */ - { 13417, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */ - { 13447, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */ - { 13481, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */ - { 13504, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */ - { 13526, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */ - { 13546, 0x00000D51 }, /* GL_INDEX_BITS */ - { 13560, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */ - { 13581, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */ - { 13599, 0x00000C30 }, /* GL_INDEX_MODE */ - { 13613, 0x00000D13 }, /* GL_INDEX_OFFSET */ - { 13629, 0x00000D12 }, /* GL_INDEX_SHIFT */ - { 13644, 0x00000C21 }, /* GL_INDEX_WRITEMASK */ - { 13663, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */ - { 13682, 0x00001404 }, /* GL_INT */ - { 13689, 0x00008049 }, /* GL_INTENSITY */ - { 13702, 0x0000804C }, /* GL_INTENSITY12 */ - { 13717, 0x0000804C }, /* GL_INTENSITY12_EXT */ - { 13736, 0x0000804D }, /* GL_INTENSITY16 */ - { 13751, 0x0000804D }, /* GL_INTENSITY16_EXT */ - { 13770, 0x0000804A }, /* GL_INTENSITY4 */ - { 13784, 0x0000804A }, /* GL_INTENSITY4_EXT */ - { 13802, 0x0000804B }, /* GL_INTENSITY8 */ - { 13816, 0x0000804B }, /* GL_INTENSITY8_EXT */ - { 13834, 0x00008049 }, /* GL_INTENSITY_EXT */ - { 13851, 0x00008575 }, /* GL_INTERPOLATE */ - { 13866, 0x00008575 }, /* GL_INTERPOLATE_ARB */ - { 13885, 0x00008575 }, /* GL_INTERPOLATE_EXT */ - { 13904, 0x00008B53 }, /* GL_INT_VEC2 */ - { 13916, 0x00008B53 }, /* GL_INT_VEC2_ARB */ - { 13932, 0x00008B54 }, /* GL_INT_VEC3 */ - { 13944, 0x00008B54 }, /* GL_INT_VEC3_ARB */ - { 13960, 0x00008B55 }, /* GL_INT_VEC4 */ - { 13972, 0x00008B55 }, /* GL_INT_VEC4_ARB */ - { 13988, 0x00000500 }, /* GL_INVALID_ENUM */ - { 14004, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */ - { 14037, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */ - { 14074, 0x00000502 }, /* GL_INVALID_OPERATION */ - { 14095, 0x00000501 }, /* GL_INVALID_VALUE */ - { 14112, 0x0000862B }, /* GL_INVERSE_NV */ - { 14126, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */ - { 14150, 0x0000150A }, /* GL_INVERT */ - { 14160, 0x00001E00 }, /* GL_KEEP */ - { 14168, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */ - { 14194, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */ - { 14224, 0x00000406 }, /* GL_LEFT */ - { 14232, 0x00000203 }, /* GL_LEQUAL */ - { 14242, 0x00000201 }, /* GL_LESS */ - { 14250, 0x00004000 }, /* GL_LIGHT0 */ - { 14260, 0x00004001 }, /* GL_LIGHT1 */ - { 14270, 0x00004002 }, /* GL_LIGHT2 */ - { 14280, 0x00004003 }, /* GL_LIGHT3 */ - { 14290, 0x00004004 }, /* GL_LIGHT4 */ - { 14300, 0x00004005 }, /* GL_LIGHT5 */ - { 14310, 0x00004006 }, /* GL_LIGHT6 */ - { 14320, 0x00004007 }, /* GL_LIGHT7 */ - { 14330, 0x00000B50 }, /* GL_LIGHTING */ - { 14342, 0x00000040 }, /* GL_LIGHTING_BIT */ - { 14358, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */ - { 14381, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */ - { 14410, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */ - { 14443, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ - { 14471, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */ - { 14495, 0x00001B01 }, /* GL_LINE */ - { 14503, 0x00002601 }, /* GL_LINEAR */ - { 14513, 0x00001208 }, /* GL_LINEAR_ATTENUATION */ - { 14535, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ - { 14565, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ - { 14596, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */ - { 14620, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */ - { 14645, 0x00000001 }, /* GL_LINES */ - { 14654, 0x00000004 }, /* GL_LINE_BIT */ - { 14666, 0x00000002 }, /* GL_LINE_LOOP */ - { 14679, 0x00000707 }, /* GL_LINE_RESET_TOKEN */ - { 14699, 0x00000B20 }, /* GL_LINE_SMOOTH */ - { 14714, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */ - { 14734, 0x00000B24 }, /* GL_LINE_STIPPLE */ - { 14750, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */ - { 14774, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */ - { 14797, 0x00000003 }, /* GL_LINE_STRIP */ - { 14811, 0x00000702 }, /* GL_LINE_TOKEN */ - { 14825, 0x00000B21 }, /* GL_LINE_WIDTH */ - { 14839, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */ - { 14865, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */ - { 14885, 0x00008B82 }, /* GL_LINK_STATUS */ - { 14900, 0x00000B32 }, /* GL_LIST_BASE */ - { 14913, 0x00020000 }, /* GL_LIST_BIT */ - { 14925, 0x00000B33 }, /* GL_LIST_INDEX */ - { 14939, 0x00000B30 }, /* GL_LIST_MODE */ - { 14952, 0x00000101 }, /* GL_LOAD */ - { 14960, 0x00000BF1 }, /* GL_LOGIC_OP */ - { 14972, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */ - { 14989, 0x00008CA1 }, /* GL_LOWER_LEFT */ - { 15003, 0x00001909 }, /* GL_LUMINANCE */ - { 15016, 0x00008041 }, /* GL_LUMINANCE12 */ - { 15031, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */ - { 15054, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */ - { 15081, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */ - { 15103, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */ - { 15129, 0x00008041 }, /* GL_LUMINANCE12_EXT */ - { 15148, 0x00008042 }, /* GL_LUMINANCE16 */ - { 15163, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */ - { 15186, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */ - { 15213, 0x00008042 }, /* GL_LUMINANCE16_EXT */ - { 15232, 0x0000803F }, /* GL_LUMINANCE4 */ - { 15246, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */ - { 15267, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */ - { 15292, 0x0000803F }, /* GL_LUMINANCE4_EXT */ - { 15310, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */ - { 15331, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */ - { 15356, 0x00008040 }, /* GL_LUMINANCE8 */ - { 15370, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */ - { 15391, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */ - { 15416, 0x00008040 }, /* GL_LUMINANCE8_EXT */ - { 15434, 0x0000190A }, /* GL_LUMINANCE_ALPHA */ - { 15453, 0x00000D90 }, /* GL_MAP1_COLOR_4 */ - { 15469, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */ - { 15489, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */ - { 15511, 0x00000D91 }, /* GL_MAP1_INDEX */ - { 15525, 0x00000D92 }, /* GL_MAP1_NORMAL */ - { 15540, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */ - { 15564, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */ - { 15588, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */ - { 15612, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */ - { 15636, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */ - { 15653, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */ - { 15670, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ - { 15698, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ - { 15727, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ - { 15756, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ - { 15785, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ - { 15814, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ - { 15843, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ - { 15872, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ - { 15900, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ - { 15928, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ - { 15956, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ - { 15984, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ - { 16012, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ - { 16040, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ - { 16068, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ - { 16096, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ - { 16124, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */ - { 16140, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */ - { 16160, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */ - { 16182, 0x00000DB1 }, /* GL_MAP2_INDEX */ - { 16196, 0x00000DB2 }, /* GL_MAP2_NORMAL */ - { 16211, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */ - { 16235, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */ - { 16259, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */ - { 16283, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */ - { 16307, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */ - { 16324, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */ - { 16341, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ - { 16369, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ - { 16398, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ - { 16427, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ - { 16456, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ - { 16485, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ - { 16514, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ - { 16543, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ - { 16571, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ - { 16599, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ - { 16627, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ - { 16655, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ - { 16683, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ - { 16711, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */ - { 16739, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ - { 16767, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ - { 16795, 0x00000D10 }, /* GL_MAP_COLOR */ - { 16808, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */ - { 16834, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */ - { 16863, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */ - { 16891, 0x00000001 }, /* GL_MAP_READ_BIT */ - { 16907, 0x00000D11 }, /* GL_MAP_STENCIL */ - { 16922, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */ - { 16948, 0x00000002 }, /* GL_MAP_WRITE_BIT */ - { 16965, 0x000088C0 }, /* GL_MATRIX0_ARB */ - { 16980, 0x00008630 }, /* GL_MATRIX0_NV */ - { 16994, 0x000088CA }, /* GL_MATRIX10_ARB */ - { 17010, 0x000088CB }, /* GL_MATRIX11_ARB */ - { 17026, 0x000088CC }, /* GL_MATRIX12_ARB */ - { 17042, 0x000088CD }, /* GL_MATRIX13_ARB */ - { 17058, 0x000088CE }, /* GL_MATRIX14_ARB */ - { 17074, 0x000088CF }, /* GL_MATRIX15_ARB */ - { 17090, 0x000088D0 }, /* GL_MATRIX16_ARB */ - { 17106, 0x000088D1 }, /* GL_MATRIX17_ARB */ - { 17122, 0x000088D2 }, /* GL_MATRIX18_ARB */ - { 17138, 0x000088D3 }, /* GL_MATRIX19_ARB */ - { 17154, 0x000088C1 }, /* GL_MATRIX1_ARB */ - { 17169, 0x00008631 }, /* GL_MATRIX1_NV */ - { 17183, 0x000088D4 }, /* GL_MATRIX20_ARB */ - { 17199, 0x000088D5 }, /* GL_MATRIX21_ARB */ - { 17215, 0x000088D6 }, /* GL_MATRIX22_ARB */ - { 17231, 0x000088D7 }, /* GL_MATRIX23_ARB */ - { 17247, 0x000088D8 }, /* GL_MATRIX24_ARB */ - { 17263, 0x000088D9 }, /* GL_MATRIX25_ARB */ - { 17279, 0x000088DA }, /* GL_MATRIX26_ARB */ - { 17295, 0x000088DB }, /* GL_MATRIX27_ARB */ - { 17311, 0x000088DC }, /* GL_MATRIX28_ARB */ - { 17327, 0x000088DD }, /* GL_MATRIX29_ARB */ - { 17343, 0x000088C2 }, /* GL_MATRIX2_ARB */ - { 17358, 0x00008632 }, /* GL_MATRIX2_NV */ - { 17372, 0x000088DE }, /* GL_MATRIX30_ARB */ - { 17388, 0x000088DF }, /* GL_MATRIX31_ARB */ - { 17404, 0x000088C3 }, /* GL_MATRIX3_ARB */ - { 17419, 0x00008633 }, /* GL_MATRIX3_NV */ - { 17433, 0x000088C4 }, /* GL_MATRIX4_ARB */ - { 17448, 0x00008634 }, /* GL_MATRIX4_NV */ - { 17462, 0x000088C5 }, /* GL_MATRIX5_ARB */ - { 17477, 0x00008635 }, /* GL_MATRIX5_NV */ - { 17491, 0x000088C6 }, /* GL_MATRIX6_ARB */ - { 17506, 0x00008636 }, /* GL_MATRIX6_NV */ - { 17520, 0x000088C7 }, /* GL_MATRIX7_ARB */ - { 17535, 0x00008637 }, /* GL_MATRIX7_NV */ - { 17549, 0x000088C8 }, /* GL_MATRIX8_ARB */ - { 17564, 0x000088C9 }, /* GL_MATRIX9_ARB */ - { 17579, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */ - { 17605, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ - { 17639, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ - { 17670, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ - { 17703, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ - { 17734, 0x00000BA0 }, /* GL_MATRIX_MODE */ - { 17749, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */ - { 17771, 0x00008008 }, /* GL_MAX */ - { 17778, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */ - { 17801, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ - { 17833, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */ - { 17859, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ - { 17892, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ - { 17918, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - { 17952, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */ - { 17971, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */ - { 17996, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */ - { 18025, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ - { 18057, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */ - { 18093, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ - { 18129, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */ - { 18169, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */ - { 18195, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */ - { 18225, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */ - { 18250, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */ - { 18279, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ - { 18308, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */ - { 18341, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */ - { 18361, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */ - { 18385, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */ - { 18409, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */ - { 18433, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */ - { 18458, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */ - { 18476, 0x00008008 }, /* GL_MAX_EXT */ - { 18487, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ - { 18522, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */ - { 18561, 0x00000D31 }, /* GL_MAX_LIGHTS */ - { 18575, 0x00000B31 }, /* GL_MAX_LIST_NESTING */ - { 18595, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ - { 18633, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */ - { 18662, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */ - { 18686, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */ - { 18714, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */ - { 18737, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ - { 18774, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ - { 18810, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ - { 18837, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ - { 18866, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ - { 18900, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ - { 18936, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ - { 18963, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ - { 18995, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ - { 19031, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ - { 19060, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ - { 19089, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */ - { 19117, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ - { 19155, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - { 19199, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - { 19242, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ - { 19276, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - { 19315, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ - { 19352, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ - { 19390, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - { 19433, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - { 19476, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ - { 19506, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ - { 19537, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ - { 19573, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ - { 19609, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */ - { 19639, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ - { 19673, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */ - { 19706, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */ - { 19731, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */ - { 19760, 0x00008D57 }, /* GL_MAX_SAMPLES */ - { 19775, 0x00008D57 }, /* GL_MAX_SAMPLES_EXT */ - { 19794, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */ - { 19821, 0x00008504 }, /* GL_MAX_SHININESS_NV */ - { 19841, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */ - { 19865, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */ - { 19887, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */ - { 19913, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */ - { 19940, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */ - { 19971, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */ - { 19995, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ - { 20029, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */ - { 20049, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */ - { 20076, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */ - { 20097, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */ - { 20122, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */ - { 20147, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */ - { 20182, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */ - { 20204, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */ - { 20230, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */ - { 20252, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */ - { 20278, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ - { 20312, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ - { 20350, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ - { 20383, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */ - { 20420, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */ - { 20444, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */ - { 20465, 0x00008007 }, /* GL_MIN */ - { 20472, 0x0000802E }, /* GL_MINMAX */ - { 20482, 0x0000802E }, /* GL_MINMAX_EXT */ - { 20496, 0x0000802F }, /* GL_MINMAX_FORMAT */ - { 20513, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */ - { 20534, 0x00008030 }, /* GL_MINMAX_SINK */ - { 20549, 0x00008030 }, /* GL_MINMAX_SINK_EXT */ - { 20568, 0x00008007 }, /* GL_MIN_EXT */ - { 20579, 0x00008370 }, /* GL_MIRRORED_REPEAT */ - { 20598, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */ - { 20621, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */ - { 20644, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */ - { 20664, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */ - { 20684, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ - { 20714, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */ - { 20742, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ - { 20770, 0x00001700 }, /* GL_MODELVIEW */ - { 20783, 0x00001700 }, /* GL_MODELVIEW0_ARB */ - { 20801, 0x0000872A }, /* GL_MODELVIEW10_ARB */ - { 20820, 0x0000872B }, /* GL_MODELVIEW11_ARB */ - { 20839, 0x0000872C }, /* GL_MODELVIEW12_ARB */ - { 20858, 0x0000872D }, /* GL_MODELVIEW13_ARB */ - { 20877, 0x0000872E }, /* GL_MODELVIEW14_ARB */ - { 20896, 0x0000872F }, /* GL_MODELVIEW15_ARB */ - { 20915, 0x00008730 }, /* GL_MODELVIEW16_ARB */ - { 20934, 0x00008731 }, /* GL_MODELVIEW17_ARB */ - { 20953, 0x00008732 }, /* GL_MODELVIEW18_ARB */ - { 20972, 0x00008733 }, /* GL_MODELVIEW19_ARB */ - { 20991, 0x0000850A }, /* GL_MODELVIEW1_ARB */ - { 21009, 0x00008734 }, /* GL_MODELVIEW20_ARB */ - { 21028, 0x00008735 }, /* GL_MODELVIEW21_ARB */ - { 21047, 0x00008736 }, /* GL_MODELVIEW22_ARB */ - { 21066, 0x00008737 }, /* GL_MODELVIEW23_ARB */ - { 21085, 0x00008738 }, /* GL_MODELVIEW24_ARB */ - { 21104, 0x00008739 }, /* GL_MODELVIEW25_ARB */ - { 21123, 0x0000873A }, /* GL_MODELVIEW26_ARB */ - { 21142, 0x0000873B }, /* GL_MODELVIEW27_ARB */ - { 21161, 0x0000873C }, /* GL_MODELVIEW28_ARB */ - { 21180, 0x0000873D }, /* GL_MODELVIEW29_ARB */ - { 21199, 0x00008722 }, /* GL_MODELVIEW2_ARB */ - { 21217, 0x0000873E }, /* GL_MODELVIEW30_ARB */ - { 21236, 0x0000873F }, /* GL_MODELVIEW31_ARB */ - { 21255, 0x00008723 }, /* GL_MODELVIEW3_ARB */ - { 21273, 0x00008724 }, /* GL_MODELVIEW4_ARB */ - { 21291, 0x00008725 }, /* GL_MODELVIEW5_ARB */ - { 21309, 0x00008726 }, /* GL_MODELVIEW6_ARB */ - { 21327, 0x00008727 }, /* GL_MODELVIEW7_ARB */ - { 21345, 0x00008728 }, /* GL_MODELVIEW8_ARB */ - { 21363, 0x00008729 }, /* GL_MODELVIEW9_ARB */ - { 21381, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */ - { 21401, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */ - { 21428, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */ - { 21453, 0x00002100 }, /* GL_MODULATE */ - { 21465, 0x00008744 }, /* GL_MODULATE_ADD_ATI */ - { 21485, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */ - { 21512, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */ - { 21537, 0x00000103 }, /* GL_MULT */ - { 21545, 0x0000809D }, /* GL_MULTISAMPLE */ - { 21560, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */ - { 21580, 0x0000809D }, /* GL_MULTISAMPLE_ARB */ - { 21599, 0x20000000 }, /* GL_MULTISAMPLE_BIT */ - { 21618, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */ - { 21642, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */ - { 21665, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */ - { 21695, 0x00002A25 }, /* GL_N3F_V3F */ - { 21706, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */ - { 21726, 0x0000150E }, /* GL_NAND */ - { 21734, 0x00002600 }, /* GL_NEAREST */ - { 21745, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ - { 21776, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ - { 21808, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */ - { 21833, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */ - { 21859, 0x00000200 }, /* GL_NEVER */ - { 21868, 0x00001102 }, /* GL_NICEST */ - { 21878, 0x00000000 }, /* GL_NONE */ - { 21886, 0x00001505 }, /* GL_NOOP */ - { 21894, 0x00001508 }, /* GL_NOR */ - { 21901, 0x00000BA1 }, /* GL_NORMALIZE */ - { 21914, 0x00008075 }, /* GL_NORMAL_ARRAY */ - { 21930, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ - { 21961, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */ - { 21996, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */ - { 22020, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */ - { 22043, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */ - { 22064, 0x00008511 }, /* GL_NORMAL_MAP */ - { 22078, 0x00008511 }, /* GL_NORMAL_MAP_ARB */ - { 22096, 0x00008511 }, /* GL_NORMAL_MAP_NV */ - { 22113, 0x00000205 }, /* GL_NOTEQUAL */ - { 22125, 0x00000000 }, /* GL_NO_ERROR */ - { 22137, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ - { 22171, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */ - { 22209, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */ - { 22241, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */ - { 22283, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */ - { 22313, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */ - { 22353, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */ - { 22384, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */ - { 22413, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */ - { 22441, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */ - { 22471, 0x00002401 }, /* GL_OBJECT_LINEAR */ - { 22488, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */ - { 22514, 0x00002501 }, /* GL_OBJECT_PLANE */ - { 22530, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */ - { 22565, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */ - { 22587, 0x00009112 }, /* GL_OBJECT_TYPE */ - { 22602, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */ - { 22621, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */ - { 22651, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */ - { 22672, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */ - { 22700, 0x00000001 }, /* GL_ONE */ - { 22707, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */ - { 22735, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */ - { 22767, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */ - { 22795, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */ - { 22827, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */ - { 22850, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */ - { 22873, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */ - { 22896, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */ - { 22919, 0x00008598 }, /* GL_OPERAND0_ALPHA */ - { 22937, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */ - { 22959, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */ - { 22981, 0x00008590 }, /* GL_OPERAND0_RGB */ - { 22997, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */ - { 23017, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */ - { 23037, 0x00008599 }, /* GL_OPERAND1_ALPHA */ - { 23055, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */ - { 23077, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */ - { 23099, 0x00008591 }, /* GL_OPERAND1_RGB */ - { 23115, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */ - { 23135, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */ - { 23155, 0x0000859A }, /* GL_OPERAND2_ALPHA */ - { 23173, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */ - { 23195, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */ - { 23217, 0x00008592 }, /* GL_OPERAND2_RGB */ - { 23233, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */ - { 23253, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */ - { 23273, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */ - { 23294, 0x00008593 }, /* GL_OPERAND3_RGB_NV */ - { 23313, 0x00001507 }, /* GL_OR */ - { 23319, 0x00000A01 }, /* GL_ORDER */ - { 23328, 0x0000150D }, /* GL_OR_INVERTED */ - { 23343, 0x0000150B }, /* GL_OR_REVERSE */ - { 23357, 0x00000505 }, /* GL_OUT_OF_MEMORY */ - { 23374, 0x00000D05 }, /* GL_PACK_ALIGNMENT */ - { 23392, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */ - { 23413, 0x00008758 }, /* GL_PACK_INVERT_MESA */ - { 23433, 0x00000D01 }, /* GL_PACK_LSB_FIRST */ - { 23451, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */ - { 23470, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */ - { 23490, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */ - { 23510, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */ - { 23528, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */ - { 23547, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */ - { 23572, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */ - { 23596, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */ - { 23617, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */ - { 23639, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */ - { 23661, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */ - { 23686, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */ - { 23710, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */ - { 23731, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */ - { 23753, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */ - { 23775, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */ - { 23797, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */ - { 23828, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */ - { 23848, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */ - { 23873, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */ - { 23893, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */ - { 23918, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */ - { 23938, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */ - { 23963, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */ - { 23983, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */ - { 24008, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */ - { 24028, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */ - { 24053, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */ - { 24073, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */ - { 24098, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */ - { 24118, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */ - { 24143, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */ - { 24163, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */ - { 24188, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */ - { 24208, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */ - { 24233, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */ - { 24253, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */ - { 24278, 0x00000020 }, /* GL_PIXEL_MODE_BIT */ - { 24296, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */ - { 24317, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */ - { 24346, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */ - { 24379, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */ - { 24404, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */ - { 24427, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */ - { 24458, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */ - { 24493, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */ - { 24520, 0x00001B00 }, /* GL_POINT */ - { 24529, 0x00000000 }, /* GL_POINTS */ - { 24539, 0x00000002 }, /* GL_POINT_BIT */ - { 24552, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */ - { 24582, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */ - { 24616, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */ - { 24650, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */ - { 24685, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */ - { 24714, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */ - { 24747, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */ - { 24780, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */ - { 24814, 0x00000B11 }, /* GL_POINT_SIZE */ - { 24828, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */ - { 24854, 0x00008127 }, /* GL_POINT_SIZE_MAX */ - { 24872, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */ - { 24894, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */ - { 24916, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */ - { 24939, 0x00008126 }, /* GL_POINT_SIZE_MIN */ - { 24957, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */ - { 24979, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */ - { 25001, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */ - { 25024, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */ - { 25044, 0x00000B10 }, /* GL_POINT_SMOOTH */ - { 25060, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */ - { 25081, 0x00008861 }, /* GL_POINT_SPRITE */ - { 25097, 0x00008861 }, /* GL_POINT_SPRITE_ARB */ - { 25117, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */ - { 25146, 0x00008861 }, /* GL_POINT_SPRITE_NV */ - { 25165, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */ - { 25191, 0x00000701 }, /* GL_POINT_TOKEN */ - { 25206, 0x00000009 }, /* GL_POLYGON */ - { 25217, 0x00000008 }, /* GL_POLYGON_BIT */ - { 25232, 0x00000B40 }, /* GL_POLYGON_MODE */ - { 25248, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */ - { 25271, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */ - { 25296, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */ - { 25319, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */ - { 25342, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */ - { 25366, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */ - { 25390, 0x00000B41 }, /* GL_POLYGON_SMOOTH */ - { 25408, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */ - { 25431, 0x00000B42 }, /* GL_POLYGON_STIPPLE */ - { 25450, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */ - { 25473, 0x00000703 }, /* GL_POLYGON_TOKEN */ - { 25490, 0x00001203 }, /* GL_POSITION */ - { 25502, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ - { 25534, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */ - { 25570, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ - { 25603, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */ - { 25640, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ - { 25671, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */ - { 25706, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ - { 25738, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */ - { 25774, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ - { 25807, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ - { 25839, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */ - { 25875, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ - { 25908, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */ - { 25945, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */ - { 25975, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */ - { 26009, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */ - { 26040, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */ - { 26075, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ - { 26106, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */ - { 26141, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ - { 26173, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */ - { 26209, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */ - { 26239, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */ - { 26273, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */ - { 26304, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */ - { 26339, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */ - { 26371, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */ - { 26402, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */ - { 26437, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */ - { 26469, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */ - { 26505, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */ - { 26534, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */ - { 26567, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */ - { 26597, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */ - { 26631, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ - { 26670, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ - { 26703, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ - { 26743, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ - { 26777, 0x00008578 }, /* GL_PREVIOUS */ - { 26789, 0x00008578 }, /* GL_PREVIOUS_ARB */ - { 26805, 0x00008578 }, /* GL_PREVIOUS_EXT */ - { 26821, 0x00008577 }, /* GL_PRIMARY_COLOR */ - { 26838, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */ - { 26859, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */ - { 26880, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ - { 26913, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ - { 26945, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */ - { 26968, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */ - { 26991, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */ - { 27021, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */ - { 27050, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */ - { 27078, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */ - { 27100, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */ - { 27128, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */ - { 27156, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */ - { 27178, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */ - { 27199, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - { 27239, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - { 27278, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ - { 27308, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - { 27343, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ - { 27376, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ - { 27410, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - { 27449, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - { 27488, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */ - { 27510, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */ - { 27536, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */ - { 27560, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */ - { 27583, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */ - { 27605, 0x00008628 }, /* GL_PROGRAM_STRING_NV */ - { 27626, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */ - { 27647, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */ - { 27674, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ - { 27706, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ - { 27738, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ - { 27773, 0x00001701 }, /* GL_PROJECTION */ - { 27787, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */ - { 27808, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */ - { 27834, 0x00008E4F }, /* GL_PROVOKING_VERTEX */ - { 27854, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */ - { 27878, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */ - { 27899, 0x00008025 }, /* GL_PROXY_HISTOGRAM */ - { 27918, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */ - { 27941, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ - { 27980, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ - { 28018, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */ - { 28038, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ - { 28068, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */ - { 28092, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */ - { 28112, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ - { 28142, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */ - { 28166, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */ - { 28186, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ - { 28219, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */ - { 28245, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */ - { 28275, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ - { 28306, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */ - { 28336, 0x00002003 }, /* GL_Q */ - { 28341, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */ - { 28366, 0x00000007 }, /* GL_QUADS */ - { 28375, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ - { 28419, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */ - { 28467, 0x00008614 }, /* GL_QUAD_MESH_SUN */ - { 28484, 0x00000008 }, /* GL_QUAD_STRIP */ - { 28498, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT_NV */ - { 28528, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT_NV */ - { 28555, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */ - { 28577, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */ - { 28603, 0x00008E14 }, /* GL_QUERY_NO_WAIT_NV */ - { 28623, 0x00008866 }, /* GL_QUERY_RESULT */ - { 28639, 0x00008866 }, /* GL_QUERY_RESULT_ARB */ - { 28659, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */ - { 28685, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */ - { 28715, 0x00008E13 }, /* GL_QUERY_WAIT_NV */ - { 28732, 0x00002002 }, /* GL_R */ - { 28737, 0x00002A10 }, /* GL_R3_G3_B2 */ - { 28749, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ - { 28782, 0x00000C02 }, /* GL_READ_BUFFER */ - { 28797, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */ - { 28817, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */ - { 28845, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */ - { 28877, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */ - { 28901, 0x000088B8 }, /* GL_READ_ONLY */ - { 28914, 0x000088B8 }, /* GL_READ_ONLY_ARB */ - { 28931, 0x000088BA }, /* GL_READ_WRITE */ - { 28945, 0x000088BA }, /* GL_READ_WRITE_ARB */ - { 28963, 0x00001903 }, /* GL_RED */ - { 28970, 0x00008016 }, /* GL_REDUCE */ - { 28980, 0x00008016 }, /* GL_REDUCE_EXT */ - { 28994, 0x00000D15 }, /* GL_RED_BIAS */ - { 29006, 0x00000D52 }, /* GL_RED_BITS */ - { 29018, 0x00000D14 }, /* GL_RED_SCALE */ - { 29031, 0x00008512 }, /* GL_REFLECTION_MAP */ - { 29049, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */ - { 29071, 0x00008512 }, /* GL_REFLECTION_MAP_NV */ - { 29092, 0x00001C00 }, /* GL_RENDER */ - { 29102, 0x00008D41 }, /* GL_RENDERBUFFER */ - { 29118, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */ - { 29145, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */ - { 29169, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */ - { 29197, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */ - { 29223, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */ - { 29250, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */ - { 29270, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */ - { 29297, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */ - { 29320, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */ - { 29347, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */ - { 29379, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */ - { 29415, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */ - { 29440, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */ - { 29464, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */ - { 29492, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */ - { 29521, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */ - { 29543, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */ - { 29569, 0x00001F01 }, /* GL_RENDERER */ - { 29581, 0x00000C40 }, /* GL_RENDER_MODE */ - { 29596, 0x00002901 }, /* GL_REPEAT */ - { 29606, 0x00001E01 }, /* GL_REPLACE */ - { 29617, 0x00008062 }, /* GL_REPLACE_EXT */ - { 29632, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */ - { 29655, 0x0000803A }, /* GL_RESCALE_NORMAL */ - { 29673, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */ - { 29695, 0x00000102 }, /* GL_RETURN */ - { 29705, 0x00001907 }, /* GL_RGB */ - { 29712, 0x00008052 }, /* GL_RGB10 */ - { 29721, 0x00008059 }, /* GL_RGB10_A2 */ - { 29733, 0x00008059 }, /* GL_RGB10_A2_EXT */ - { 29749, 0x00008052 }, /* GL_RGB10_EXT */ - { 29762, 0x00008053 }, /* GL_RGB12 */ - { 29771, 0x00008053 }, /* GL_RGB12_EXT */ - { 29784, 0x00008054 }, /* GL_RGB16 */ - { 29793, 0x00008054 }, /* GL_RGB16_EXT */ - { 29806, 0x0000804E }, /* GL_RGB2_EXT */ - { 29818, 0x0000804F }, /* GL_RGB4 */ - { 29826, 0x0000804F }, /* GL_RGB4_EXT */ - { 29838, 0x000083A1 }, /* GL_RGB4_S3TC */ - { 29851, 0x00008050 }, /* GL_RGB5 */ - { 29859, 0x00008057 }, /* GL_RGB5_A1 */ - { 29870, 0x00008057 }, /* GL_RGB5_A1_EXT */ - { 29885, 0x00008050 }, /* GL_RGB5_EXT */ - { 29897, 0x00008051 }, /* GL_RGB8 */ - { 29905, 0x00008051 }, /* GL_RGB8_EXT */ - { 29917, 0x00001908 }, /* GL_RGBA */ - { 29925, 0x0000805A }, /* GL_RGBA12 */ - { 29935, 0x0000805A }, /* GL_RGBA12_EXT */ - { 29949, 0x0000805B }, /* GL_RGBA16 */ - { 29959, 0x0000805B }, /* GL_RGBA16_EXT */ - { 29973, 0x00008055 }, /* GL_RGBA2 */ - { 29982, 0x00008055 }, /* GL_RGBA2_EXT */ - { 29995, 0x00008056 }, /* GL_RGBA4 */ - { 30004, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */ - { 30023, 0x00008056 }, /* GL_RGBA4_EXT */ - { 30036, 0x000083A3 }, /* GL_RGBA4_S3TC */ - { 30050, 0x00008058 }, /* GL_RGBA8 */ - { 30059, 0x00008058 }, /* GL_RGBA8_EXT */ - { 30072, 0x00008F97 }, /* GL_RGBA8_SNORM */ - { 30087, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */ - { 30105, 0x00000C31 }, /* GL_RGBA_MODE */ - { 30118, 0x000083A2 }, /* GL_RGBA_S3TC */ - { 30131, 0x00008F93 }, /* GL_RGBA_SNORM */ - { 30145, 0x000083A0 }, /* GL_RGB_S3TC */ - { 30157, 0x00008573 }, /* GL_RGB_SCALE */ - { 30170, 0x00008573 }, /* GL_RGB_SCALE_ARB */ - { 30187, 0x00008573 }, /* GL_RGB_SCALE_EXT */ - { 30204, 0x00000407 }, /* GL_RIGHT */ - { 30213, 0x00002000 }, /* GL_S */ - { 30218, 0x00008B5D }, /* GL_SAMPLER_1D */ - { 30232, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */ - { 30253, 0x00008B5E }, /* GL_SAMPLER_2D */ - { 30267, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */ - { 30288, 0x00008B5F }, /* GL_SAMPLER_3D */ - { 30302, 0x00008B60 }, /* GL_SAMPLER_CUBE */ - { 30318, 0x000080A9 }, /* GL_SAMPLES */ - { 30329, 0x000086B4 }, /* GL_SAMPLES_3DFX */ - { 30345, 0x000080A9 }, /* GL_SAMPLES_ARB */ - { 30360, 0x00008914 }, /* GL_SAMPLES_PASSED */ - { 30378, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */ - { 30400, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ - { 30428, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */ - { 30460, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */ - { 30483, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */ - { 30510, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */ - { 30528, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */ - { 30551, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */ - { 30573, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */ - { 30592, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */ - { 30615, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */ - { 30641, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */ - { 30671, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */ - { 30696, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */ - { 30725, 0x00080000 }, /* GL_SCISSOR_BIT */ - { 30740, 0x00000C10 }, /* GL_SCISSOR_BOX */ - { 30755, 0x00000C11 }, /* GL_SCISSOR_TEST */ - { 30771, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */ - { 30796, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ - { 30836, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */ - { 30880, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ - { 30913, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ - { 30943, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ - { 30975, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ - { 31005, 0x00001C02 }, /* GL_SELECT */ - { 31015, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */ - { 31043, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */ - { 31068, 0x00008012 }, /* GL_SEPARABLE_2D */ - { 31084, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */ - { 31111, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */ - { 31142, 0x0000150F }, /* GL_SET */ - { 31149, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */ - { 31170, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */ - { 31194, 0x00008B4F }, /* GL_SHADER_TYPE */ - { 31209, 0x00000B54 }, /* GL_SHADE_MODEL */ - { 31224, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */ - { 31252, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */ - { 31275, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */ - { 31305, 0x00001601 }, /* GL_SHININESS */ - { 31318, 0x00001402 }, /* GL_SHORT */ - { 31327, 0x00009119 }, /* GL_SIGNALED */ - { 31339, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */ - { 31360, 0x000081F9 }, /* GL_SINGLE_COLOR */ - { 31376, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */ - { 31396, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */ - { 31415, 0x00008C46 }, /* GL_SLUMINANCE */ - { 31429, 0x00008C47 }, /* GL_SLUMINANCE8 */ - { 31444, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */ - { 31466, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */ - { 31486, 0x00001D01 }, /* GL_SMOOTH */ - { 31496, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */ - { 31529, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */ - { 31556, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */ - { 31589, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */ - { 31616, 0x00008588 }, /* GL_SOURCE0_ALPHA */ - { 31633, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */ - { 31654, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */ - { 31675, 0x00008580 }, /* GL_SOURCE0_RGB */ - { 31690, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */ - { 31709, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */ - { 31728, 0x00008589 }, /* GL_SOURCE1_ALPHA */ - { 31745, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */ - { 31766, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */ - { 31787, 0x00008581 }, /* GL_SOURCE1_RGB */ - { 31802, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */ - { 31821, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */ - { 31840, 0x0000858A }, /* GL_SOURCE2_ALPHA */ - { 31857, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */ - { 31878, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */ - { 31899, 0x00008582 }, /* GL_SOURCE2_RGB */ - { 31914, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */ - { 31933, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */ - { 31952, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */ - { 31972, 0x00008583 }, /* GL_SOURCE3_RGB_NV */ - { 31990, 0x00001202 }, /* GL_SPECULAR */ - { 32002, 0x00002402 }, /* GL_SPHERE_MAP */ - { 32016, 0x00001206 }, /* GL_SPOT_CUTOFF */ - { 32031, 0x00001204 }, /* GL_SPOT_DIRECTION */ - { 32049, 0x00001205 }, /* GL_SPOT_EXPONENT */ - { 32066, 0x00008588 }, /* GL_SRC0_ALPHA */ - { 32080, 0x00008580 }, /* GL_SRC0_RGB */ - { 32092, 0x00008589 }, /* GL_SRC1_ALPHA */ - { 32106, 0x00008581 }, /* GL_SRC1_RGB */ - { 32118, 0x0000858A }, /* GL_SRC2_ALPHA */ - { 32132, 0x00008582 }, /* GL_SRC2_RGB */ - { 32144, 0x00000302 }, /* GL_SRC_ALPHA */ - { 32157, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */ - { 32179, 0x00000300 }, /* GL_SRC_COLOR */ - { 32192, 0x00008C40 }, /* GL_SRGB */ - { 32200, 0x00008C41 }, /* GL_SRGB8 */ - { 32209, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */ - { 32225, 0x00008C42 }, /* GL_SRGB_ALPHA */ - { 32239, 0x00000503 }, /* GL_STACK_OVERFLOW */ - { 32257, 0x00000504 }, /* GL_STACK_UNDERFLOW */ - { 32276, 0x000088E6 }, /* GL_STATIC_COPY */ - { 32291, 0x000088E6 }, /* GL_STATIC_COPY_ARB */ - { 32310, 0x000088E4 }, /* GL_STATIC_DRAW */ - { 32325, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */ - { 32344, 0x000088E5 }, /* GL_STATIC_READ */ - { 32359, 0x000088E5 }, /* GL_STATIC_READ_ARB */ - { 32378, 0x00001802 }, /* GL_STENCIL */ - { 32389, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */ - { 32411, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */ - { 32437, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */ - { 32458, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */ - { 32483, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */ - { 32504, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */ - { 32529, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ - { 32561, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */ - { 32597, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ - { 32629, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */ - { 32665, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */ - { 32685, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */ - { 32712, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */ - { 32738, 0x00000D57 }, /* GL_STENCIL_BITS */ - { 32754, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */ - { 32776, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */ - { 32799, 0x00000B94 }, /* GL_STENCIL_FAIL */ - { 32815, 0x00000B92 }, /* GL_STENCIL_FUNC */ - { 32831, 0x00001901 }, /* GL_STENCIL_INDEX */ - { 32848, 0x00008D46 }, /* GL_STENCIL_INDEX1 */ - { 32866, 0x00008D49 }, /* GL_STENCIL_INDEX16 */ - { 32885, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */ - { 32908, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */ - { 32930, 0x00008D47 }, /* GL_STENCIL_INDEX4 */ - { 32948, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */ - { 32970, 0x00008D48 }, /* GL_STENCIL_INDEX8 */ - { 32988, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */ - { 33010, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */ - { 33031, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */ - { 33058, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */ - { 33085, 0x00000B97 }, /* GL_STENCIL_REF */ - { 33100, 0x00000B90 }, /* GL_STENCIL_TEST */ - { 33116, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ - { 33145, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */ - { 33167, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */ - { 33188, 0x00000C33 }, /* GL_STEREO */ - { 33198, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */ - { 33222, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */ - { 33247, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */ - { 33271, 0x000088E2 }, /* GL_STREAM_COPY */ - { 33286, 0x000088E2 }, /* GL_STREAM_COPY_ARB */ - { 33305, 0x000088E0 }, /* GL_STREAM_DRAW */ - { 33320, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */ - { 33339, 0x000088E1 }, /* GL_STREAM_READ */ - { 33354, 0x000088E1 }, /* GL_STREAM_READ_ARB */ - { 33373, 0x00000D50 }, /* GL_SUBPIXEL_BITS */ - { 33390, 0x000084E7 }, /* GL_SUBTRACT */ - { 33402, 0x000084E7 }, /* GL_SUBTRACT_ARB */ - { 33418, 0x00009113 }, /* GL_SYNC_CONDITION */ - { 33436, 0x00009116 }, /* GL_SYNC_FENCE */ - { 33450, 0x00009115 }, /* GL_SYNC_FLAGS */ - { 33464, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */ - { 33491, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */ - { 33521, 0x00009114 }, /* GL_SYNC_STATUS */ - { 33536, 0x00002001 }, /* GL_T */ - { 33541, 0x00002A2A }, /* GL_T2F_C3F_V3F */ - { 33556, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */ - { 33575, 0x00002A29 }, /* GL_T2F_C4UB_V3F */ - { 33591, 0x00002A2B }, /* GL_T2F_N3F_V3F */ - { 33606, 0x00002A27 }, /* GL_T2F_V3F */ - { 33617, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */ - { 33636, 0x00002A28 }, /* GL_T4F_V4F */ - { 33647, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */ - { 33670, 0x00001702 }, /* GL_TEXTURE */ - { 33681, 0x000084C0 }, /* GL_TEXTURE0 */ - { 33693, 0x000084C0 }, /* GL_TEXTURE0_ARB */ - { 33709, 0x000084C1 }, /* GL_TEXTURE1 */ - { 33721, 0x000084CA }, /* GL_TEXTURE10 */ - { 33734, 0x000084CA }, /* GL_TEXTURE10_ARB */ - { 33751, 0x000084CB }, /* GL_TEXTURE11 */ - { 33764, 0x000084CB }, /* GL_TEXTURE11_ARB */ - { 33781, 0x000084CC }, /* GL_TEXTURE12 */ - { 33794, 0x000084CC }, /* GL_TEXTURE12_ARB */ - { 33811, 0x000084CD }, /* GL_TEXTURE13 */ - { 33824, 0x000084CD }, /* GL_TEXTURE13_ARB */ - { 33841, 0x000084CE }, /* GL_TEXTURE14 */ - { 33854, 0x000084CE }, /* GL_TEXTURE14_ARB */ - { 33871, 0x000084CF }, /* GL_TEXTURE15 */ - { 33884, 0x000084CF }, /* GL_TEXTURE15_ARB */ - { 33901, 0x000084D0 }, /* GL_TEXTURE16 */ - { 33914, 0x000084D0 }, /* GL_TEXTURE16_ARB */ - { 33931, 0x000084D1 }, /* GL_TEXTURE17 */ - { 33944, 0x000084D1 }, /* GL_TEXTURE17_ARB */ - { 33961, 0x000084D2 }, /* GL_TEXTURE18 */ - { 33974, 0x000084D2 }, /* GL_TEXTURE18_ARB */ - { 33991, 0x000084D3 }, /* GL_TEXTURE19 */ - { 34004, 0x000084D3 }, /* GL_TEXTURE19_ARB */ - { 34021, 0x000084C1 }, /* GL_TEXTURE1_ARB */ - { 34037, 0x000084C2 }, /* GL_TEXTURE2 */ - { 34049, 0x000084D4 }, /* GL_TEXTURE20 */ - { 34062, 0x000084D4 }, /* GL_TEXTURE20_ARB */ - { 34079, 0x000084D5 }, /* GL_TEXTURE21 */ - { 34092, 0x000084D5 }, /* GL_TEXTURE21_ARB */ - { 34109, 0x000084D6 }, /* GL_TEXTURE22 */ - { 34122, 0x000084D6 }, /* GL_TEXTURE22_ARB */ - { 34139, 0x000084D7 }, /* GL_TEXTURE23 */ - { 34152, 0x000084D7 }, /* GL_TEXTURE23_ARB */ - { 34169, 0x000084D8 }, /* GL_TEXTURE24 */ - { 34182, 0x000084D8 }, /* GL_TEXTURE24_ARB */ - { 34199, 0x000084D9 }, /* GL_TEXTURE25 */ - { 34212, 0x000084D9 }, /* GL_TEXTURE25_ARB */ - { 34229, 0x000084DA }, /* GL_TEXTURE26 */ - { 34242, 0x000084DA }, /* GL_TEXTURE26_ARB */ - { 34259, 0x000084DB }, /* GL_TEXTURE27 */ - { 34272, 0x000084DB }, /* GL_TEXTURE27_ARB */ - { 34289, 0x000084DC }, /* GL_TEXTURE28 */ - { 34302, 0x000084DC }, /* GL_TEXTURE28_ARB */ - { 34319, 0x000084DD }, /* GL_TEXTURE29 */ - { 34332, 0x000084DD }, /* GL_TEXTURE29_ARB */ - { 34349, 0x000084C2 }, /* GL_TEXTURE2_ARB */ - { 34365, 0x000084C3 }, /* GL_TEXTURE3 */ - { 34377, 0x000084DE }, /* GL_TEXTURE30 */ - { 34390, 0x000084DE }, /* GL_TEXTURE30_ARB */ - { 34407, 0x000084DF }, /* GL_TEXTURE31 */ - { 34420, 0x000084DF }, /* GL_TEXTURE31_ARB */ - { 34437, 0x000084C3 }, /* GL_TEXTURE3_ARB */ - { 34453, 0x000084C4 }, /* GL_TEXTURE4 */ - { 34465, 0x000084C4 }, /* GL_TEXTURE4_ARB */ - { 34481, 0x000084C5 }, /* GL_TEXTURE5 */ - { 34493, 0x000084C5 }, /* GL_TEXTURE5_ARB */ - { 34509, 0x000084C6 }, /* GL_TEXTURE6 */ - { 34521, 0x000084C6 }, /* GL_TEXTURE6_ARB */ - { 34537, 0x000084C7 }, /* GL_TEXTURE7 */ - { 34549, 0x000084C7 }, /* GL_TEXTURE7_ARB */ - { 34565, 0x000084C8 }, /* GL_TEXTURE8 */ - { 34577, 0x000084C8 }, /* GL_TEXTURE8_ARB */ - { 34593, 0x000084C9 }, /* GL_TEXTURE9 */ - { 34605, 0x000084C9 }, /* GL_TEXTURE9_ARB */ - { 34621, 0x00000DE0 }, /* GL_TEXTURE_1D */ - { 34635, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */ - { 34659, 0x00000DE1 }, /* GL_TEXTURE_2D */ - { 34673, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */ - { 34697, 0x0000806F }, /* GL_TEXTURE_3D */ - { 34711, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */ - { 34733, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */ - { 34759, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */ - { 34781, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */ - { 34803, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ - { 34835, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */ - { 34857, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ - { 34889, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */ - { 34911, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */ - { 34939, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */ - { 34971, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ - { 35004, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */ - { 35036, 0x00040000 }, /* GL_TEXTURE_BIT */ - { 35051, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */ - { 35072, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */ - { 35097, 0x00001005 }, /* GL_TEXTURE_BORDER */ - { 35115, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */ - { 35139, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ - { 35170, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ - { 35200, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ - { 35230, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ - { 35265, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ - { 35296, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - { 35334, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */ - { 35361, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ - { 35393, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ - { 35427, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */ - { 35451, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */ - { 35479, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */ - { 35503, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */ - { 35531, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ - { 35564, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */ - { 35588, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */ - { 35610, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */ - { 35632, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */ - { 35658, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */ - { 35692, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ - { 35725, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */ - { 35762, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */ - { 35790, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */ - { 35822, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */ - { 35845, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ - { 35883, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */ - { 35925, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */ - { 35956, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */ - { 35984, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ - { 36014, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */ - { 36042, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */ - { 36062, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */ - { 36086, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ - { 36117, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */ - { 36152, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ - { 36183, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */ - { 36218, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ - { 36249, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */ - { 36284, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ - { 36315, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */ - { 36350, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ - { 36381, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */ - { 36416, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ - { 36447, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */ - { 36482, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */ - { 36511, 0x00008071 }, /* GL_TEXTURE_DEPTH */ - { 36528, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */ - { 36550, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */ - { 36576, 0x00002300 }, /* GL_TEXTURE_ENV */ - { 36591, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */ - { 36612, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */ - { 36632, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */ - { 36658, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */ - { 36678, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */ - { 36695, 0x00000C62 }, /* GL_TEXTURE_GEN_R */ - { 36712, 0x00000C60 }, /* GL_TEXTURE_GEN_S */ - { 36729, 0x00000C61 }, /* GL_TEXTURE_GEN_T */ - { 36746, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */ - { 36771, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */ - { 36793, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */ - { 36819, 0x00001001 }, /* GL_TEXTURE_HEIGHT */ - { 36837, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */ - { 36863, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */ - { 36889, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */ - { 36919, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */ - { 36946, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */ - { 36971, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */ - { 36991, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */ - { 37015, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ - { 37042, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ - { 37069, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ - { 37096, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */ - { 37122, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */ - { 37152, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */ - { 37174, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */ - { 37192, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ - { 37222, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ - { 37250, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ - { 37278, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ - { 37306, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */ - { 37327, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */ - { 37346, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */ - { 37368, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */ - { 37387, 0x00008066 }, /* GL_TEXTURE_PRIORITY */ - { 37407, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */ - { 37437, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */ - { 37468, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */ - { 37493, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */ - { 37517, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */ - { 37537, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */ - { 37561, 0x00008067 }, /* GL_TEXTURE_RESIDENT */ - { 37581, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */ - { 37604, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */ - { 37628, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */ - { 37656, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */ - { 37686, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */ - { 37711, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ - { 37745, 0x00001000 }, /* GL_TEXTURE_WIDTH */ - { 37762, 0x00008072 }, /* GL_TEXTURE_WRAP_R */ - { 37780, 0x00002802 }, /* GL_TEXTURE_WRAP_S */ - { 37798, 0x00002803 }, /* GL_TEXTURE_WRAP_T */ - { 37816, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */ - { 37835, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */ - { 37855, 0x00008648 }, /* GL_TRACK_MATRIX_NV */ - { 37874, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */ - { 37903, 0x00001000 }, /* GL_TRANSFORM_BIT */ - { 37920, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */ - { 37946, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */ - { 37976, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ - { 38008, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ - { 38038, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */ - { 38072, 0x0000862C }, /* GL_TRANSPOSE_NV */ - { 38088, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */ - { 38119, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */ - { 38154, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */ - { 38182, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */ - { 38214, 0x00000004 }, /* GL_TRIANGLES */ - { 38227, 0x00000006 }, /* GL_TRIANGLE_FAN */ - { 38243, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */ - { 38264, 0x00000005 }, /* GL_TRIANGLE_STRIP */ - { 38282, 0x00000001 }, /* GL_TRUE */ - { 38290, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */ - { 38310, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */ - { 38333, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */ - { 38353, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */ - { 38374, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */ - { 38396, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */ - { 38418, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */ - { 38438, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */ - { 38459, 0x00009118 }, /* GL_UNSIGNALED */ - { 38473, 0x00001401 }, /* GL_UNSIGNED_BYTE */ - { 38490, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */ - { 38517, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */ - { 38540, 0x00001405 }, /* GL_UNSIGNED_INT */ - { 38556, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */ - { 38583, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */ - { 38604, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */ - { 38629, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */ - { 38653, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */ - { 38684, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */ - { 38708, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */ - { 38736, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */ - { 38759, 0x00001403 }, /* GL_UNSIGNED_SHORT */ - { 38777, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ - { 38807, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */ - { 38833, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ - { 38863, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */ - { 38889, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */ - { 38913, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */ - { 38941, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */ - { 38969, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */ - { 38996, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ - { 39028, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */ - { 39059, 0x00008CA2 }, /* GL_UPPER_LEFT */ - { 39073, 0x00002A20 }, /* GL_V2F */ - { 39080, 0x00002A21 }, /* GL_V3F */ - { 39087, 0x00008B83 }, /* GL_VALIDATE_STATUS */ - { 39106, 0x00001F00 }, /* GL_VENDOR */ - { 39116, 0x00001F02 }, /* GL_VERSION */ - { 39127, 0x00008074 }, /* GL_VERTEX_ARRAY */ - { 39143, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */ - { 39167, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */ - { 39197, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ - { 39228, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */ - { 39263, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */ - { 39287, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */ - { 39308, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */ - { 39331, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */ - { 39352, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ - { 39379, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ - { 39407, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ - { 39435, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ - { 39463, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ - { 39491, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ - { 39519, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ - { 39547, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ - { 39574, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ - { 39601, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ - { 39628, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ - { 39655, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ - { 39682, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ - { 39709, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ - { 39736, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ - { 39763, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ - { 39790, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ - { 39828, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */ - { 39870, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ - { 39901, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */ - { 39936, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ - { 39970, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */ - { 40008, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ - { 40039, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */ - { 40074, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ - { 40102, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */ - { 40134, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ - { 40164, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */ - { 40198, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ - { 40226, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */ - { 40258, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */ - { 40278, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */ - { 40300, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */ - { 40329, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */ - { 40350, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */ - { 40379, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */ - { 40412, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */ - { 40444, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */ - { 40471, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */ - { 40502, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */ - { 40532, 0x00008B31 }, /* GL_VERTEX_SHADER */ - { 40549, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */ - { 40570, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */ - { 40597, 0x00000BA2 }, /* GL_VIEWPORT */ - { 40609, 0x00000800 }, /* GL_VIEWPORT_BIT */ - { 40625, 0x0000911D }, /* GL_WAIT_FAILED */ - { 40640, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */ - { 40660, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ - { 40691, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */ - { 40726, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */ - { 40754, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */ - { 40779, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ - { 40806, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */ - { 40831, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */ - { 40855, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */ - { 40874, 0x000088B9 }, /* GL_WRITE_ONLY */ - { 40888, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */ - { 40906, 0x00001506 }, /* GL_XOR */ - { 40913, 0x000085B9 }, /* GL_YCBCR_422_APPLE */ - { 40932, 0x00008757 }, /* GL_YCBCR_MESA */ - { 40946, 0x00000000 }, /* GL_ZERO */ - { 40954, 0x00000D16 }, /* GL_ZOOM_X */ - { 40964, 0x00000D17 }, /* GL_ZOOM_Y */ + { 12812, 0x0000140B }, /* GL_HALF_FLOAT */ + { 12826, 0x00008000 }, /* GL_HINT_BIT */ + { 12838, 0x00008024 }, /* GL_HISTOGRAM */ + { 12851, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */ + { 12875, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */ + { 12903, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */ + { 12926, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */ + { 12953, 0x00008024 }, /* GL_HISTOGRAM_EXT */ + { 12970, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */ + { 12990, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */ + { 13014, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */ + { 13038, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */ + { 13066, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */ + { 13094, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */ + { 13126, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */ + { 13148, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */ + { 13174, 0x0000802D }, /* GL_HISTOGRAM_SINK */ + { 13192, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */ + { 13214, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */ + { 13233, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */ + { 13256, 0x0000862A }, /* GL_IDENTITY_NV */ + { 13271, 0x00008150 }, /* GL_IGNORE_BORDER_HP */ + { 13291, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ + { 13331, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ + { 13369, 0x00001E02 }, /* GL_INCR */ + { 13377, 0x00008507 }, /* GL_INCR_WRAP */ + { 13390, 0x00008507 }, /* GL_INCR_WRAP_EXT */ + { 13407, 0x00008222 }, /* GL_INDEX */ + { 13416, 0x00008077 }, /* GL_INDEX_ARRAY */ + { 13431, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */ + { 13461, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */ + { 13495, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */ + { 13518, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */ + { 13540, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */ + { 13560, 0x00000D51 }, /* GL_INDEX_BITS */ + { 13574, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */ + { 13595, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */ + { 13613, 0x00000C30 }, /* GL_INDEX_MODE */ + { 13627, 0x00000D13 }, /* GL_INDEX_OFFSET */ + { 13643, 0x00000D12 }, /* GL_INDEX_SHIFT */ + { 13658, 0x00000C21 }, /* GL_INDEX_WRITEMASK */ + { 13677, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */ + { 13696, 0x00001404 }, /* GL_INT */ + { 13703, 0x00008049 }, /* GL_INTENSITY */ + { 13716, 0x0000804C }, /* GL_INTENSITY12 */ + { 13731, 0x0000804C }, /* GL_INTENSITY12_EXT */ + { 13750, 0x0000804D }, /* GL_INTENSITY16 */ + { 13765, 0x0000804D }, /* GL_INTENSITY16_EXT */ + { 13784, 0x0000804A }, /* GL_INTENSITY4 */ + { 13798, 0x0000804A }, /* GL_INTENSITY4_EXT */ + { 13816, 0x0000804B }, /* GL_INTENSITY8 */ + { 13830, 0x0000804B }, /* GL_INTENSITY8_EXT */ + { 13848, 0x00008049 }, /* GL_INTENSITY_EXT */ + { 13865, 0x00008575 }, /* GL_INTERPOLATE */ + { 13880, 0x00008575 }, /* GL_INTERPOLATE_ARB */ + { 13899, 0x00008575 }, /* GL_INTERPOLATE_EXT */ + { 13918, 0x00008B53 }, /* GL_INT_VEC2 */ + { 13930, 0x00008B53 }, /* GL_INT_VEC2_ARB */ + { 13946, 0x00008B54 }, /* GL_INT_VEC3 */ + { 13958, 0x00008B54 }, /* GL_INT_VEC3_ARB */ + { 13974, 0x00008B55 }, /* GL_INT_VEC4 */ + { 13986, 0x00008B55 }, /* GL_INT_VEC4_ARB */ + { 14002, 0x00000500 }, /* GL_INVALID_ENUM */ + { 14018, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */ + { 14051, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */ + { 14088, 0x00000502 }, /* GL_INVALID_OPERATION */ + { 14109, 0x00000501 }, /* GL_INVALID_VALUE */ + { 14126, 0x0000862B }, /* GL_INVERSE_NV */ + { 14140, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */ + { 14164, 0x0000150A }, /* GL_INVERT */ + { 14174, 0x00001E00 }, /* GL_KEEP */ + { 14182, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */ + { 14208, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */ + { 14238, 0x00000406 }, /* GL_LEFT */ + { 14246, 0x00000203 }, /* GL_LEQUAL */ + { 14256, 0x00000201 }, /* GL_LESS */ + { 14264, 0x00004000 }, /* GL_LIGHT0 */ + { 14274, 0x00004001 }, /* GL_LIGHT1 */ + { 14284, 0x00004002 }, /* GL_LIGHT2 */ + { 14294, 0x00004003 }, /* GL_LIGHT3 */ + { 14304, 0x00004004 }, /* GL_LIGHT4 */ + { 14314, 0x00004005 }, /* GL_LIGHT5 */ + { 14324, 0x00004006 }, /* GL_LIGHT6 */ + { 14334, 0x00004007 }, /* GL_LIGHT7 */ + { 14344, 0x00000B50 }, /* GL_LIGHTING */ + { 14356, 0x00000040 }, /* GL_LIGHTING_BIT */ + { 14372, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */ + { 14395, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */ + { 14424, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */ + { 14457, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ + { 14485, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */ + { 14509, 0x00001B01 }, /* GL_LINE */ + { 14517, 0x00002601 }, /* GL_LINEAR */ + { 14527, 0x00001208 }, /* GL_LINEAR_ATTENUATION */ + { 14549, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ + { 14579, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ + { 14610, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */ + { 14634, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */ + { 14659, 0x00000001 }, /* GL_LINES */ + { 14668, 0x00000004 }, /* GL_LINE_BIT */ + { 14680, 0x00000002 }, /* GL_LINE_LOOP */ + { 14693, 0x00000707 }, /* GL_LINE_RESET_TOKEN */ + { 14713, 0x00000B20 }, /* GL_LINE_SMOOTH */ + { 14728, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */ + { 14748, 0x00000B24 }, /* GL_LINE_STIPPLE */ + { 14764, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */ + { 14788, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */ + { 14811, 0x00000003 }, /* GL_LINE_STRIP */ + { 14825, 0x00000702 }, /* GL_LINE_TOKEN */ + { 14839, 0x00000B21 }, /* GL_LINE_WIDTH */ + { 14853, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */ + { 14879, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */ + { 14899, 0x00008B82 }, /* GL_LINK_STATUS */ + { 14914, 0x00000B32 }, /* GL_LIST_BASE */ + { 14927, 0x00020000 }, /* GL_LIST_BIT */ + { 14939, 0x00000B33 }, /* GL_LIST_INDEX */ + { 14953, 0x00000B30 }, /* GL_LIST_MODE */ + { 14966, 0x00000101 }, /* GL_LOAD */ + { 14974, 0x00000BF1 }, /* GL_LOGIC_OP */ + { 14986, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */ + { 15003, 0x00008CA1 }, /* GL_LOWER_LEFT */ + { 15017, 0x00001909 }, /* GL_LUMINANCE */ + { 15030, 0x00008041 }, /* GL_LUMINANCE12 */ + { 15045, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */ + { 15068, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */ + { 15095, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */ + { 15117, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */ + { 15143, 0x00008041 }, /* GL_LUMINANCE12_EXT */ + { 15162, 0x00008042 }, /* GL_LUMINANCE16 */ + { 15177, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */ + { 15200, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */ + { 15227, 0x00008042 }, /* GL_LUMINANCE16_EXT */ + { 15246, 0x0000803F }, /* GL_LUMINANCE4 */ + { 15260, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */ + { 15281, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */ + { 15306, 0x0000803F }, /* GL_LUMINANCE4_EXT */ + { 15324, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */ + { 15345, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */ + { 15370, 0x00008040 }, /* GL_LUMINANCE8 */ + { 15384, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */ + { 15405, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */ + { 15430, 0x00008040 }, /* GL_LUMINANCE8_EXT */ + { 15448, 0x0000190A }, /* GL_LUMINANCE_ALPHA */ + { 15467, 0x00000D90 }, /* GL_MAP1_COLOR_4 */ + { 15483, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */ + { 15503, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */ + { 15525, 0x00000D91 }, /* GL_MAP1_INDEX */ + { 15539, 0x00000D92 }, /* GL_MAP1_NORMAL */ + { 15554, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */ + { 15578, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */ + { 15602, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */ + { 15626, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */ + { 15650, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */ + { 15667, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */ + { 15684, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ + { 15712, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ + { 15741, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ + { 15770, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ + { 15799, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ + { 15828, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ + { 15857, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ + { 15886, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ + { 15914, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ + { 15942, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ + { 15970, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ + { 15998, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ + { 16026, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ + { 16054, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ + { 16082, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ + { 16110, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ + { 16138, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */ + { 16154, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */ + { 16174, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */ + { 16196, 0x00000DB1 }, /* GL_MAP2_INDEX */ + { 16210, 0x00000DB2 }, /* GL_MAP2_NORMAL */ + { 16225, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */ + { 16249, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */ + { 16273, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */ + { 16297, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */ + { 16321, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */ + { 16338, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */ + { 16355, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ + { 16383, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ + { 16412, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ + { 16441, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ + { 16470, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ + { 16499, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ + { 16528, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ + { 16557, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ + { 16585, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ + { 16613, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ + { 16641, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ + { 16669, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ + { 16697, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ + { 16725, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */ + { 16753, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ + { 16781, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ + { 16809, 0x00000D10 }, /* GL_MAP_COLOR */ + { 16822, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */ + { 16848, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */ + { 16877, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */ + { 16905, 0x00000001 }, /* GL_MAP_READ_BIT */ + { 16921, 0x00000D11 }, /* GL_MAP_STENCIL */ + { 16936, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */ + { 16962, 0x00000002 }, /* GL_MAP_WRITE_BIT */ + { 16979, 0x000088C0 }, /* GL_MATRIX0_ARB */ + { 16994, 0x00008630 }, /* GL_MATRIX0_NV */ + { 17008, 0x000088CA }, /* GL_MATRIX10_ARB */ + { 17024, 0x000088CB }, /* GL_MATRIX11_ARB */ + { 17040, 0x000088CC }, /* GL_MATRIX12_ARB */ + { 17056, 0x000088CD }, /* GL_MATRIX13_ARB */ + { 17072, 0x000088CE }, /* GL_MATRIX14_ARB */ + { 17088, 0x000088CF }, /* GL_MATRIX15_ARB */ + { 17104, 0x000088D0 }, /* GL_MATRIX16_ARB */ + { 17120, 0x000088D1 }, /* GL_MATRIX17_ARB */ + { 17136, 0x000088D2 }, /* GL_MATRIX18_ARB */ + { 17152, 0x000088D3 }, /* GL_MATRIX19_ARB */ + { 17168, 0x000088C1 }, /* GL_MATRIX1_ARB */ + { 17183, 0x00008631 }, /* GL_MATRIX1_NV */ + { 17197, 0x000088D4 }, /* GL_MATRIX20_ARB */ + { 17213, 0x000088D5 }, /* GL_MATRIX21_ARB */ + { 17229, 0x000088D6 }, /* GL_MATRIX22_ARB */ + { 17245, 0x000088D7 }, /* GL_MATRIX23_ARB */ + { 17261, 0x000088D8 }, /* GL_MATRIX24_ARB */ + { 17277, 0x000088D9 }, /* GL_MATRIX25_ARB */ + { 17293, 0x000088DA }, /* GL_MATRIX26_ARB */ + { 17309, 0x000088DB }, /* GL_MATRIX27_ARB */ + { 17325, 0x000088DC }, /* GL_MATRIX28_ARB */ + { 17341, 0x000088DD }, /* GL_MATRIX29_ARB */ + { 17357, 0x000088C2 }, /* GL_MATRIX2_ARB */ + { 17372, 0x00008632 }, /* GL_MATRIX2_NV */ + { 17386, 0x000088DE }, /* GL_MATRIX30_ARB */ + { 17402, 0x000088DF }, /* GL_MATRIX31_ARB */ + { 17418, 0x000088C3 }, /* GL_MATRIX3_ARB */ + { 17433, 0x00008633 }, /* GL_MATRIX3_NV */ + { 17447, 0x000088C4 }, /* GL_MATRIX4_ARB */ + { 17462, 0x00008634 }, /* GL_MATRIX4_NV */ + { 17476, 0x000088C5 }, /* GL_MATRIX5_ARB */ + { 17491, 0x00008635 }, /* GL_MATRIX5_NV */ + { 17505, 0x000088C6 }, /* GL_MATRIX6_ARB */ + { 17520, 0x00008636 }, /* GL_MATRIX6_NV */ + { 17534, 0x000088C7 }, /* GL_MATRIX7_ARB */ + { 17549, 0x00008637 }, /* GL_MATRIX7_NV */ + { 17563, 0x000088C8 }, /* GL_MATRIX8_ARB */ + { 17578, 0x000088C9 }, /* GL_MATRIX9_ARB */ + { 17593, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */ + { 17619, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ + { 17653, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ + { 17684, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ + { 17717, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ + { 17748, 0x00000BA0 }, /* GL_MATRIX_MODE */ + { 17763, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */ + { 17785, 0x00008008 }, /* GL_MAX */ + { 17792, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */ + { 17815, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ + { 17847, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */ + { 17873, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ + { 17906, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ + { 17932, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ + { 17966, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */ + { 17985, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */ + { 18010, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */ + { 18039, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ + { 18071, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */ + { 18107, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ + { 18143, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */ + { 18183, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */ + { 18209, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */ + { 18239, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */ + { 18264, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */ + { 18293, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ + { 18322, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */ + { 18355, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */ + { 18375, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */ + { 18399, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */ + { 18423, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */ + { 18447, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */ + { 18472, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */ + { 18490, 0x00008008 }, /* GL_MAX_EXT */ + { 18501, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ + { 18536, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */ + { 18575, 0x00000D31 }, /* GL_MAX_LIGHTS */ + { 18589, 0x00000B31 }, /* GL_MAX_LIST_NESTING */ + { 18609, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ + { 18647, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */ + { 18676, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */ + { 18700, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */ + { 18728, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */ + { 18751, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ + { 18788, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ + { 18824, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ + { 18851, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ + { 18880, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ + { 18914, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ + { 18950, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ + { 18977, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ + { 19009, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ + { 19045, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ + { 19074, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ + { 19103, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */ + { 19131, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ + { 19169, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ + { 19213, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ + { 19256, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ + { 19290, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ + { 19329, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ + { 19366, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ + { 19404, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ + { 19447, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ + { 19490, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ + { 19520, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ + { 19551, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ + { 19587, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ + { 19623, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */ + { 19653, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ + { 19687, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */ + { 19720, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */ + { 19745, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */ + { 19774, 0x00008D57 }, /* GL_MAX_SAMPLES */ + { 19789, 0x00008D57 }, /* GL_MAX_SAMPLES_EXT */ + { 19808, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */ + { 19835, 0x00008504 }, /* GL_MAX_SHININESS_NV */ + { 19855, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */ + { 19879, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */ + { 19901, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */ + { 19927, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */ + { 19954, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */ + { 19985, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */ + { 20009, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ + { 20043, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */ + { 20063, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */ + { 20090, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */ + { 20111, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */ + { 20136, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */ + { 20161, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */ + { 20196, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */ + { 20218, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */ + { 20244, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */ + { 20266, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */ + { 20292, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ + { 20326, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ + { 20364, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ + { 20397, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */ + { 20434, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */ + { 20458, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */ + { 20479, 0x00008007 }, /* GL_MIN */ + { 20486, 0x0000802E }, /* GL_MINMAX */ + { 20496, 0x0000802E }, /* GL_MINMAX_EXT */ + { 20510, 0x0000802F }, /* GL_MINMAX_FORMAT */ + { 20527, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */ + { 20548, 0x00008030 }, /* GL_MINMAX_SINK */ + { 20563, 0x00008030 }, /* GL_MINMAX_SINK_EXT */ + { 20582, 0x00008007 }, /* GL_MIN_EXT */ + { 20593, 0x00008370 }, /* GL_MIRRORED_REPEAT */ + { 20612, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */ + { 20635, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */ + { 20658, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */ + { 20678, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */ + { 20698, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ + { 20728, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */ + { 20756, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ + { 20784, 0x00001700 }, /* GL_MODELVIEW */ + { 20797, 0x00001700 }, /* GL_MODELVIEW0_ARB */ + { 20815, 0x0000872A }, /* GL_MODELVIEW10_ARB */ + { 20834, 0x0000872B }, /* GL_MODELVIEW11_ARB */ + { 20853, 0x0000872C }, /* GL_MODELVIEW12_ARB */ + { 20872, 0x0000872D }, /* GL_MODELVIEW13_ARB */ + { 20891, 0x0000872E }, /* GL_MODELVIEW14_ARB */ + { 20910, 0x0000872F }, /* GL_MODELVIEW15_ARB */ + { 20929, 0x00008730 }, /* GL_MODELVIEW16_ARB */ + { 20948, 0x00008731 }, /* GL_MODELVIEW17_ARB */ + { 20967, 0x00008732 }, /* GL_MODELVIEW18_ARB */ + { 20986, 0x00008733 }, /* GL_MODELVIEW19_ARB */ + { 21005, 0x0000850A }, /* GL_MODELVIEW1_ARB */ + { 21023, 0x00008734 }, /* GL_MODELVIEW20_ARB */ + { 21042, 0x00008735 }, /* GL_MODELVIEW21_ARB */ + { 21061, 0x00008736 }, /* GL_MODELVIEW22_ARB */ + { 21080, 0x00008737 }, /* GL_MODELVIEW23_ARB */ + { 21099, 0x00008738 }, /* GL_MODELVIEW24_ARB */ + { 21118, 0x00008739 }, /* GL_MODELVIEW25_ARB */ + { 21137, 0x0000873A }, /* GL_MODELVIEW26_ARB */ + { 21156, 0x0000873B }, /* GL_MODELVIEW27_ARB */ + { 21175, 0x0000873C }, /* GL_MODELVIEW28_ARB */ + { 21194, 0x0000873D }, /* GL_MODELVIEW29_ARB */ + { 21213, 0x00008722 }, /* GL_MODELVIEW2_ARB */ + { 21231, 0x0000873E }, /* GL_MODELVIEW30_ARB */ + { 21250, 0x0000873F }, /* GL_MODELVIEW31_ARB */ + { 21269, 0x00008723 }, /* GL_MODELVIEW3_ARB */ + { 21287, 0x00008724 }, /* GL_MODELVIEW4_ARB */ + { 21305, 0x00008725 }, /* GL_MODELVIEW5_ARB */ + { 21323, 0x00008726 }, /* GL_MODELVIEW6_ARB */ + { 21341, 0x00008727 }, /* GL_MODELVIEW7_ARB */ + { 21359, 0x00008728 }, /* GL_MODELVIEW8_ARB */ + { 21377, 0x00008729 }, /* GL_MODELVIEW9_ARB */ + { 21395, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */ + { 21415, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */ + { 21442, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */ + { 21467, 0x00002100 }, /* GL_MODULATE */ + { 21479, 0x00008744 }, /* GL_MODULATE_ADD_ATI */ + { 21499, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */ + { 21526, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */ + { 21551, 0x00000103 }, /* GL_MULT */ + { 21559, 0x0000809D }, /* GL_MULTISAMPLE */ + { 21574, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */ + { 21594, 0x0000809D }, /* GL_MULTISAMPLE_ARB */ + { 21613, 0x20000000 }, /* GL_MULTISAMPLE_BIT */ + { 21632, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */ + { 21656, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */ + { 21679, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */ + { 21709, 0x00002A25 }, /* GL_N3F_V3F */ + { 21720, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */ + { 21740, 0x0000150E }, /* GL_NAND */ + { 21748, 0x00002600 }, /* GL_NEAREST */ + { 21759, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ + { 21790, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ + { 21822, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */ + { 21847, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */ + { 21873, 0x00000200 }, /* GL_NEVER */ + { 21882, 0x00001102 }, /* GL_NICEST */ + { 21892, 0x00000000 }, /* GL_NONE */ + { 21900, 0x00001505 }, /* GL_NOOP */ + { 21908, 0x00001508 }, /* GL_NOR */ + { 21915, 0x00000BA1 }, /* GL_NORMALIZE */ + { 21928, 0x00008075 }, /* GL_NORMAL_ARRAY */ + { 21944, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ + { 21975, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */ + { 22010, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */ + { 22034, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */ + { 22057, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */ + { 22078, 0x00008511 }, /* GL_NORMAL_MAP */ + { 22092, 0x00008511 }, /* GL_NORMAL_MAP_ARB */ + { 22110, 0x00008511 }, /* GL_NORMAL_MAP_NV */ + { 22127, 0x00000205 }, /* GL_NOTEQUAL */ + { 22139, 0x00000000 }, /* GL_NO_ERROR */ + { 22151, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ + { 22185, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */ + { 22223, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */ + { 22255, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */ + { 22297, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */ + { 22327, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */ + { 22367, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */ + { 22398, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */ + { 22427, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */ + { 22455, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */ + { 22485, 0x00002401 }, /* GL_OBJECT_LINEAR */ + { 22502, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */ + { 22528, 0x00002501 }, /* GL_OBJECT_PLANE */ + { 22544, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */ + { 22579, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */ + { 22601, 0x00009112 }, /* GL_OBJECT_TYPE */ + { 22616, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */ + { 22635, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */ + { 22665, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */ + { 22686, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */ + { 22714, 0x00000001 }, /* GL_ONE */ + { 22721, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */ + { 22749, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */ + { 22781, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */ + { 22809, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */ + { 22841, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */ + { 22864, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */ + { 22887, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */ + { 22910, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */ + { 22933, 0x00008598 }, /* GL_OPERAND0_ALPHA */ + { 22951, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */ + { 22973, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */ + { 22995, 0x00008590 }, /* GL_OPERAND0_RGB */ + { 23011, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */ + { 23031, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */ + { 23051, 0x00008599 }, /* GL_OPERAND1_ALPHA */ + { 23069, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */ + { 23091, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */ + { 23113, 0x00008591 }, /* GL_OPERAND1_RGB */ + { 23129, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */ + { 23149, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */ + { 23169, 0x0000859A }, /* GL_OPERAND2_ALPHA */ + { 23187, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */ + { 23209, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */ + { 23231, 0x00008592 }, /* GL_OPERAND2_RGB */ + { 23247, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */ + { 23267, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */ + { 23287, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */ + { 23308, 0x00008593 }, /* GL_OPERAND3_RGB_NV */ + { 23327, 0x00001507 }, /* GL_OR */ + { 23333, 0x00000A01 }, /* GL_ORDER */ + { 23342, 0x0000150D }, /* GL_OR_INVERTED */ + { 23357, 0x0000150B }, /* GL_OR_REVERSE */ + { 23371, 0x00000505 }, /* GL_OUT_OF_MEMORY */ + { 23388, 0x00000D05 }, /* GL_PACK_ALIGNMENT */ + { 23406, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */ + { 23427, 0x00008758 }, /* GL_PACK_INVERT_MESA */ + { 23447, 0x00000D01 }, /* GL_PACK_LSB_FIRST */ + { 23465, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */ + { 23484, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */ + { 23504, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */ + { 23524, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */ + { 23542, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */ + { 23561, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */ + { 23586, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */ + { 23610, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */ + { 23631, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */ + { 23653, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */ + { 23675, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */ + { 23700, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */ + { 23724, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */ + { 23745, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */ + { 23767, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */ + { 23789, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */ + { 23811, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */ + { 23842, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */ + { 23862, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */ + { 23887, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */ + { 23907, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */ + { 23932, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */ + { 23952, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */ + { 23977, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */ + { 23997, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */ + { 24022, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */ + { 24042, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */ + { 24067, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */ + { 24087, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */ + { 24112, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */ + { 24132, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */ + { 24157, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */ + { 24177, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */ + { 24202, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */ + { 24222, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */ + { 24247, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */ + { 24267, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */ + { 24292, 0x00000020 }, /* GL_PIXEL_MODE_BIT */ + { 24310, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */ + { 24331, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */ + { 24360, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */ + { 24393, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */ + { 24418, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */ + { 24441, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */ + { 24472, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */ + { 24507, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */ + { 24534, 0x00001B00 }, /* GL_POINT */ + { 24543, 0x00000000 }, /* GL_POINTS */ + { 24553, 0x00000002 }, /* GL_POINT_BIT */ + { 24566, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */ + { 24596, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */ + { 24630, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */ + { 24664, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */ + { 24699, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */ + { 24728, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */ + { 24761, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */ + { 24794, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */ + { 24828, 0x00000B11 }, /* GL_POINT_SIZE */ + { 24842, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */ + { 24868, 0x00008127 }, /* GL_POINT_SIZE_MAX */ + { 24886, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */ + { 24908, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */ + { 24930, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */ + { 24953, 0x00008126 }, /* GL_POINT_SIZE_MIN */ + { 24971, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */ + { 24993, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */ + { 25015, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */ + { 25038, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */ + { 25058, 0x00000B10 }, /* GL_POINT_SMOOTH */ + { 25074, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */ + { 25095, 0x00008861 }, /* GL_POINT_SPRITE */ + { 25111, 0x00008861 }, /* GL_POINT_SPRITE_ARB */ + { 25131, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */ + { 25160, 0x00008861 }, /* GL_POINT_SPRITE_NV */ + { 25179, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */ + { 25205, 0x00000701 }, /* GL_POINT_TOKEN */ + { 25220, 0x00000009 }, /* GL_POLYGON */ + { 25231, 0x00000008 }, /* GL_POLYGON_BIT */ + { 25246, 0x00000B40 }, /* GL_POLYGON_MODE */ + { 25262, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */ + { 25285, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */ + { 25310, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */ + { 25333, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */ + { 25356, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */ + { 25380, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */ + { 25404, 0x00000B41 }, /* GL_POLYGON_SMOOTH */ + { 25422, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */ + { 25445, 0x00000B42 }, /* GL_POLYGON_STIPPLE */ + { 25464, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */ + { 25487, 0x00000703 }, /* GL_POLYGON_TOKEN */ + { 25504, 0x00001203 }, /* GL_POSITION */ + { 25516, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ + { 25548, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */ + { 25584, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ + { 25617, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */ + { 25654, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ + { 25685, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */ + { 25720, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ + { 25752, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */ + { 25788, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ + { 25821, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ + { 25853, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */ + { 25889, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ + { 25922, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */ + { 25959, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */ + { 25989, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */ + { 26023, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */ + { 26054, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */ + { 26089, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ + { 26120, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */ + { 26155, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ + { 26187, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */ + { 26223, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */ + { 26253, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */ + { 26287, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */ + { 26318, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */ + { 26353, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */ + { 26385, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */ + { 26416, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */ + { 26451, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */ + { 26483, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */ + { 26519, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */ + { 26548, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */ + { 26581, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */ + { 26611, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */ + { 26645, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ + { 26684, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ + { 26717, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ + { 26757, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ + { 26791, 0x00008578 }, /* GL_PREVIOUS */ + { 26803, 0x00008578 }, /* GL_PREVIOUS_ARB */ + { 26819, 0x00008578 }, /* GL_PREVIOUS_EXT */ + { 26835, 0x00008577 }, /* GL_PRIMARY_COLOR */ + { 26852, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */ + { 26873, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */ + { 26894, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ + { 26927, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ + { 26959, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */ + { 26982, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */ + { 27005, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */ + { 27035, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */ + { 27064, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */ + { 27092, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */ + { 27114, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */ + { 27142, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */ + { 27170, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */ + { 27192, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */ + { 27213, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ + { 27253, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ + { 27292, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ + { 27322, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ + { 27357, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ + { 27390, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ + { 27424, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ + { 27463, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ + { 27502, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */ + { 27524, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */ + { 27550, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */ + { 27574, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */ + { 27597, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */ + { 27619, 0x00008628 }, /* GL_PROGRAM_STRING_NV */ + { 27640, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */ + { 27661, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */ + { 27688, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ + { 27720, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ + { 27752, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ + { 27787, 0x00001701 }, /* GL_PROJECTION */ + { 27801, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */ + { 27822, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */ + { 27848, 0x00008E4F }, /* GL_PROVOKING_VERTEX */ + { 27868, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */ + { 27892, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */ + { 27913, 0x00008025 }, /* GL_PROXY_HISTOGRAM */ + { 27932, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */ + { 27955, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ + { 27994, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ + { 28032, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */ + { 28052, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ + { 28082, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */ + { 28106, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */ + { 28126, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ + { 28156, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */ + { 28180, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */ + { 28200, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ + { 28233, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */ + { 28259, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */ + { 28289, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ + { 28320, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */ + { 28350, 0x00002003 }, /* GL_Q */ + { 28355, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */ + { 28380, 0x00000007 }, /* GL_QUADS */ + { 28389, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ + { 28433, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */ + { 28481, 0x00008614 }, /* GL_QUAD_MESH_SUN */ + { 28498, 0x00000008 }, /* GL_QUAD_STRIP */ + { 28512, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT_NV */ + { 28542, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT_NV */ + { 28569, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */ + { 28591, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */ + { 28617, 0x00008E14 }, /* GL_QUERY_NO_WAIT_NV */ + { 28637, 0x00008866 }, /* GL_QUERY_RESULT */ + { 28653, 0x00008866 }, /* GL_QUERY_RESULT_ARB */ + { 28673, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */ + { 28699, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */ + { 28729, 0x00008E13 }, /* GL_QUERY_WAIT_NV */ + { 28746, 0x00002002 }, /* GL_R */ + { 28751, 0x00002A10 }, /* GL_R3_G3_B2 */ + { 28763, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ + { 28796, 0x00000C02 }, /* GL_READ_BUFFER */ + { 28811, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */ + { 28831, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */ + { 28859, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */ + { 28891, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */ + { 28915, 0x000088B8 }, /* GL_READ_ONLY */ + { 28928, 0x000088B8 }, /* GL_READ_ONLY_ARB */ + { 28945, 0x000088BA }, /* GL_READ_WRITE */ + { 28959, 0x000088BA }, /* GL_READ_WRITE_ARB */ + { 28977, 0x00001903 }, /* GL_RED */ + { 28984, 0x00008016 }, /* GL_REDUCE */ + { 28994, 0x00008016 }, /* GL_REDUCE_EXT */ + { 29008, 0x00000D15 }, /* GL_RED_BIAS */ + { 29020, 0x00000D52 }, /* GL_RED_BITS */ + { 29032, 0x00000D14 }, /* GL_RED_SCALE */ + { 29045, 0x00008512 }, /* GL_REFLECTION_MAP */ + { 29063, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */ + { 29085, 0x00008512 }, /* GL_REFLECTION_MAP_NV */ + { 29106, 0x00001C00 }, /* GL_RENDER */ + { 29116, 0x00008D41 }, /* GL_RENDERBUFFER */ + { 29132, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */ + { 29159, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */ + { 29183, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */ + { 29211, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */ + { 29237, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */ + { 29264, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */ + { 29284, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */ + { 29311, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */ + { 29334, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */ + { 29361, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */ + { 29393, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */ + { 29429, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */ + { 29454, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */ + { 29478, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */ + { 29506, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */ + { 29535, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */ + { 29557, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */ + { 29583, 0x00001F01 }, /* GL_RENDERER */ + { 29595, 0x00000C40 }, /* GL_RENDER_MODE */ + { 29610, 0x00002901 }, /* GL_REPEAT */ + { 29620, 0x00001E01 }, /* GL_REPLACE */ + { 29631, 0x00008062 }, /* GL_REPLACE_EXT */ + { 29646, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */ + { 29669, 0x0000803A }, /* GL_RESCALE_NORMAL */ + { 29687, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */ + { 29709, 0x00000102 }, /* GL_RETURN */ + { 29719, 0x00001907 }, /* GL_RGB */ + { 29726, 0x00008052 }, /* GL_RGB10 */ + { 29735, 0x00008059 }, /* GL_RGB10_A2 */ + { 29747, 0x00008059 }, /* GL_RGB10_A2_EXT */ + { 29763, 0x00008052 }, /* GL_RGB10_EXT */ + { 29776, 0x00008053 }, /* GL_RGB12 */ + { 29785, 0x00008053 }, /* GL_RGB12_EXT */ + { 29798, 0x00008054 }, /* GL_RGB16 */ + { 29807, 0x00008054 }, /* GL_RGB16_EXT */ + { 29820, 0x0000804E }, /* GL_RGB2_EXT */ + { 29832, 0x0000804F }, /* GL_RGB4 */ + { 29840, 0x0000804F }, /* GL_RGB4_EXT */ + { 29852, 0x000083A1 }, /* GL_RGB4_S3TC */ + { 29865, 0x00008050 }, /* GL_RGB5 */ + { 29873, 0x00008057 }, /* GL_RGB5_A1 */ + { 29884, 0x00008057 }, /* GL_RGB5_A1_EXT */ + { 29899, 0x00008050 }, /* GL_RGB5_EXT */ + { 29911, 0x00008051 }, /* GL_RGB8 */ + { 29919, 0x00008051 }, /* GL_RGB8_EXT */ + { 29931, 0x00001908 }, /* GL_RGBA */ + { 29939, 0x0000805A }, /* GL_RGBA12 */ + { 29949, 0x0000805A }, /* GL_RGBA12_EXT */ + { 29963, 0x0000805B }, /* GL_RGBA16 */ + { 29973, 0x0000805B }, /* GL_RGBA16_EXT */ + { 29987, 0x00008055 }, /* GL_RGBA2 */ + { 29996, 0x00008055 }, /* GL_RGBA2_EXT */ + { 30009, 0x00008056 }, /* GL_RGBA4 */ + { 30018, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */ + { 30037, 0x00008056 }, /* GL_RGBA4_EXT */ + { 30050, 0x000083A3 }, /* GL_RGBA4_S3TC */ + { 30064, 0x00008058 }, /* GL_RGBA8 */ + { 30073, 0x00008058 }, /* GL_RGBA8_EXT */ + { 30086, 0x00008F97 }, /* GL_RGBA8_SNORM */ + { 30101, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */ + { 30119, 0x00000C31 }, /* GL_RGBA_MODE */ + { 30132, 0x000083A2 }, /* GL_RGBA_S3TC */ + { 30145, 0x00008F93 }, /* GL_RGBA_SNORM */ + { 30159, 0x000083A0 }, /* GL_RGB_S3TC */ + { 30171, 0x00008573 }, /* GL_RGB_SCALE */ + { 30184, 0x00008573 }, /* GL_RGB_SCALE_ARB */ + { 30201, 0x00008573 }, /* GL_RGB_SCALE_EXT */ + { 30218, 0x00000407 }, /* GL_RIGHT */ + { 30227, 0x00002000 }, /* GL_S */ + { 30232, 0x00008B5D }, /* GL_SAMPLER_1D */ + { 30246, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */ + { 30267, 0x00008B5E }, /* GL_SAMPLER_2D */ + { 30281, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */ + { 30302, 0x00008B5F }, /* GL_SAMPLER_3D */ + { 30316, 0x00008B60 }, /* GL_SAMPLER_CUBE */ + { 30332, 0x000080A9 }, /* GL_SAMPLES */ + { 30343, 0x000086B4 }, /* GL_SAMPLES_3DFX */ + { 30359, 0x000080A9 }, /* GL_SAMPLES_ARB */ + { 30374, 0x00008914 }, /* GL_SAMPLES_PASSED */ + { 30392, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */ + { 30414, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ + { 30442, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */ + { 30474, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */ + { 30497, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */ + { 30524, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */ + { 30542, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */ + { 30565, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */ + { 30587, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */ + { 30606, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */ + { 30629, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */ + { 30655, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */ + { 30685, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */ + { 30710, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */ + { 30739, 0x00080000 }, /* GL_SCISSOR_BIT */ + { 30754, 0x00000C10 }, /* GL_SCISSOR_BOX */ + { 30769, 0x00000C11 }, /* GL_SCISSOR_TEST */ + { 30785, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */ + { 30810, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ + { 30850, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */ + { 30894, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ + { 30927, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ + { 30957, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ + { 30989, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ + { 31019, 0x00001C02 }, /* GL_SELECT */ + { 31029, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */ + { 31057, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */ + { 31082, 0x00008012 }, /* GL_SEPARABLE_2D */ + { 31098, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */ + { 31125, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */ + { 31156, 0x0000150F }, /* GL_SET */ + { 31163, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */ + { 31184, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */ + { 31208, 0x00008B4F }, /* GL_SHADER_TYPE */ + { 31223, 0x00000B54 }, /* GL_SHADE_MODEL */ + { 31238, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */ + { 31266, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */ + { 31289, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */ + { 31319, 0x00001601 }, /* GL_SHININESS */ + { 31332, 0x00001402 }, /* GL_SHORT */ + { 31341, 0x00009119 }, /* GL_SIGNALED */ + { 31353, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */ + { 31374, 0x000081F9 }, /* GL_SINGLE_COLOR */ + { 31390, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */ + { 31410, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */ + { 31429, 0x00008C46 }, /* GL_SLUMINANCE */ + { 31443, 0x00008C47 }, /* GL_SLUMINANCE8 */ + { 31458, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */ + { 31480, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */ + { 31500, 0x00001D01 }, /* GL_SMOOTH */ + { 31510, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */ + { 31543, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */ + { 31570, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */ + { 31603, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */ + { 31630, 0x00008588 }, /* GL_SOURCE0_ALPHA */ + { 31647, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */ + { 31668, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */ + { 31689, 0x00008580 }, /* GL_SOURCE0_RGB */ + { 31704, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */ + { 31723, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */ + { 31742, 0x00008589 }, /* GL_SOURCE1_ALPHA */ + { 31759, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */ + { 31780, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */ + { 31801, 0x00008581 }, /* GL_SOURCE1_RGB */ + { 31816, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */ + { 31835, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */ + { 31854, 0x0000858A }, /* GL_SOURCE2_ALPHA */ + { 31871, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */ + { 31892, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */ + { 31913, 0x00008582 }, /* GL_SOURCE2_RGB */ + { 31928, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */ + { 31947, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */ + { 31966, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */ + { 31986, 0x00008583 }, /* GL_SOURCE3_RGB_NV */ + { 32004, 0x00001202 }, /* GL_SPECULAR */ + { 32016, 0x00002402 }, /* GL_SPHERE_MAP */ + { 32030, 0x00001206 }, /* GL_SPOT_CUTOFF */ + { 32045, 0x00001204 }, /* GL_SPOT_DIRECTION */ + { 32063, 0x00001205 }, /* GL_SPOT_EXPONENT */ + { 32080, 0x00008588 }, /* GL_SRC0_ALPHA */ + { 32094, 0x00008580 }, /* GL_SRC0_RGB */ + { 32106, 0x00008589 }, /* GL_SRC1_ALPHA */ + { 32120, 0x00008581 }, /* GL_SRC1_RGB */ + { 32132, 0x0000858A }, /* GL_SRC2_ALPHA */ + { 32146, 0x00008582 }, /* GL_SRC2_RGB */ + { 32158, 0x00000302 }, /* GL_SRC_ALPHA */ + { 32171, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */ + { 32193, 0x00000300 }, /* GL_SRC_COLOR */ + { 32206, 0x00008C40 }, /* GL_SRGB */ + { 32214, 0x00008C41 }, /* GL_SRGB8 */ + { 32223, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */ + { 32239, 0x00008C42 }, /* GL_SRGB_ALPHA */ + { 32253, 0x00000503 }, /* GL_STACK_OVERFLOW */ + { 32271, 0x00000504 }, /* GL_STACK_UNDERFLOW */ + { 32290, 0x000088E6 }, /* GL_STATIC_COPY */ + { 32305, 0x000088E6 }, /* GL_STATIC_COPY_ARB */ + { 32324, 0x000088E4 }, /* GL_STATIC_DRAW */ + { 32339, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */ + { 32358, 0x000088E5 }, /* GL_STATIC_READ */ + { 32373, 0x000088E5 }, /* GL_STATIC_READ_ARB */ + { 32392, 0x00001802 }, /* GL_STENCIL */ + { 32403, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */ + { 32425, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */ + { 32451, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */ + { 32472, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */ + { 32497, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */ + { 32518, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */ + { 32543, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ + { 32575, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */ + { 32611, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ + { 32643, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */ + { 32679, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */ + { 32699, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */ + { 32726, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */ + { 32752, 0x00000D57 }, /* GL_STENCIL_BITS */ + { 32768, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */ + { 32790, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */ + { 32813, 0x00000B94 }, /* GL_STENCIL_FAIL */ + { 32829, 0x00000B92 }, /* GL_STENCIL_FUNC */ + { 32845, 0x00001901 }, /* GL_STENCIL_INDEX */ + { 32862, 0x00008D46 }, /* GL_STENCIL_INDEX1 */ + { 32880, 0x00008D49 }, /* GL_STENCIL_INDEX16 */ + { 32899, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */ + { 32922, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */ + { 32944, 0x00008D47 }, /* GL_STENCIL_INDEX4 */ + { 32962, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */ + { 32984, 0x00008D48 }, /* GL_STENCIL_INDEX8 */ + { 33002, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */ + { 33024, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */ + { 33045, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */ + { 33072, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */ + { 33099, 0x00000B97 }, /* GL_STENCIL_REF */ + { 33114, 0x00000B90 }, /* GL_STENCIL_TEST */ + { 33130, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ + { 33159, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */ + { 33181, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */ + { 33202, 0x00000C33 }, /* GL_STEREO */ + { 33212, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */ + { 33236, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */ + { 33261, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */ + { 33285, 0x000088E2 }, /* GL_STREAM_COPY */ + { 33300, 0x000088E2 }, /* GL_STREAM_COPY_ARB */ + { 33319, 0x000088E0 }, /* GL_STREAM_DRAW */ + { 33334, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */ + { 33353, 0x000088E1 }, /* GL_STREAM_READ */ + { 33368, 0x000088E1 }, /* GL_STREAM_READ_ARB */ + { 33387, 0x00000D50 }, /* GL_SUBPIXEL_BITS */ + { 33404, 0x000084E7 }, /* GL_SUBTRACT */ + { 33416, 0x000084E7 }, /* GL_SUBTRACT_ARB */ + { 33432, 0x00009113 }, /* GL_SYNC_CONDITION */ + { 33450, 0x00009116 }, /* GL_SYNC_FENCE */ + { 33464, 0x00009115 }, /* GL_SYNC_FLAGS */ + { 33478, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */ + { 33505, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */ + { 33535, 0x00009114 }, /* GL_SYNC_STATUS */ + { 33550, 0x00002001 }, /* GL_T */ + { 33555, 0x00002A2A }, /* GL_T2F_C3F_V3F */ + { 33570, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */ + { 33589, 0x00002A29 }, /* GL_T2F_C4UB_V3F */ + { 33605, 0x00002A2B }, /* GL_T2F_N3F_V3F */ + { 33620, 0x00002A27 }, /* GL_T2F_V3F */ + { 33631, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */ + { 33650, 0x00002A28 }, /* GL_T4F_V4F */ + { 33661, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */ + { 33684, 0x00001702 }, /* GL_TEXTURE */ + { 33695, 0x000084C0 }, /* GL_TEXTURE0 */ + { 33707, 0x000084C0 }, /* GL_TEXTURE0_ARB */ + { 33723, 0x000084C1 }, /* GL_TEXTURE1 */ + { 33735, 0x000084CA }, /* GL_TEXTURE10 */ + { 33748, 0x000084CA }, /* GL_TEXTURE10_ARB */ + { 33765, 0x000084CB }, /* GL_TEXTURE11 */ + { 33778, 0x000084CB }, /* GL_TEXTURE11_ARB */ + { 33795, 0x000084CC }, /* GL_TEXTURE12 */ + { 33808, 0x000084CC }, /* GL_TEXTURE12_ARB */ + { 33825, 0x000084CD }, /* GL_TEXTURE13 */ + { 33838, 0x000084CD }, /* GL_TEXTURE13_ARB */ + { 33855, 0x000084CE }, /* GL_TEXTURE14 */ + { 33868, 0x000084CE }, /* GL_TEXTURE14_ARB */ + { 33885, 0x000084CF }, /* GL_TEXTURE15 */ + { 33898, 0x000084CF }, /* GL_TEXTURE15_ARB */ + { 33915, 0x000084D0 }, /* GL_TEXTURE16 */ + { 33928, 0x000084D0 }, /* GL_TEXTURE16_ARB */ + { 33945, 0x000084D1 }, /* GL_TEXTURE17 */ + { 33958, 0x000084D1 }, /* GL_TEXTURE17_ARB */ + { 33975, 0x000084D2 }, /* GL_TEXTURE18 */ + { 33988, 0x000084D2 }, /* GL_TEXTURE18_ARB */ + { 34005, 0x000084D3 }, /* GL_TEXTURE19 */ + { 34018, 0x000084D3 }, /* GL_TEXTURE19_ARB */ + { 34035, 0x000084C1 }, /* GL_TEXTURE1_ARB */ + { 34051, 0x000084C2 }, /* GL_TEXTURE2 */ + { 34063, 0x000084D4 }, /* GL_TEXTURE20 */ + { 34076, 0x000084D4 }, /* GL_TEXTURE20_ARB */ + { 34093, 0x000084D5 }, /* GL_TEXTURE21 */ + { 34106, 0x000084D5 }, /* GL_TEXTURE21_ARB */ + { 34123, 0x000084D6 }, /* GL_TEXTURE22 */ + { 34136, 0x000084D6 }, /* GL_TEXTURE22_ARB */ + { 34153, 0x000084D7 }, /* GL_TEXTURE23 */ + { 34166, 0x000084D7 }, /* GL_TEXTURE23_ARB */ + { 34183, 0x000084D8 }, /* GL_TEXTURE24 */ + { 34196, 0x000084D8 }, /* GL_TEXTURE24_ARB */ + { 34213, 0x000084D9 }, /* GL_TEXTURE25 */ + { 34226, 0x000084D9 }, /* GL_TEXTURE25_ARB */ + { 34243, 0x000084DA }, /* GL_TEXTURE26 */ + { 34256, 0x000084DA }, /* GL_TEXTURE26_ARB */ + { 34273, 0x000084DB }, /* GL_TEXTURE27 */ + { 34286, 0x000084DB }, /* GL_TEXTURE27_ARB */ + { 34303, 0x000084DC }, /* GL_TEXTURE28 */ + { 34316, 0x000084DC }, /* GL_TEXTURE28_ARB */ + { 34333, 0x000084DD }, /* GL_TEXTURE29 */ + { 34346, 0x000084DD }, /* GL_TEXTURE29_ARB */ + { 34363, 0x000084C2 }, /* GL_TEXTURE2_ARB */ + { 34379, 0x000084C3 }, /* GL_TEXTURE3 */ + { 34391, 0x000084DE }, /* GL_TEXTURE30 */ + { 34404, 0x000084DE }, /* GL_TEXTURE30_ARB */ + { 34421, 0x000084DF }, /* GL_TEXTURE31 */ + { 34434, 0x000084DF }, /* GL_TEXTURE31_ARB */ + { 34451, 0x000084C3 }, /* GL_TEXTURE3_ARB */ + { 34467, 0x000084C4 }, /* GL_TEXTURE4 */ + { 34479, 0x000084C4 }, /* GL_TEXTURE4_ARB */ + { 34495, 0x000084C5 }, /* GL_TEXTURE5 */ + { 34507, 0x000084C5 }, /* GL_TEXTURE5_ARB */ + { 34523, 0x000084C6 }, /* GL_TEXTURE6 */ + { 34535, 0x000084C6 }, /* GL_TEXTURE6_ARB */ + { 34551, 0x000084C7 }, /* GL_TEXTURE7 */ + { 34563, 0x000084C7 }, /* GL_TEXTURE7_ARB */ + { 34579, 0x000084C8 }, /* GL_TEXTURE8 */ + { 34591, 0x000084C8 }, /* GL_TEXTURE8_ARB */ + { 34607, 0x000084C9 }, /* GL_TEXTURE9 */ + { 34619, 0x000084C9 }, /* GL_TEXTURE9_ARB */ + { 34635, 0x00000DE0 }, /* GL_TEXTURE_1D */ + { 34649, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */ + { 34673, 0x00000DE1 }, /* GL_TEXTURE_2D */ + { 34687, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */ + { 34711, 0x0000806F }, /* GL_TEXTURE_3D */ + { 34725, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */ + { 34747, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */ + { 34773, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */ + { 34795, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */ + { 34817, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ + { 34849, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */ + { 34871, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ + { 34903, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */ + { 34925, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */ + { 34953, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */ + { 34985, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ + { 35018, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */ + { 35050, 0x00040000 }, /* GL_TEXTURE_BIT */ + { 35065, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */ + { 35086, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */ + { 35111, 0x00001005 }, /* GL_TEXTURE_BORDER */ + { 35129, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */ + { 35153, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ + { 35184, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ + { 35214, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ + { 35244, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ + { 35279, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ + { 35310, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ + { 35348, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */ + { 35375, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ + { 35407, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ + { 35441, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */ + { 35465, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */ + { 35493, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */ + { 35517, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */ + { 35545, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ + { 35578, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */ + { 35602, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */ + { 35624, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */ + { 35646, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */ + { 35672, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */ + { 35706, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ + { 35739, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */ + { 35776, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */ + { 35804, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */ + { 35836, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */ + { 35859, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ + { 35897, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */ + { 35939, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */ + { 35970, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */ + { 35998, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ + { 36028, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */ + { 36056, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */ + { 36076, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */ + { 36100, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ + { 36131, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */ + { 36166, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ + { 36197, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */ + { 36232, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ + { 36263, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */ + { 36298, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ + { 36329, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */ + { 36364, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ + { 36395, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */ + { 36430, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ + { 36461, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */ + { 36496, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */ + { 36525, 0x00008071 }, /* GL_TEXTURE_DEPTH */ + { 36542, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */ + { 36564, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */ + { 36590, 0x00002300 }, /* GL_TEXTURE_ENV */ + { 36605, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */ + { 36626, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */ + { 36646, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */ + { 36672, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */ + { 36692, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */ + { 36709, 0x00000C62 }, /* GL_TEXTURE_GEN_R */ + { 36726, 0x00000C60 }, /* GL_TEXTURE_GEN_S */ + { 36743, 0x00000C61 }, /* GL_TEXTURE_GEN_T */ + { 36760, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */ + { 36785, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */ + { 36807, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */ + { 36833, 0x00001001 }, /* GL_TEXTURE_HEIGHT */ + { 36851, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */ + { 36877, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */ + { 36903, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */ + { 36933, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */ + { 36960, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */ + { 36985, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */ + { 37005, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */ + { 37029, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ + { 37056, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ + { 37083, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ + { 37110, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */ + { 37136, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */ + { 37166, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */ + { 37188, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */ + { 37206, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ + { 37236, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ + { 37264, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ + { 37292, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ + { 37320, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */ + { 37341, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */ + { 37360, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */ + { 37382, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */ + { 37401, 0x00008066 }, /* GL_TEXTURE_PRIORITY */ + { 37421, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */ + { 37451, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */ + { 37482, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */ + { 37507, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */ + { 37531, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */ + { 37551, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */ + { 37575, 0x00008067 }, /* GL_TEXTURE_RESIDENT */ + { 37595, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */ + { 37618, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */ + { 37642, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */ + { 37670, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */ + { 37700, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */ + { 37725, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ + { 37759, 0x00001000 }, /* GL_TEXTURE_WIDTH */ + { 37776, 0x00008072 }, /* GL_TEXTURE_WRAP_R */ + { 37794, 0x00002802 }, /* GL_TEXTURE_WRAP_S */ + { 37812, 0x00002803 }, /* GL_TEXTURE_WRAP_T */ + { 37830, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */ + { 37849, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */ + { 37869, 0x00008648 }, /* GL_TRACK_MATRIX_NV */ + { 37888, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */ + { 37917, 0x00001000 }, /* GL_TRANSFORM_BIT */ + { 37934, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */ + { 37960, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */ + { 37990, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ + { 38022, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ + { 38052, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */ + { 38086, 0x0000862C }, /* GL_TRANSPOSE_NV */ + { 38102, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */ + { 38133, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */ + { 38168, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */ + { 38196, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */ + { 38228, 0x00000004 }, /* GL_TRIANGLES */ + { 38241, 0x00000006 }, /* GL_TRIANGLE_FAN */ + { 38257, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */ + { 38278, 0x00000005 }, /* GL_TRIANGLE_STRIP */ + { 38296, 0x00000001 }, /* GL_TRUE */ + { 38304, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */ + { 38324, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */ + { 38347, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */ + { 38367, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */ + { 38388, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */ + { 38410, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */ + { 38432, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */ + { 38452, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */ + { 38473, 0x00009118 }, /* GL_UNSIGNALED */ + { 38487, 0x00001401 }, /* GL_UNSIGNED_BYTE */ + { 38504, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */ + { 38531, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */ + { 38554, 0x00001405 }, /* GL_UNSIGNED_INT */ + { 38570, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */ + { 38597, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */ + { 38618, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */ + { 38643, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */ + { 38667, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */ + { 38698, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */ + { 38722, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */ + { 38750, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */ + { 38773, 0x00001403 }, /* GL_UNSIGNED_SHORT */ + { 38791, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ + { 38821, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */ + { 38847, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ + { 38877, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */ + { 38903, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */ + { 38927, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */ + { 38955, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */ + { 38983, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */ + { 39010, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ + { 39042, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */ + { 39073, 0x00008CA2 }, /* GL_UPPER_LEFT */ + { 39087, 0x00002A20 }, /* GL_V2F */ + { 39094, 0x00002A21 }, /* GL_V3F */ + { 39101, 0x00008B83 }, /* GL_VALIDATE_STATUS */ + { 39120, 0x00001F00 }, /* GL_VENDOR */ + { 39130, 0x00001F02 }, /* GL_VERSION */ + { 39141, 0x00008074 }, /* GL_VERTEX_ARRAY */ + { 39157, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */ + { 39181, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */ + { 39211, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ + { 39242, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */ + { 39277, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */ + { 39301, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */ + { 39322, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */ + { 39345, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */ + { 39366, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ + { 39393, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ + { 39421, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ + { 39449, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ + { 39477, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ + { 39505, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ + { 39533, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ + { 39561, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ + { 39588, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ + { 39615, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ + { 39642, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ + { 39669, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ + { 39696, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ + { 39723, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ + { 39750, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ + { 39777, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ + { 39804, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ + { 39842, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */ + { 39884, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ + { 39915, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */ + { 39950, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ + { 39984, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */ + { 40022, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ + { 40053, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */ + { 40088, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ + { 40116, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */ + { 40148, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ + { 40178, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */ + { 40212, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ + { 40240, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */ + { 40272, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */ + { 40292, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */ + { 40314, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */ + { 40343, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */ + { 40364, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */ + { 40393, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */ + { 40426, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */ + { 40458, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */ + { 40485, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */ + { 40516, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */ + { 40546, 0x00008B31 }, /* GL_VERTEX_SHADER */ + { 40563, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */ + { 40584, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */ + { 40611, 0x00000BA2 }, /* GL_VIEWPORT */ + { 40623, 0x00000800 }, /* GL_VIEWPORT_BIT */ + { 40639, 0x0000911D }, /* GL_WAIT_FAILED */ + { 40654, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */ + { 40674, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ + { 40705, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */ + { 40740, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */ + { 40768, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */ + { 40793, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ + { 40820, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */ + { 40845, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */ + { 40869, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */ + { 40888, 0x000088B9 }, /* GL_WRITE_ONLY */ + { 40902, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */ + { 40920, 0x00001506 }, /* GL_XOR */ + { 40927, 0x000085B9 }, /* GL_YCBCR_422_APPLE */ + { 40946, 0x00008757 }, /* GL_YCBCR_MESA */ + { 40960, 0x00000000 }, /* GL_ZERO */ + { 40968, 0x00000D16 }, /* GL_ZOOM_X */ + { 40978, 0x00000D17 }, /* GL_ZOOM_Y */ }; -static const unsigned reduced_enums[1350] = +static const unsigned reduced_enums[1351] = { 479, /* GL_FALSE */ - 701, /* GL_LINES */ - 703, /* GL_LINE_LOOP */ - 710, /* GL_LINE_STRIP */ - 1769, /* GL_TRIANGLES */ - 1772, /* GL_TRIANGLE_STRIP */ - 1770, /* GL_TRIANGLE_FAN */ - 1285, /* GL_QUADS */ - 1289, /* GL_QUAD_STRIP */ - 1171, /* GL_POLYGON */ - 1183, /* GL_POLYGON_STIPPLE_BIT */ - 1132, /* GL_PIXEL_MODE_BIT */ - 688, /* GL_LIGHTING_BIT */ + 702, /* GL_LINES */ + 704, /* GL_LINE_LOOP */ + 711, /* GL_LINE_STRIP */ + 1770, /* GL_TRIANGLES */ + 1773, /* GL_TRIANGLE_STRIP */ + 1771, /* GL_TRIANGLE_FAN */ + 1286, /* GL_QUADS */ + 1290, /* GL_QUAD_STRIP */ + 1172, /* GL_POLYGON */ + 1184, /* GL_POLYGON_STIPPLE_BIT */ + 1133, /* GL_PIXEL_MODE_BIT */ + 689, /* GL_LIGHTING_BIT */ 509, /* GL_FOG_BIT */ 8, /* GL_ACCUM */ - 720, /* GL_LOAD */ - 1348, /* GL_RETURN */ - 1004, /* GL_MULT */ + 721, /* GL_LOAD */ + 1349, /* GL_RETURN */ + 1005, /* GL_MULT */ 23, /* GL_ADD */ - 1020, /* GL_NEVER */ - 678, /* GL_LESS */ + 1021, /* GL_NEVER */ + 679, /* GL_LESS */ 469, /* GL_EQUAL */ - 677, /* GL_LEQUAL */ + 678, /* GL_LEQUAL */ 599, /* GL_GREATER */ - 1035, /* GL_NOTEQUAL */ + 1036, /* GL_NOTEQUAL */ 598, /* GL_GEQUAL */ 47, /* GL_ALWAYS */ - 1489, /* GL_SRC_COLOR */ - 1065, /* GL_ONE_MINUS_SRC_COLOR */ - 1487, /* GL_SRC_ALPHA */ - 1064, /* GL_ONE_MINUS_SRC_ALPHA */ + 1490, /* GL_SRC_COLOR */ + 1066, /* GL_ONE_MINUS_SRC_COLOR */ + 1488, /* GL_SRC_ALPHA */ + 1065, /* GL_ONE_MINUS_SRC_ALPHA */ 448, /* GL_DST_ALPHA */ - 1062, /* GL_ONE_MINUS_DST_ALPHA */ + 1063, /* GL_ONE_MINUS_DST_ALPHA */ 449, /* GL_DST_COLOR */ - 1063, /* GL_ONE_MINUS_DST_COLOR */ - 1488, /* GL_SRC_ALPHA_SATURATE */ + 1064, /* GL_ONE_MINUS_DST_COLOR */ + 1489, /* GL_SRC_ALPHA_SATURATE */ 586, /* GL_FRONT_LEFT */ 587, /* GL_FRONT_RIGHT */ 69, /* GL_BACK_LEFT */ 70, /* GL_BACK_RIGHT */ 583, /* GL_FRONT */ 68, /* GL_BACK */ - 676, /* GL_LEFT */ - 1390, /* GL_RIGHT */ + 677, /* GL_LEFT */ + 1391, /* GL_RIGHT */ 584, /* GL_FRONT_AND_BACK */ 63, /* GL_AUX0 */ 64, /* GL_AUX1 */ 65, /* GL_AUX2 */ 66, /* GL_AUX3 */ - 665, /* GL_INVALID_ENUM */ - 669, /* GL_INVALID_VALUE */ - 668, /* GL_INVALID_OPERATION */ - 1494, /* GL_STACK_OVERFLOW */ - 1495, /* GL_STACK_UNDERFLOW */ - 1090, /* GL_OUT_OF_MEMORY */ - 666, /* GL_INVALID_FRAMEBUFFER_OPERATION */ + 666, /* GL_INVALID_ENUM */ + 670, /* GL_INVALID_VALUE */ + 669, /* GL_INVALID_OPERATION */ + 1495, /* GL_STACK_OVERFLOW */ + 1496, /* GL_STACK_UNDERFLOW */ + 1091, /* GL_OUT_OF_MEMORY */ + 667, /* GL_INVALID_FRAMEBUFFER_OPERATION */ 0, /* GL_2D */ 2, /* GL_3D */ 3, /* GL_3D_COLOR */ 4, /* GL_3D_COLOR_TEXTURE */ 6, /* GL_4D_COLOR_TEXTURE */ - 1110, /* GL_PASS_THROUGH_TOKEN */ - 1170, /* GL_POINT_TOKEN */ - 711, /* GL_LINE_TOKEN */ - 1184, /* GL_POLYGON_TOKEN */ + 1111, /* GL_PASS_THROUGH_TOKEN */ + 1171, /* GL_POINT_TOKEN */ + 712, /* GL_LINE_TOKEN */ + 1185, /* GL_POLYGON_TOKEN */ 74, /* GL_BITMAP_TOKEN */ 447, /* GL_DRAW_PIXEL_TOKEN */ 301, /* GL_COPY_PIXEL_TOKEN */ - 704, /* GL_LINE_RESET_TOKEN */ + 705, /* GL_LINE_RESET_TOKEN */ 472, /* GL_EXP */ 473, /* GL_EXP2 */ 337, /* GL_CW */ 125, /* GL_CCW */ 146, /* GL_COEFF */ - 1087, /* GL_ORDER */ + 1088, /* GL_ORDER */ 384, /* GL_DOMAIN */ 311, /* GL_CURRENT_COLOR */ 314, /* GL_CURRENT_INDEX */ @@ -3898,33 +3900,33 @@ static const unsigned reduced_enums[1350] = 328, /* GL_CURRENT_RASTER_POSITION */ 329, /* GL_CURRENT_RASTER_POSITION_VALID */ 326, /* GL_CURRENT_RASTER_DISTANCE */ - 1163, /* GL_POINT_SMOOTH */ - 1152, /* GL_POINT_SIZE */ - 1162, /* GL_POINT_SIZE_RANGE */ - 1153, /* GL_POINT_SIZE_GRANULARITY */ - 705, /* GL_LINE_SMOOTH */ - 712, /* GL_LINE_WIDTH */ - 714, /* GL_LINE_WIDTH_RANGE */ - 713, /* GL_LINE_WIDTH_GRANULARITY */ - 707, /* GL_LINE_STIPPLE */ - 708, /* GL_LINE_STIPPLE_PATTERN */ - 709, /* GL_LINE_STIPPLE_REPEAT */ - 719, /* GL_LIST_MODE */ - 885, /* GL_MAX_LIST_NESTING */ - 716, /* GL_LIST_BASE */ - 718, /* GL_LIST_INDEX */ - 1173, /* GL_POLYGON_MODE */ - 1180, /* GL_POLYGON_SMOOTH */ - 1182, /* GL_POLYGON_STIPPLE */ + 1164, /* GL_POINT_SMOOTH */ + 1153, /* GL_POINT_SIZE */ + 1163, /* GL_POINT_SIZE_RANGE */ + 1154, /* GL_POINT_SIZE_GRANULARITY */ + 706, /* GL_LINE_SMOOTH */ + 713, /* GL_LINE_WIDTH */ + 715, /* GL_LINE_WIDTH_RANGE */ + 714, /* GL_LINE_WIDTH_GRANULARITY */ + 708, /* GL_LINE_STIPPLE */ + 709, /* GL_LINE_STIPPLE_PATTERN */ + 710, /* GL_LINE_STIPPLE_REPEAT */ + 720, /* GL_LIST_MODE */ + 886, /* GL_MAX_LIST_NESTING */ + 717, /* GL_LIST_BASE */ + 719, /* GL_LIST_INDEX */ + 1174, /* GL_POLYGON_MODE */ + 1181, /* GL_POLYGON_SMOOTH */ + 1183, /* GL_POLYGON_STIPPLE */ 458, /* GL_EDGE_FLAG */ 304, /* GL_CULL_FACE */ 305, /* GL_CULL_FACE_MODE */ 585, /* GL_FRONT_FACE */ - 687, /* GL_LIGHTING */ - 692, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ - 693, /* GL_LIGHT_MODEL_TWO_SIDE */ - 689, /* GL_LIGHT_MODEL_AMBIENT */ - 1436, /* GL_SHADE_MODEL */ + 688, /* GL_LIGHTING */ + 693, /* GL_LIGHT_MODEL_LOCAL_VIEWER */ + 694, /* GL_LIGHT_MODEL_TWO_SIDE */ + 690, /* GL_LIGHT_MODEL_AMBIENT */ + 1437, /* GL_SHADE_MODEL */ 193, /* GL_COLOR_MATERIAL_FACE */ 194, /* GL_COLOR_MATERIAL_PARAMETER */ 192, /* GL_COLOR_MATERIAL */ @@ -3941,24 +3943,24 @@ static const unsigned reduced_enums[1350] = 358, /* GL_DEPTH_CLEAR_VALUE */ 369, /* GL_DEPTH_FUNC */ 12, /* GL_ACCUM_CLEAR_VALUE */ - 1534, /* GL_STENCIL_TEST */ - 1518, /* GL_STENCIL_CLEAR_VALUE */ - 1520, /* GL_STENCIL_FUNC */ - 1536, /* GL_STENCIL_VALUE_MASK */ - 1519, /* GL_STENCIL_FAIL */ - 1531, /* GL_STENCIL_PASS_DEPTH_FAIL */ - 1532, /* GL_STENCIL_PASS_DEPTH_PASS */ - 1533, /* GL_STENCIL_REF */ - 1537, /* GL_STENCIL_WRITEMASK */ - 853, /* GL_MATRIX_MODE */ - 1025, /* GL_NORMALIZE */ - 1864, /* GL_VIEWPORT */ - 999, /* GL_MODELVIEW_STACK_DEPTH */ - 1263, /* GL_PROJECTION_STACK_DEPTH */ - 1744, /* GL_TEXTURE_STACK_DEPTH */ - 997, /* GL_MODELVIEW_MATRIX */ - 1262, /* GL_PROJECTION_MATRIX */ - 1727, /* GL_TEXTURE_MATRIX */ + 1535, /* GL_STENCIL_TEST */ + 1519, /* GL_STENCIL_CLEAR_VALUE */ + 1521, /* GL_STENCIL_FUNC */ + 1537, /* GL_STENCIL_VALUE_MASK */ + 1520, /* GL_STENCIL_FAIL */ + 1532, /* GL_STENCIL_PASS_DEPTH_FAIL */ + 1533, /* GL_STENCIL_PASS_DEPTH_PASS */ + 1534, /* GL_STENCIL_REF */ + 1538, /* GL_STENCIL_WRITEMASK */ + 854, /* GL_MATRIX_MODE */ + 1026, /* GL_NORMALIZE */ + 1865, /* GL_VIEWPORT */ + 1000, /* GL_MODELVIEW_STACK_DEPTH */ + 1264, /* GL_PROJECTION_STACK_DEPTH */ + 1745, /* GL_TEXTURE_STACK_DEPTH */ + 998, /* GL_MODELVIEW_MATRIX */ + 1263, /* GL_PROJECTION_MATRIX */ + 1728, /* GL_TEXTURE_MATRIX */ 61, /* GL_ATTRIB_STACK_DEPTH */ 136, /* GL_CLIENT_ATTRIB_STACK_DEPTH */ 43, /* GL_ALPHA_TEST */ @@ -3968,72 +3970,72 @@ static const unsigned reduced_enums[1350] = 78, /* GL_BLEND_DST */ 87, /* GL_BLEND_SRC */ 75, /* GL_BLEND */ - 722, /* GL_LOGIC_OP_MODE */ - 639, /* GL_INDEX_LOGIC_OP */ + 723, /* GL_LOGIC_OP_MODE */ + 640, /* GL_INDEX_LOGIC_OP */ 191, /* GL_COLOR_LOGIC_OP */ 67, /* GL_AUX_BUFFERS */ 394, /* GL_DRAW_BUFFER */ - 1303, /* GL_READ_BUFFER */ - 1417, /* GL_SCISSOR_BOX */ - 1418, /* GL_SCISSOR_TEST */ - 638, /* GL_INDEX_CLEAR_VALUE */ - 643, /* GL_INDEX_WRITEMASK */ + 1304, /* GL_READ_BUFFER */ + 1418, /* GL_SCISSOR_BOX */ + 1419, /* GL_SCISSOR_TEST */ + 639, /* GL_INDEX_CLEAR_VALUE */ + 644, /* GL_INDEX_WRITEMASK */ 188, /* GL_COLOR_CLEAR_VALUE */ 230, /* GL_COLOR_WRITEMASK */ - 640, /* GL_INDEX_MODE */ - 1383, /* GL_RGBA_MODE */ + 641, /* GL_INDEX_MODE */ + 1384, /* GL_RGBA_MODE */ 393, /* GL_DOUBLEBUFFER */ - 1538, /* GL_STEREO */ - 1341, /* GL_RENDER_MODE */ - 1111, /* GL_PERSPECTIVE_CORRECTION_HINT */ - 1164, /* GL_POINT_SMOOTH_HINT */ - 706, /* GL_LINE_SMOOTH_HINT */ - 1181, /* GL_POLYGON_SMOOTH_HINT */ + 1539, /* GL_STEREO */ + 1342, /* GL_RENDER_MODE */ + 1112, /* GL_PERSPECTIVE_CORRECTION_HINT */ + 1165, /* GL_POINT_SMOOTH_HINT */ + 707, /* GL_LINE_SMOOTH_HINT */ + 1182, /* GL_POLYGON_SMOOTH_HINT */ 529, /* GL_FOG_HINT */ - 1708, /* GL_TEXTURE_GEN_S */ - 1709, /* GL_TEXTURE_GEN_T */ - 1707, /* GL_TEXTURE_GEN_R */ - 1706, /* GL_TEXTURE_GEN_Q */ - 1124, /* GL_PIXEL_MAP_I_TO_I */ - 1130, /* GL_PIXEL_MAP_S_TO_S */ - 1126, /* GL_PIXEL_MAP_I_TO_R */ - 1122, /* GL_PIXEL_MAP_I_TO_G */ - 1120, /* GL_PIXEL_MAP_I_TO_B */ - 1118, /* GL_PIXEL_MAP_I_TO_A */ - 1128, /* GL_PIXEL_MAP_R_TO_R */ - 1116, /* GL_PIXEL_MAP_G_TO_G */ - 1114, /* GL_PIXEL_MAP_B_TO_B */ - 1112, /* GL_PIXEL_MAP_A_TO_A */ - 1125, /* GL_PIXEL_MAP_I_TO_I_SIZE */ - 1131, /* GL_PIXEL_MAP_S_TO_S_SIZE */ - 1127, /* GL_PIXEL_MAP_I_TO_R_SIZE */ - 1123, /* GL_PIXEL_MAP_I_TO_G_SIZE */ - 1121, /* GL_PIXEL_MAP_I_TO_B_SIZE */ - 1119, /* GL_PIXEL_MAP_I_TO_A_SIZE */ - 1129, /* GL_PIXEL_MAP_R_TO_R_SIZE */ - 1117, /* GL_PIXEL_MAP_G_TO_G_SIZE */ - 1115, /* GL_PIXEL_MAP_B_TO_B_SIZE */ - 1113, /* GL_PIXEL_MAP_A_TO_A_SIZE */ - 1781, /* GL_UNPACK_SWAP_BYTES */ - 1776, /* GL_UNPACK_LSB_FIRST */ - 1777, /* GL_UNPACK_ROW_LENGTH */ - 1780, /* GL_UNPACK_SKIP_ROWS */ - 1779, /* GL_UNPACK_SKIP_PIXELS */ - 1774, /* GL_UNPACK_ALIGNMENT */ - 1099, /* GL_PACK_SWAP_BYTES */ - 1094, /* GL_PACK_LSB_FIRST */ - 1095, /* GL_PACK_ROW_LENGTH */ - 1098, /* GL_PACK_SKIP_ROWS */ - 1097, /* GL_PACK_SKIP_PIXELS */ - 1091, /* GL_PACK_ALIGNMENT */ - 800, /* GL_MAP_COLOR */ - 805, /* GL_MAP_STENCIL */ - 642, /* GL_INDEX_SHIFT */ - 641, /* GL_INDEX_OFFSET */ - 1317, /* GL_RED_SCALE */ - 1315, /* GL_RED_BIAS */ - 1882, /* GL_ZOOM_X */ - 1883, /* GL_ZOOM_Y */ + 1709, /* GL_TEXTURE_GEN_S */ + 1710, /* GL_TEXTURE_GEN_T */ + 1708, /* GL_TEXTURE_GEN_R */ + 1707, /* GL_TEXTURE_GEN_Q */ + 1125, /* GL_PIXEL_MAP_I_TO_I */ + 1131, /* GL_PIXEL_MAP_S_TO_S */ + 1127, /* GL_PIXEL_MAP_I_TO_R */ + 1123, /* GL_PIXEL_MAP_I_TO_G */ + 1121, /* GL_PIXEL_MAP_I_TO_B */ + 1119, /* GL_PIXEL_MAP_I_TO_A */ + 1129, /* GL_PIXEL_MAP_R_TO_R */ + 1117, /* GL_PIXEL_MAP_G_TO_G */ + 1115, /* GL_PIXEL_MAP_B_TO_B */ + 1113, /* GL_PIXEL_MAP_A_TO_A */ + 1126, /* GL_PIXEL_MAP_I_TO_I_SIZE */ + 1132, /* GL_PIXEL_MAP_S_TO_S_SIZE */ + 1128, /* GL_PIXEL_MAP_I_TO_R_SIZE */ + 1124, /* GL_PIXEL_MAP_I_TO_G_SIZE */ + 1122, /* GL_PIXEL_MAP_I_TO_B_SIZE */ + 1120, /* GL_PIXEL_MAP_I_TO_A_SIZE */ + 1130, /* GL_PIXEL_MAP_R_TO_R_SIZE */ + 1118, /* GL_PIXEL_MAP_G_TO_G_SIZE */ + 1116, /* GL_PIXEL_MAP_B_TO_B_SIZE */ + 1114, /* GL_PIXEL_MAP_A_TO_A_SIZE */ + 1782, /* GL_UNPACK_SWAP_BYTES */ + 1777, /* GL_UNPACK_LSB_FIRST */ + 1778, /* GL_UNPACK_ROW_LENGTH */ + 1781, /* GL_UNPACK_SKIP_ROWS */ + 1780, /* GL_UNPACK_SKIP_PIXELS */ + 1775, /* GL_UNPACK_ALIGNMENT */ + 1100, /* GL_PACK_SWAP_BYTES */ + 1095, /* GL_PACK_LSB_FIRST */ + 1096, /* GL_PACK_ROW_LENGTH */ + 1099, /* GL_PACK_SKIP_ROWS */ + 1098, /* GL_PACK_SKIP_PIXELS */ + 1092, /* GL_PACK_ALIGNMENT */ + 801, /* GL_MAP_COLOR */ + 806, /* GL_MAP_STENCIL */ + 643, /* GL_INDEX_SHIFT */ + 642, /* GL_INDEX_OFFSET */ + 1318, /* GL_RED_SCALE */ + 1316, /* GL_RED_BIAS */ + 1883, /* GL_ZOOM_X */ + 1884, /* GL_ZOOM_Y */ 603, /* GL_GREEN_SCALE */ 601, /* GL_GREEN_BIAS */ 93, /* GL_BLUE_SCALE */ @@ -4042,375 +4044,376 @@ static const unsigned reduced_enums[1350] = 40, /* GL_ALPHA_BIAS */ 371, /* GL_DEPTH_SCALE */ 351, /* GL_DEPTH_BIAS */ - 880, /* GL_MAX_EVAL_ORDER */ - 884, /* GL_MAX_LIGHTS */ - 862, /* GL_MAX_CLIP_PLANES */ - 932, /* GL_MAX_TEXTURE_SIZE */ - 890, /* GL_MAX_PIXEL_MAP_TABLE */ - 858, /* GL_MAX_ATTRIB_STACK_DEPTH */ - 887, /* GL_MAX_MODELVIEW_STACK_DEPTH */ - 888, /* GL_MAX_NAME_STACK_DEPTH */ - 916, /* GL_MAX_PROJECTION_STACK_DEPTH */ - 933, /* GL_MAX_TEXTURE_STACK_DEPTH */ - 947, /* GL_MAX_VIEWPORT_DIMS */ - 859, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ - 1548, /* GL_SUBPIXEL_BITS */ - 637, /* GL_INDEX_BITS */ - 1316, /* GL_RED_BITS */ + 881, /* GL_MAX_EVAL_ORDER */ + 885, /* GL_MAX_LIGHTS */ + 863, /* GL_MAX_CLIP_PLANES */ + 933, /* GL_MAX_TEXTURE_SIZE */ + 891, /* GL_MAX_PIXEL_MAP_TABLE */ + 859, /* GL_MAX_ATTRIB_STACK_DEPTH */ + 888, /* GL_MAX_MODELVIEW_STACK_DEPTH */ + 889, /* GL_MAX_NAME_STACK_DEPTH */ + 917, /* GL_MAX_PROJECTION_STACK_DEPTH */ + 934, /* GL_MAX_TEXTURE_STACK_DEPTH */ + 948, /* GL_MAX_VIEWPORT_DIMS */ + 860, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */ + 1549, /* GL_SUBPIXEL_BITS */ + 638, /* GL_INDEX_BITS */ + 1317, /* GL_RED_BITS */ 602, /* GL_GREEN_BITS */ 92, /* GL_BLUE_BITS */ 41, /* GL_ALPHA_BITS */ 352, /* GL_DEPTH_BITS */ - 1516, /* GL_STENCIL_BITS */ + 1517, /* GL_STENCIL_BITS */ 14, /* GL_ACCUM_RED_BITS */ 13, /* GL_ACCUM_GREEN_BITS */ 10, /* GL_ACCUM_BLUE_BITS */ 9, /* GL_ACCUM_ALPHA_BITS */ - 1013, /* GL_NAME_STACK_DEPTH */ + 1014, /* GL_NAME_STACK_DEPTH */ 62, /* GL_AUTO_NORMAL */ - 746, /* GL_MAP1_COLOR_4 */ - 749, /* GL_MAP1_INDEX */ - 750, /* GL_MAP1_NORMAL */ - 751, /* GL_MAP1_TEXTURE_COORD_1 */ - 752, /* GL_MAP1_TEXTURE_COORD_2 */ - 753, /* GL_MAP1_TEXTURE_COORD_3 */ - 754, /* GL_MAP1_TEXTURE_COORD_4 */ - 755, /* GL_MAP1_VERTEX_3 */ - 756, /* GL_MAP1_VERTEX_4 */ - 773, /* GL_MAP2_COLOR_4 */ - 776, /* GL_MAP2_INDEX */ - 777, /* GL_MAP2_NORMAL */ - 778, /* GL_MAP2_TEXTURE_COORD_1 */ - 779, /* GL_MAP2_TEXTURE_COORD_2 */ - 780, /* GL_MAP2_TEXTURE_COORD_3 */ - 781, /* GL_MAP2_TEXTURE_COORD_4 */ - 782, /* GL_MAP2_VERTEX_3 */ - 783, /* GL_MAP2_VERTEX_4 */ - 747, /* GL_MAP1_GRID_DOMAIN */ - 748, /* GL_MAP1_GRID_SEGMENTS */ - 774, /* GL_MAP2_GRID_DOMAIN */ - 775, /* GL_MAP2_GRID_SEGMENTS */ - 1631, /* GL_TEXTURE_1D */ - 1633, /* GL_TEXTURE_2D */ + 747, /* GL_MAP1_COLOR_4 */ + 750, /* GL_MAP1_INDEX */ + 751, /* GL_MAP1_NORMAL */ + 752, /* GL_MAP1_TEXTURE_COORD_1 */ + 753, /* GL_MAP1_TEXTURE_COORD_2 */ + 754, /* GL_MAP1_TEXTURE_COORD_3 */ + 755, /* GL_MAP1_TEXTURE_COORD_4 */ + 756, /* GL_MAP1_VERTEX_3 */ + 757, /* GL_MAP1_VERTEX_4 */ + 774, /* GL_MAP2_COLOR_4 */ + 777, /* GL_MAP2_INDEX */ + 778, /* GL_MAP2_NORMAL */ + 779, /* GL_MAP2_TEXTURE_COORD_1 */ + 780, /* GL_MAP2_TEXTURE_COORD_2 */ + 781, /* GL_MAP2_TEXTURE_COORD_3 */ + 782, /* GL_MAP2_TEXTURE_COORD_4 */ + 783, /* GL_MAP2_VERTEX_3 */ + 784, /* GL_MAP2_VERTEX_4 */ + 748, /* GL_MAP1_GRID_DOMAIN */ + 749, /* GL_MAP1_GRID_SEGMENTS */ + 775, /* GL_MAP2_GRID_DOMAIN */ + 776, /* GL_MAP2_GRID_SEGMENTS */ + 1632, /* GL_TEXTURE_1D */ + 1634, /* GL_TEXTURE_2D */ 482, /* GL_FEEDBACK_BUFFER_POINTER */ 483, /* GL_FEEDBACK_BUFFER_SIZE */ 484, /* GL_FEEDBACK_BUFFER_TYPE */ - 1427, /* GL_SELECTION_BUFFER_POINTER */ - 1428, /* GL_SELECTION_BUFFER_SIZE */ - 1750, /* GL_TEXTURE_WIDTH */ - 1713, /* GL_TEXTURE_HEIGHT */ - 1668, /* GL_TEXTURE_COMPONENTS */ - 1652, /* GL_TEXTURE_BORDER_COLOR */ - 1651, /* GL_TEXTURE_BORDER */ + 1428, /* GL_SELECTION_BUFFER_POINTER */ + 1429, /* GL_SELECTION_BUFFER_SIZE */ + 1751, /* GL_TEXTURE_WIDTH */ + 1714, /* GL_TEXTURE_HEIGHT */ + 1669, /* GL_TEXTURE_COMPONENTS */ + 1653, /* GL_TEXTURE_BORDER_COLOR */ + 1652, /* GL_TEXTURE_BORDER */ 385, /* GL_DONT_CARE */ 480, /* GL_FASTEST */ - 1021, /* GL_NICEST */ + 1022, /* GL_NICEST */ 48, /* GL_AMBIENT */ 382, /* GL_DIFFUSE */ - 1476, /* GL_SPECULAR */ - 1185, /* GL_POSITION */ - 1479, /* GL_SPOT_DIRECTION */ - 1480, /* GL_SPOT_EXPONENT */ - 1478, /* GL_SPOT_CUTOFF */ + 1477, /* GL_SPECULAR */ + 1186, /* GL_POSITION */ + 1480, /* GL_SPOT_DIRECTION */ + 1481, /* GL_SPOT_EXPONENT */ + 1479, /* GL_SPOT_CUTOFF */ 275, /* GL_CONSTANT_ATTENUATION */ - 696, /* GL_LINEAR_ATTENUATION */ - 1284, /* GL_QUADRATIC_ATTENUATION */ + 697, /* GL_LINEAR_ATTENUATION */ + 1285, /* GL_QUADRATIC_ATTENUATION */ 244, /* GL_COMPILE */ 245, /* GL_COMPILE_AND_EXECUTE */ 120, /* GL_BYTE */ - 1783, /* GL_UNSIGNED_BYTE */ - 1441, /* GL_SHORT */ - 1795, /* GL_UNSIGNED_SHORT */ - 645, /* GL_INT */ - 1786, /* GL_UNSIGNED_INT */ + 1784, /* GL_UNSIGNED_BYTE */ + 1442, /* GL_SHORT */ + 1796, /* GL_UNSIGNED_SHORT */ + 646, /* GL_INT */ + 1787, /* GL_UNSIGNED_INT */ 489, /* GL_FLOAT */ 1, /* GL_2_BYTES */ 5, /* GL_3_BYTES */ 7, /* GL_4_BYTES */ 392, /* GL_DOUBLE */ + 604, /* GL_HALF_FLOAT */ 132, /* GL_CLEAR */ 50, /* GL_AND */ 52, /* GL_AND_REVERSE */ 299, /* GL_COPY */ 51, /* GL_AND_INVERTED */ - 1023, /* GL_NOOP */ - 1878, /* GL_XOR */ - 1086, /* GL_OR */ - 1024, /* GL_NOR */ + 1024, /* GL_NOOP */ + 1879, /* GL_XOR */ + 1087, /* GL_OR */ + 1025, /* GL_NOR */ 470, /* GL_EQUIV */ - 672, /* GL_INVERT */ - 1089, /* GL_OR_REVERSE */ + 673, /* GL_INVERT */ + 1090, /* GL_OR_REVERSE */ 300, /* GL_COPY_INVERTED */ - 1088, /* GL_OR_INVERTED */ - 1014, /* GL_NAND */ - 1432, /* GL_SET */ + 1089, /* GL_OR_INVERTED */ + 1015, /* GL_NAND */ + 1433, /* GL_SET */ 467, /* GL_EMISSION */ - 1440, /* GL_SHININESS */ + 1441, /* GL_SHININESS */ 49, /* GL_AMBIENT_AND_DIFFUSE */ 190, /* GL_COLOR_INDEXES */ - 964, /* GL_MODELVIEW */ - 1261, /* GL_PROJECTION */ - 1566, /* GL_TEXTURE */ + 965, /* GL_MODELVIEW */ + 1262, /* GL_PROJECTION */ + 1567, /* GL_TEXTURE */ 147, /* GL_COLOR */ 346, /* GL_DEPTH */ - 1502, /* GL_STENCIL */ + 1503, /* GL_STENCIL */ 189, /* GL_COLOR_INDEX */ - 1521, /* GL_STENCIL_INDEX */ + 1522, /* GL_STENCIL_INDEX */ 359, /* GL_DEPTH_COMPONENT */ - 1312, /* GL_RED */ + 1313, /* GL_RED */ 600, /* GL_GREEN */ 90, /* GL_BLUE */ 31, /* GL_ALPHA */ - 1349, /* GL_RGB */ - 1368, /* GL_RGBA */ - 724, /* GL_LUMINANCE */ - 745, /* GL_LUMINANCE_ALPHA */ + 1350, /* GL_RGB */ + 1369, /* GL_RGBA */ + 725, /* GL_LUMINANCE */ + 746, /* GL_LUMINANCE_ALPHA */ 73, /* GL_BITMAP */ - 1141, /* GL_POINT */ - 694, /* GL_LINE */ + 1142, /* GL_POINT */ + 695, /* GL_LINE */ 485, /* GL_FILL */ - 1321, /* GL_RENDER */ + 1322, /* GL_RENDER */ 481, /* GL_FEEDBACK */ - 1426, /* GL_SELECT */ + 1427, /* GL_SELECT */ 488, /* GL_FLAT */ - 1451, /* GL_SMOOTH */ - 673, /* GL_KEEP */ - 1343, /* GL_REPLACE */ - 627, /* GL_INCR */ + 1452, /* GL_SMOOTH */ + 674, /* GL_KEEP */ + 1344, /* GL_REPLACE */ + 628, /* GL_INCR */ 342, /* GL_DECR */ - 1810, /* GL_VENDOR */ - 1340, /* GL_RENDERER */ - 1811, /* GL_VERSION */ + 1811, /* GL_VENDOR */ + 1341, /* GL_RENDERER */ + 1812, /* GL_VERSION */ 474, /* GL_EXTENSIONS */ - 1391, /* GL_S */ - 1557, /* GL_T */ - 1300, /* GL_R */ - 1283, /* GL_Q */ - 1000, /* GL_MODULATE */ + 1392, /* GL_S */ + 1558, /* GL_T */ + 1301, /* GL_R */ + 1284, /* GL_Q */ + 1001, /* GL_MODULATE */ 341, /* GL_DECAL */ - 1703, /* GL_TEXTURE_ENV_MODE */ - 1702, /* GL_TEXTURE_ENV_COLOR */ - 1701, /* GL_TEXTURE_ENV */ + 1704, /* GL_TEXTURE_ENV_MODE */ + 1703, /* GL_TEXTURE_ENV_COLOR */ + 1702, /* GL_TEXTURE_ENV */ 475, /* GL_EYE_LINEAR */ - 1047, /* GL_OBJECT_LINEAR */ - 1477, /* GL_SPHERE_MAP */ - 1705, /* GL_TEXTURE_GEN_MODE */ - 1049, /* GL_OBJECT_PLANE */ + 1048, /* GL_OBJECT_LINEAR */ + 1478, /* GL_SPHERE_MAP */ + 1706, /* GL_TEXTURE_GEN_MODE */ + 1050, /* GL_OBJECT_PLANE */ 476, /* GL_EYE_PLANE */ - 1015, /* GL_NEAREST */ - 695, /* GL_LINEAR */ - 1019, /* GL_NEAREST_MIPMAP_NEAREST */ - 700, /* GL_LINEAR_MIPMAP_NEAREST */ - 1018, /* GL_NEAREST_MIPMAP_LINEAR */ - 699, /* GL_LINEAR_MIPMAP_LINEAR */ - 1726, /* GL_TEXTURE_MAG_FILTER */ - 1734, /* GL_TEXTURE_MIN_FILTER */ - 1752, /* GL_TEXTURE_WRAP_S */ - 1753, /* GL_TEXTURE_WRAP_T */ + 1016, /* GL_NEAREST */ + 696, /* GL_LINEAR */ + 1020, /* GL_NEAREST_MIPMAP_NEAREST */ + 701, /* GL_LINEAR_MIPMAP_NEAREST */ + 1019, /* GL_NEAREST_MIPMAP_LINEAR */ + 700, /* GL_LINEAR_MIPMAP_LINEAR */ + 1727, /* GL_TEXTURE_MAG_FILTER */ + 1735, /* GL_TEXTURE_MIN_FILTER */ + 1753, /* GL_TEXTURE_WRAP_S */ + 1754, /* GL_TEXTURE_WRAP_T */ 126, /* GL_CLAMP */ - 1342, /* GL_REPEAT */ - 1179, /* GL_POLYGON_OFFSET_UNITS */ - 1178, /* GL_POLYGON_OFFSET_POINT */ - 1177, /* GL_POLYGON_OFFSET_LINE */ - 1301, /* GL_R3_G3_B2 */ - 1807, /* GL_V2F */ - 1808, /* GL_V3F */ + 1343, /* GL_REPEAT */ + 1180, /* GL_POLYGON_OFFSET_UNITS */ + 1179, /* GL_POLYGON_OFFSET_POINT */ + 1178, /* GL_POLYGON_OFFSET_LINE */ + 1302, /* GL_R3_G3_B2 */ + 1808, /* GL_V2F */ + 1809, /* GL_V3F */ 123, /* GL_C4UB_V2F */ 124, /* GL_C4UB_V3F */ 121, /* GL_C3F_V3F */ - 1012, /* GL_N3F_V3F */ + 1013, /* GL_N3F_V3F */ 122, /* GL_C4F_N3F_V3F */ - 1562, /* GL_T2F_V3F */ - 1564, /* GL_T4F_V4F */ - 1560, /* GL_T2F_C4UB_V3F */ - 1558, /* GL_T2F_C3F_V3F */ - 1561, /* GL_T2F_N3F_V3F */ - 1559, /* GL_T2F_C4F_N3F_V3F */ - 1563, /* GL_T4F_C4F_N3F_V4F */ + 1563, /* GL_T2F_V3F */ + 1565, /* GL_T4F_V4F */ + 1561, /* GL_T2F_C4UB_V3F */ + 1559, /* GL_T2F_C3F_V3F */ + 1562, /* GL_T2F_N3F_V3F */ + 1560, /* GL_T2F_C4F_N3F_V3F */ + 1564, /* GL_T4F_C4F_N3F_V4F */ 139, /* GL_CLIP_PLANE0 */ 140, /* GL_CLIP_PLANE1 */ 141, /* GL_CLIP_PLANE2 */ 142, /* GL_CLIP_PLANE3 */ 143, /* GL_CLIP_PLANE4 */ 144, /* GL_CLIP_PLANE5 */ - 679, /* GL_LIGHT0 */ - 680, /* GL_LIGHT1 */ - 681, /* GL_LIGHT2 */ - 682, /* GL_LIGHT3 */ - 683, /* GL_LIGHT4 */ - 684, /* GL_LIGHT5 */ - 685, /* GL_LIGHT6 */ - 686, /* GL_LIGHT7 */ - 604, /* GL_HINT_BIT */ + 680, /* GL_LIGHT0 */ + 681, /* GL_LIGHT1 */ + 682, /* GL_LIGHT2 */ + 683, /* GL_LIGHT3 */ + 684, /* GL_LIGHT4 */ + 685, /* GL_LIGHT5 */ + 686, /* GL_LIGHT6 */ + 687, /* GL_LIGHT7 */ + 605, /* GL_HINT_BIT */ 277, /* GL_CONSTANT_COLOR */ - 1060, /* GL_ONE_MINUS_CONSTANT_COLOR */ + 1061, /* GL_ONE_MINUS_CONSTANT_COLOR */ 272, /* GL_CONSTANT_ALPHA */ - 1058, /* GL_ONE_MINUS_CONSTANT_ALPHA */ + 1059, /* GL_ONE_MINUS_CONSTANT_ALPHA */ 76, /* GL_BLEND_COLOR */ 588, /* GL_FUNC_ADD */ - 948, /* GL_MIN */ - 855, /* GL_MAX */ + 949, /* GL_MIN */ + 856, /* GL_MAX */ 81, /* GL_BLEND_EQUATION */ 592, /* GL_FUNC_SUBTRACT */ 590, /* GL_FUNC_REVERSE_SUBTRACT */ 280, /* GL_CONVOLUTION_1D */ 281, /* GL_CONVOLUTION_2D */ - 1429, /* GL_SEPARABLE_2D */ + 1430, /* GL_SEPARABLE_2D */ 284, /* GL_CONVOLUTION_BORDER_MODE */ 288, /* GL_CONVOLUTION_FILTER_SCALE */ 286, /* GL_CONVOLUTION_FILTER_BIAS */ - 1313, /* GL_REDUCE */ + 1314, /* GL_REDUCE */ 290, /* GL_CONVOLUTION_FORMAT */ 294, /* GL_CONVOLUTION_WIDTH */ 292, /* GL_CONVOLUTION_HEIGHT */ - 871, /* GL_MAX_CONVOLUTION_WIDTH */ - 869, /* GL_MAX_CONVOLUTION_HEIGHT */ - 1218, /* GL_POST_CONVOLUTION_RED_SCALE */ - 1214, /* GL_POST_CONVOLUTION_GREEN_SCALE */ - 1209, /* GL_POST_CONVOLUTION_BLUE_SCALE */ - 1205, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ - 1216, /* GL_POST_CONVOLUTION_RED_BIAS */ - 1212, /* GL_POST_CONVOLUTION_GREEN_BIAS */ - 1207, /* GL_POST_CONVOLUTION_BLUE_BIAS */ - 1203, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ - 605, /* GL_HISTOGRAM */ - 1267, /* GL_PROXY_HISTOGRAM */ - 621, /* GL_HISTOGRAM_WIDTH */ - 611, /* GL_HISTOGRAM_FORMAT */ - 617, /* GL_HISTOGRAM_RED_SIZE */ - 613, /* GL_HISTOGRAM_GREEN_SIZE */ - 608, /* GL_HISTOGRAM_BLUE_SIZE */ - 606, /* GL_HISTOGRAM_ALPHA_SIZE */ - 615, /* GL_HISTOGRAM_LUMINANCE_SIZE */ - 619, /* GL_HISTOGRAM_SINK */ - 949, /* GL_MINMAX */ - 951, /* GL_MINMAX_FORMAT */ - 953, /* GL_MINMAX_SINK */ - 1565, /* GL_TABLE_TOO_LARGE_EXT */ - 1785, /* GL_UNSIGNED_BYTE_3_3_2 */ - 1797, /* GL_UNSIGNED_SHORT_4_4_4_4 */ - 1799, /* GL_UNSIGNED_SHORT_5_5_5_1 */ - 1792, /* GL_UNSIGNED_INT_8_8_8_8 */ - 1787, /* GL_UNSIGNED_INT_10_10_10_2 */ - 1176, /* GL_POLYGON_OFFSET_FILL */ - 1175, /* GL_POLYGON_OFFSET_FACTOR */ - 1174, /* GL_POLYGON_OFFSET_BIAS */ - 1346, /* GL_RESCALE_NORMAL */ + 872, /* GL_MAX_CONVOLUTION_WIDTH */ + 870, /* GL_MAX_CONVOLUTION_HEIGHT */ + 1219, /* GL_POST_CONVOLUTION_RED_SCALE */ + 1215, /* GL_POST_CONVOLUTION_GREEN_SCALE */ + 1210, /* GL_POST_CONVOLUTION_BLUE_SCALE */ + 1206, /* GL_POST_CONVOLUTION_ALPHA_SCALE */ + 1217, /* GL_POST_CONVOLUTION_RED_BIAS */ + 1213, /* GL_POST_CONVOLUTION_GREEN_BIAS */ + 1208, /* GL_POST_CONVOLUTION_BLUE_BIAS */ + 1204, /* GL_POST_CONVOLUTION_ALPHA_BIAS */ + 606, /* GL_HISTOGRAM */ + 1268, /* GL_PROXY_HISTOGRAM */ + 622, /* GL_HISTOGRAM_WIDTH */ + 612, /* GL_HISTOGRAM_FORMAT */ + 618, /* GL_HISTOGRAM_RED_SIZE */ + 614, /* GL_HISTOGRAM_GREEN_SIZE */ + 609, /* GL_HISTOGRAM_BLUE_SIZE */ + 607, /* GL_HISTOGRAM_ALPHA_SIZE */ + 616, /* GL_HISTOGRAM_LUMINANCE_SIZE */ + 620, /* GL_HISTOGRAM_SINK */ + 950, /* GL_MINMAX */ + 952, /* GL_MINMAX_FORMAT */ + 954, /* GL_MINMAX_SINK */ + 1566, /* GL_TABLE_TOO_LARGE_EXT */ + 1786, /* GL_UNSIGNED_BYTE_3_3_2 */ + 1798, /* GL_UNSIGNED_SHORT_4_4_4_4 */ + 1800, /* GL_UNSIGNED_SHORT_5_5_5_1 */ + 1793, /* GL_UNSIGNED_INT_8_8_8_8 */ + 1788, /* GL_UNSIGNED_INT_10_10_10_2 */ + 1177, /* GL_POLYGON_OFFSET_FILL */ + 1176, /* GL_POLYGON_OFFSET_FACTOR */ + 1175, /* GL_POLYGON_OFFSET_BIAS */ + 1347, /* GL_RESCALE_NORMAL */ 36, /* GL_ALPHA4 */ 38, /* GL_ALPHA8 */ 32, /* GL_ALPHA12 */ 34, /* GL_ALPHA16 */ - 735, /* GL_LUMINANCE4 */ - 741, /* GL_LUMINANCE8 */ - 725, /* GL_LUMINANCE12 */ - 731, /* GL_LUMINANCE16 */ - 736, /* GL_LUMINANCE4_ALPHA4 */ - 739, /* GL_LUMINANCE6_ALPHA2 */ - 742, /* GL_LUMINANCE8_ALPHA8 */ - 728, /* GL_LUMINANCE12_ALPHA4 */ - 726, /* GL_LUMINANCE12_ALPHA12 */ - 732, /* GL_LUMINANCE16_ALPHA16 */ - 646, /* GL_INTENSITY */ - 651, /* GL_INTENSITY4 */ - 653, /* GL_INTENSITY8 */ - 647, /* GL_INTENSITY12 */ - 649, /* GL_INTENSITY16 */ - 1358, /* GL_RGB2_EXT */ - 1359, /* GL_RGB4 */ - 1362, /* GL_RGB5 */ - 1366, /* GL_RGB8 */ - 1350, /* GL_RGB10 */ - 1354, /* GL_RGB12 */ - 1356, /* GL_RGB16 */ - 1373, /* GL_RGBA2 */ - 1375, /* GL_RGBA4 */ - 1363, /* GL_RGB5_A1 */ - 1379, /* GL_RGBA8 */ - 1351, /* GL_RGB10_A2 */ - 1369, /* GL_RGBA12 */ - 1371, /* GL_RGBA16 */ - 1741, /* GL_TEXTURE_RED_SIZE */ - 1711, /* GL_TEXTURE_GREEN_SIZE */ - 1649, /* GL_TEXTURE_BLUE_SIZE */ - 1636, /* GL_TEXTURE_ALPHA_SIZE */ - 1724, /* GL_TEXTURE_LUMINANCE_SIZE */ - 1715, /* GL_TEXTURE_INTENSITY_SIZE */ - 1344, /* GL_REPLACE_EXT */ - 1271, /* GL_PROXY_TEXTURE_1D */ - 1274, /* GL_PROXY_TEXTURE_2D */ - 1748, /* GL_TEXTURE_TOO_LARGE_EXT */ - 1736, /* GL_TEXTURE_PRIORITY */ - 1743, /* GL_TEXTURE_RESIDENT */ - 1639, /* GL_TEXTURE_BINDING_1D */ - 1641, /* GL_TEXTURE_BINDING_2D */ - 1643, /* GL_TEXTURE_BINDING_3D */ - 1096, /* GL_PACK_SKIP_IMAGES */ - 1092, /* GL_PACK_IMAGE_HEIGHT */ - 1778, /* GL_UNPACK_SKIP_IMAGES */ - 1775, /* GL_UNPACK_IMAGE_HEIGHT */ - 1635, /* GL_TEXTURE_3D */ - 1277, /* GL_PROXY_TEXTURE_3D */ - 1698, /* GL_TEXTURE_DEPTH */ - 1751, /* GL_TEXTURE_WRAP_R */ - 856, /* GL_MAX_3D_TEXTURE_SIZE */ - 1812, /* GL_VERTEX_ARRAY */ - 1026, /* GL_NORMAL_ARRAY */ + 736, /* GL_LUMINANCE4 */ + 742, /* GL_LUMINANCE8 */ + 726, /* GL_LUMINANCE12 */ + 732, /* GL_LUMINANCE16 */ + 737, /* GL_LUMINANCE4_ALPHA4 */ + 740, /* GL_LUMINANCE6_ALPHA2 */ + 743, /* GL_LUMINANCE8_ALPHA8 */ + 729, /* GL_LUMINANCE12_ALPHA4 */ + 727, /* GL_LUMINANCE12_ALPHA12 */ + 733, /* GL_LUMINANCE16_ALPHA16 */ + 647, /* GL_INTENSITY */ + 652, /* GL_INTENSITY4 */ + 654, /* GL_INTENSITY8 */ + 648, /* GL_INTENSITY12 */ + 650, /* GL_INTENSITY16 */ + 1359, /* GL_RGB2_EXT */ + 1360, /* GL_RGB4 */ + 1363, /* GL_RGB5 */ + 1367, /* GL_RGB8 */ + 1351, /* GL_RGB10 */ + 1355, /* GL_RGB12 */ + 1357, /* GL_RGB16 */ + 1374, /* GL_RGBA2 */ + 1376, /* GL_RGBA4 */ + 1364, /* GL_RGB5_A1 */ + 1380, /* GL_RGBA8 */ + 1352, /* GL_RGB10_A2 */ + 1370, /* GL_RGBA12 */ + 1372, /* GL_RGBA16 */ + 1742, /* GL_TEXTURE_RED_SIZE */ + 1712, /* GL_TEXTURE_GREEN_SIZE */ + 1650, /* GL_TEXTURE_BLUE_SIZE */ + 1637, /* GL_TEXTURE_ALPHA_SIZE */ + 1725, /* GL_TEXTURE_LUMINANCE_SIZE */ + 1716, /* GL_TEXTURE_INTENSITY_SIZE */ + 1345, /* GL_REPLACE_EXT */ + 1272, /* GL_PROXY_TEXTURE_1D */ + 1275, /* GL_PROXY_TEXTURE_2D */ + 1749, /* GL_TEXTURE_TOO_LARGE_EXT */ + 1737, /* GL_TEXTURE_PRIORITY */ + 1744, /* GL_TEXTURE_RESIDENT */ + 1640, /* GL_TEXTURE_BINDING_1D */ + 1642, /* GL_TEXTURE_BINDING_2D */ + 1644, /* GL_TEXTURE_BINDING_3D */ + 1097, /* GL_PACK_SKIP_IMAGES */ + 1093, /* GL_PACK_IMAGE_HEIGHT */ + 1779, /* GL_UNPACK_SKIP_IMAGES */ + 1776, /* GL_UNPACK_IMAGE_HEIGHT */ + 1636, /* GL_TEXTURE_3D */ + 1278, /* GL_PROXY_TEXTURE_3D */ + 1699, /* GL_TEXTURE_DEPTH */ + 1752, /* GL_TEXTURE_WRAP_R */ + 857, /* GL_MAX_3D_TEXTURE_SIZE */ + 1813, /* GL_VERTEX_ARRAY */ + 1027, /* GL_NORMAL_ARRAY */ 148, /* GL_COLOR_ARRAY */ - 631, /* GL_INDEX_ARRAY */ - 1676, /* GL_TEXTURE_COORD_ARRAY */ + 632, /* GL_INDEX_ARRAY */ + 1677, /* GL_TEXTURE_COORD_ARRAY */ 459, /* GL_EDGE_FLAG_ARRAY */ - 1818, /* GL_VERTEX_ARRAY_SIZE */ - 1820, /* GL_VERTEX_ARRAY_TYPE */ - 1819, /* GL_VERTEX_ARRAY_STRIDE */ - 1031, /* GL_NORMAL_ARRAY_TYPE */ - 1030, /* GL_NORMAL_ARRAY_STRIDE */ + 1819, /* GL_VERTEX_ARRAY_SIZE */ + 1821, /* GL_VERTEX_ARRAY_TYPE */ + 1820, /* GL_VERTEX_ARRAY_STRIDE */ + 1032, /* GL_NORMAL_ARRAY_TYPE */ + 1031, /* GL_NORMAL_ARRAY_STRIDE */ 152, /* GL_COLOR_ARRAY_SIZE */ 154, /* GL_COLOR_ARRAY_TYPE */ 153, /* GL_COLOR_ARRAY_STRIDE */ - 636, /* GL_INDEX_ARRAY_TYPE */ - 635, /* GL_INDEX_ARRAY_STRIDE */ - 1680, /* GL_TEXTURE_COORD_ARRAY_SIZE */ - 1682, /* GL_TEXTURE_COORD_ARRAY_TYPE */ - 1681, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ + 637, /* GL_INDEX_ARRAY_TYPE */ + 636, /* GL_INDEX_ARRAY_STRIDE */ + 1681, /* GL_TEXTURE_COORD_ARRAY_SIZE */ + 1683, /* GL_TEXTURE_COORD_ARRAY_TYPE */ + 1682, /* GL_TEXTURE_COORD_ARRAY_STRIDE */ 463, /* GL_EDGE_FLAG_ARRAY_STRIDE */ - 1817, /* GL_VERTEX_ARRAY_POINTER */ - 1029, /* GL_NORMAL_ARRAY_POINTER */ + 1818, /* GL_VERTEX_ARRAY_POINTER */ + 1030, /* GL_NORMAL_ARRAY_POINTER */ 151, /* GL_COLOR_ARRAY_POINTER */ - 634, /* GL_INDEX_ARRAY_POINTER */ - 1679, /* GL_TEXTURE_COORD_ARRAY_POINTER */ + 635, /* GL_INDEX_ARRAY_POINTER */ + 1680, /* GL_TEXTURE_COORD_ARRAY_POINTER */ 462, /* GL_EDGE_FLAG_ARRAY_POINTER */ - 1005, /* GL_MULTISAMPLE */ - 1403, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ - 1405, /* GL_SAMPLE_ALPHA_TO_ONE */ - 1410, /* GL_SAMPLE_COVERAGE */ - 1407, /* GL_SAMPLE_BUFFERS */ - 1398, /* GL_SAMPLES */ - 1414, /* GL_SAMPLE_COVERAGE_VALUE */ - 1412, /* GL_SAMPLE_COVERAGE_INVERT */ + 1006, /* GL_MULTISAMPLE */ + 1404, /* GL_SAMPLE_ALPHA_TO_COVERAGE */ + 1406, /* GL_SAMPLE_ALPHA_TO_ONE */ + 1411, /* GL_SAMPLE_COVERAGE */ + 1408, /* GL_SAMPLE_BUFFERS */ + 1399, /* GL_SAMPLES */ + 1415, /* GL_SAMPLE_COVERAGE_VALUE */ + 1413, /* GL_SAMPLE_COVERAGE_INVERT */ 195, /* GL_COLOR_MATRIX */ 197, /* GL_COLOR_MATRIX_STACK_DEPTH */ - 865, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ - 1201, /* GL_POST_COLOR_MATRIX_RED_SCALE */ - 1197, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ - 1192, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ - 1188, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ - 1199, /* GL_POST_COLOR_MATRIX_RED_BIAS */ - 1195, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ - 1190, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ - 1186, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ - 1659, /* GL_TEXTURE_COLOR_TABLE_SGI */ - 1278, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ - 1661, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ + 866, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ + 1202, /* GL_POST_COLOR_MATRIX_RED_SCALE */ + 1198, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */ + 1193, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */ + 1189, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ + 1200, /* GL_POST_COLOR_MATRIX_RED_BIAS */ + 1196, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */ + 1191, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */ + 1187, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ + 1660, /* GL_TEXTURE_COLOR_TABLE_SGI */ + 1279, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */ + 1662, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ 80, /* GL_BLEND_DST_RGB */ 89, /* GL_BLEND_SRC_RGB */ 79, /* GL_BLEND_DST_ALPHA */ 88, /* GL_BLEND_SRC_ALPHA */ 201, /* GL_COLOR_TABLE */ - 1211, /* GL_POST_CONVOLUTION_COLOR_TABLE */ - 1194, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ - 1266, /* GL_PROXY_COLOR_TABLE */ - 1270, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ - 1269, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ + 1212, /* GL_POST_CONVOLUTION_COLOR_TABLE */ + 1195, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */ + 1267, /* GL_PROXY_COLOR_TABLE */ + 1271, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ + 1270, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ 225, /* GL_COLOR_TABLE_SCALE */ 205, /* GL_COLOR_TABLE_BIAS */ 210, /* GL_COLOR_TABLE_FORMAT */ @@ -4423,62 +4426,62 @@ static const unsigned reduced_enums[1350] = 216, /* GL_COLOR_TABLE_INTENSITY_SIZE */ 71, /* GL_BGR */ 72, /* GL_BGRA */ - 879, /* GL_MAX_ELEMENTS_VERTICES */ - 878, /* GL_MAX_ELEMENTS_INDICES */ - 1714, /* GL_TEXTURE_INDEX_SIZE_EXT */ + 880, /* GL_MAX_ELEMENTS_VERTICES */ + 879, /* GL_MAX_ELEMENTS_INDICES */ + 1715, /* GL_TEXTURE_INDEX_SIZE_EXT */ 145, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */ - 1158, /* GL_POINT_SIZE_MIN */ - 1154, /* GL_POINT_SIZE_MAX */ - 1148, /* GL_POINT_FADE_THRESHOLD_SIZE */ - 1144, /* GL_POINT_DISTANCE_ATTENUATION */ + 1159, /* GL_POINT_SIZE_MIN */ + 1155, /* GL_POINT_SIZE_MAX */ + 1149, /* GL_POINT_FADE_THRESHOLD_SIZE */ + 1145, /* GL_POINT_DISTANCE_ATTENUATION */ 127, /* GL_CLAMP_TO_BORDER */ 130, /* GL_CLAMP_TO_EDGE */ - 1735, /* GL_TEXTURE_MIN_LOD */ - 1733, /* GL_TEXTURE_MAX_LOD */ - 1638, /* GL_TEXTURE_BASE_LEVEL */ - 1732, /* GL_TEXTURE_MAX_LEVEL */ - 624, /* GL_IGNORE_BORDER_HP */ + 1736, /* GL_TEXTURE_MIN_LOD */ + 1734, /* GL_TEXTURE_MAX_LOD */ + 1639, /* GL_TEXTURE_BASE_LEVEL */ + 1733, /* GL_TEXTURE_MAX_LEVEL */ + 625, /* GL_IGNORE_BORDER_HP */ 276, /* GL_CONSTANT_BORDER_HP */ - 1345, /* GL_REPLICATE_BORDER_HP */ + 1346, /* GL_REPLICATE_BORDER_HP */ 282, /* GL_CONVOLUTION_BORDER_COLOR */ - 1055, /* GL_OCCLUSION_TEST_HP */ - 1056, /* GL_OCCLUSION_TEST_RESULT_HP */ - 697, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ - 1653, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ - 1655, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ - 1657, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ - 1658, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - 1656, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ - 1654, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ - 860, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ - 861, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ - 1221, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ - 1223, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ - 1220, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ - 1222, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ - 1722, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ - 1723, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ - 1721, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ + 1056, /* GL_OCCLUSION_TEST_HP */ + 1057, /* GL_OCCLUSION_TEST_RESULT_HP */ + 698, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */ + 1654, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */ + 1656, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */ + 1658, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */ + 1659, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */ + 1657, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */ + 1655, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */ + 861, /* GL_MAX_CLIPMAP_DEPTH_SGIX */ + 862, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */ + 1222, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */ + 1224, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */ + 1221, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */ + 1223, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */ + 1723, /* GL_TEXTURE_LOD_BIAS_S_SGIX */ + 1724, /* GL_TEXTURE_LOD_BIAS_T_SGIX */ + 1722, /* GL_TEXTURE_LOD_BIAS_R_SGIX */ 594, /* GL_GENERATE_MIPMAP */ 595, /* GL_GENERATE_MIPMAP_HINT */ 532, /* GL_FOG_OFFSET_SGIX */ 533, /* GL_FOG_OFFSET_VALUE_SGIX */ - 1667, /* GL_TEXTURE_COMPARE_SGIX */ - 1666, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ - 1718, /* GL_TEXTURE_LEQUAL_R_SGIX */ - 1710, /* GL_TEXTURE_GEQUAL_R_SGIX */ + 1668, /* GL_TEXTURE_COMPARE_SGIX */ + 1667, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */ + 1719, /* GL_TEXTURE_LEQUAL_R_SGIX */ + 1711, /* GL_TEXTURE_GEQUAL_R_SGIX */ 360, /* GL_DEPTH_COMPONENT16 */ 363, /* GL_DEPTH_COMPONENT24 */ 366, /* GL_DEPTH_COMPONENT32 */ 306, /* GL_CULL_VERTEX_EXT */ 308, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */ 307, /* GL_CULL_VERTEX_EYE_POSITION_EXT */ - 1875, /* GL_WRAP_BORDER_SUN */ - 1660, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ - 690, /* GL_LIGHT_MODEL_COLOR_CONTROL */ - 1444, /* GL_SINGLE_COLOR */ - 1430, /* GL_SEPARATE_SPECULAR_COLOR */ - 1439, /* GL_SHARED_TEXTURE_PALETTE_EXT */ + 1876, /* GL_WRAP_BORDER_SUN */ + 1661, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */ + 691, /* GL_LIGHT_MODEL_COLOR_CONTROL */ + 1445, /* GL_SINGLE_COLOR */ + 1431, /* GL_SEPARATE_SPECULAR_COLOR */ + 1440, /* GL_SHARED_TEXTURE_PALETTE_EXT */ 543, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ 544, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ 551, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ @@ -4490,31 +4493,31 @@ static const unsigned reduced_enums[1350] = 564, /* GL_FRAMEBUFFER_DEFAULT */ 580, /* GL_FRAMEBUFFER_UNDEFINED */ 373, /* GL_DEPTH_STENCIL_ATTACHMENT */ - 630, /* GL_INDEX */ - 1784, /* GL_UNSIGNED_BYTE_2_3_3_REV */ - 1800, /* GL_UNSIGNED_SHORT_5_6_5 */ - 1801, /* GL_UNSIGNED_SHORT_5_6_5_REV */ - 1798, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ - 1796, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ - 1793, /* GL_UNSIGNED_INT_8_8_8_8_REV */ - 1791, /* GL_UNSIGNED_INT_2_10_10_10_REV */ - 1730, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ - 1731, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ - 1729, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ - 956, /* GL_MIRRORED_REPEAT */ - 1386, /* GL_RGB_S3TC */ - 1361, /* GL_RGB4_S3TC */ - 1384, /* GL_RGBA_S3TC */ - 1378, /* GL_RGBA4_S3TC */ - 1382, /* GL_RGBA_DXT5_S3TC */ - 1376, /* GL_RGBA4_DXT5_S3TC */ + 631, /* GL_INDEX */ + 1785, /* GL_UNSIGNED_BYTE_2_3_3_REV */ + 1801, /* GL_UNSIGNED_SHORT_5_6_5 */ + 1802, /* GL_UNSIGNED_SHORT_5_6_5_REV */ + 1799, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */ + 1797, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */ + 1794, /* GL_UNSIGNED_INT_8_8_8_8_REV */ + 1792, /* GL_UNSIGNED_INT_2_10_10_10_REV */ + 1731, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */ + 1732, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */ + 1730, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */ + 957, /* GL_MIRRORED_REPEAT */ + 1387, /* GL_RGB_S3TC */ + 1362, /* GL_RGB4_S3TC */ + 1385, /* GL_RGBA_S3TC */ + 1379, /* GL_RGBA4_S3TC */ + 1383, /* GL_RGBA_DXT5_S3TC */ + 1377, /* GL_RGBA4_DXT5_S3TC */ 264, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */ 259, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */ 260, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */ 261, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */ - 1017, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ - 1016, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ - 698, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ + 1018, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */ + 1017, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */ + 699, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */ 519, /* GL_FOG_COORDINATE_SOURCE */ 511, /* GL_FOG_COORD */ 535, /* GL_FRAGMENT_DEPTH */ @@ -4525,278 +4528,278 @@ static const unsigned reduced_enums[1350] = 513, /* GL_FOG_COORDINATE_ARRAY */ 199, /* GL_COLOR_SUM */ 332, /* GL_CURRENT_SECONDARY_COLOR */ - 1423, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ - 1425, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ - 1424, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ - 1422, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ - 1419, /* GL_SECONDARY_COLOR_ARRAY */ + 1424, /* GL_SECONDARY_COLOR_ARRAY_SIZE */ + 1426, /* GL_SECONDARY_COLOR_ARRAY_TYPE */ + 1425, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */ + 1423, /* GL_SECONDARY_COLOR_ARRAY_POINTER */ + 1420, /* GL_SECONDARY_COLOR_ARRAY */ 330, /* GL_CURRENT_RASTER_SECONDARY_COLOR */ 28, /* GL_ALIASED_POINT_SIZE_RANGE */ 27, /* GL_ALIASED_LINE_WIDTH_RANGE */ - 1567, /* GL_TEXTURE0 */ - 1569, /* GL_TEXTURE1 */ - 1591, /* GL_TEXTURE2 */ - 1613, /* GL_TEXTURE3 */ - 1619, /* GL_TEXTURE4 */ - 1621, /* GL_TEXTURE5 */ - 1623, /* GL_TEXTURE6 */ - 1625, /* GL_TEXTURE7 */ - 1627, /* GL_TEXTURE8 */ - 1629, /* GL_TEXTURE9 */ - 1570, /* GL_TEXTURE10 */ - 1572, /* GL_TEXTURE11 */ - 1574, /* GL_TEXTURE12 */ - 1576, /* GL_TEXTURE13 */ - 1578, /* GL_TEXTURE14 */ - 1580, /* GL_TEXTURE15 */ - 1582, /* GL_TEXTURE16 */ - 1584, /* GL_TEXTURE17 */ - 1586, /* GL_TEXTURE18 */ - 1588, /* GL_TEXTURE19 */ - 1592, /* GL_TEXTURE20 */ - 1594, /* GL_TEXTURE21 */ - 1596, /* GL_TEXTURE22 */ - 1598, /* GL_TEXTURE23 */ - 1600, /* GL_TEXTURE24 */ - 1602, /* GL_TEXTURE25 */ - 1604, /* GL_TEXTURE26 */ - 1606, /* GL_TEXTURE27 */ - 1608, /* GL_TEXTURE28 */ - 1610, /* GL_TEXTURE29 */ - 1614, /* GL_TEXTURE30 */ - 1616, /* GL_TEXTURE31 */ + 1568, /* GL_TEXTURE0 */ + 1570, /* GL_TEXTURE1 */ + 1592, /* GL_TEXTURE2 */ + 1614, /* GL_TEXTURE3 */ + 1620, /* GL_TEXTURE4 */ + 1622, /* GL_TEXTURE5 */ + 1624, /* GL_TEXTURE6 */ + 1626, /* GL_TEXTURE7 */ + 1628, /* GL_TEXTURE8 */ + 1630, /* GL_TEXTURE9 */ + 1571, /* GL_TEXTURE10 */ + 1573, /* GL_TEXTURE11 */ + 1575, /* GL_TEXTURE12 */ + 1577, /* GL_TEXTURE13 */ + 1579, /* GL_TEXTURE14 */ + 1581, /* GL_TEXTURE15 */ + 1583, /* GL_TEXTURE16 */ + 1585, /* GL_TEXTURE17 */ + 1587, /* GL_TEXTURE18 */ + 1589, /* GL_TEXTURE19 */ + 1593, /* GL_TEXTURE20 */ + 1595, /* GL_TEXTURE21 */ + 1597, /* GL_TEXTURE22 */ + 1599, /* GL_TEXTURE23 */ + 1601, /* GL_TEXTURE24 */ + 1603, /* GL_TEXTURE25 */ + 1605, /* GL_TEXTURE26 */ + 1607, /* GL_TEXTURE27 */ + 1609, /* GL_TEXTURE28 */ + 1611, /* GL_TEXTURE29 */ + 1615, /* GL_TEXTURE30 */ + 1617, /* GL_TEXTURE31 */ 18, /* GL_ACTIVE_TEXTURE */ 133, /* GL_CLIENT_ACTIVE_TEXTURE */ - 934, /* GL_MAX_TEXTURE_UNITS */ - 1762, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ - 1765, /* GL_TRANSPOSE_PROJECTION_MATRIX */ - 1767, /* GL_TRANSPOSE_TEXTURE_MATRIX */ - 1759, /* GL_TRANSPOSE_COLOR_MATRIX */ - 1549, /* GL_SUBTRACT */ - 919, /* GL_MAX_RENDERBUFFER_SIZE */ + 935, /* GL_MAX_TEXTURE_UNITS */ + 1763, /* GL_TRANSPOSE_MODELVIEW_MATRIX */ + 1766, /* GL_TRANSPOSE_PROJECTION_MATRIX */ + 1768, /* GL_TRANSPOSE_TEXTURE_MATRIX */ + 1760, /* GL_TRANSPOSE_COLOR_MATRIX */ + 1550, /* GL_SUBTRACT */ + 920, /* GL_MAX_RENDERBUFFER_SIZE */ 247, /* GL_COMPRESSED_ALPHA */ 251, /* GL_COMPRESSED_LUMINANCE */ 252, /* GL_COMPRESSED_LUMINANCE_ALPHA */ 249, /* GL_COMPRESSED_INTENSITY */ 255, /* GL_COMPRESSED_RGB */ 256, /* GL_COMPRESSED_RGBA */ - 1674, /* GL_TEXTURE_COMPRESSION_HINT */ - 1739, /* GL_TEXTURE_RECTANGLE_ARB */ - 1646, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ - 1281, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ - 917, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ + 1675, /* GL_TEXTURE_COMPRESSION_HINT */ + 1740, /* GL_TEXTURE_RECTANGLE_ARB */ + 1647, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */ + 1282, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */ + 918, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */ 372, /* GL_DEPTH_STENCIL */ - 1788, /* GL_UNSIGNED_INT_24_8 */ - 930, /* GL_MAX_TEXTURE_LOD_BIAS */ - 1728, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ - 931, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ - 1704, /* GL_TEXTURE_FILTER_CONTROL */ - 1719, /* GL_TEXTURE_LOD_BIAS */ + 1789, /* GL_UNSIGNED_INT_24_8 */ + 931, /* GL_MAX_TEXTURE_LOD_BIAS */ + 1729, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */ + 932, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */ + 1705, /* GL_TEXTURE_FILTER_CONTROL */ + 1720, /* GL_TEXTURE_LOD_BIAS */ 232, /* GL_COMBINE4 */ - 924, /* GL_MAX_SHININESS_NV */ - 925, /* GL_MAX_SPOT_EXPONENT_NV */ - 628, /* GL_INCR_WRAP */ + 925, /* GL_MAX_SHININESS_NV */ + 926, /* GL_MAX_SPOT_EXPONENT_NV */ + 629, /* GL_INCR_WRAP */ 343, /* GL_DECR_WRAP */ - 976, /* GL_MODELVIEW1_ARB */ - 1032, /* GL_NORMAL_MAP */ - 1318, /* GL_REFLECTION_MAP */ - 1683, /* GL_TEXTURE_CUBE_MAP */ - 1644, /* GL_TEXTURE_BINDING_CUBE_MAP */ - 1691, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ - 1685, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ - 1693, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ - 1687, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ - 1695, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ - 1689, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ - 1279, /* GL_PROXY_TEXTURE_CUBE_MAP */ - 873, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ - 1011, /* GL_MULTISAMPLE_FILTER_HINT_NV */ + 977, /* GL_MODELVIEW1_ARB */ + 1033, /* GL_NORMAL_MAP */ + 1319, /* GL_REFLECTION_MAP */ + 1684, /* GL_TEXTURE_CUBE_MAP */ + 1645, /* GL_TEXTURE_BINDING_CUBE_MAP */ + 1692, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */ + 1686, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */ + 1694, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */ + 1688, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */ + 1696, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */ + 1690, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */ + 1280, /* GL_PROXY_TEXTURE_CUBE_MAP */ + 874, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */ + 1012, /* GL_MULTISAMPLE_FILTER_HINT_NV */ 527, /* GL_FOG_DISTANCE_MODE_NV */ 478, /* GL_EYE_RADIAL_NV */ 477, /* GL_EYE_PLANE_ABSOLUTE_NV */ 231, /* GL_COMBINE */ 238, /* GL_COMBINE_RGB */ 233, /* GL_COMBINE_ALPHA */ - 1387, /* GL_RGB_SCALE */ + 1388, /* GL_RGB_SCALE */ 24, /* GL_ADD_SIGNED */ - 656, /* GL_INTERPOLATE */ + 657, /* GL_INTERPOLATE */ 271, /* GL_CONSTANT */ - 1227, /* GL_PRIMARY_COLOR */ - 1224, /* GL_PREVIOUS */ - 1459, /* GL_SOURCE0_RGB */ - 1465, /* GL_SOURCE1_RGB */ - 1471, /* GL_SOURCE2_RGB */ - 1475, /* GL_SOURCE3_RGB_NV */ - 1456, /* GL_SOURCE0_ALPHA */ - 1462, /* GL_SOURCE1_ALPHA */ - 1468, /* GL_SOURCE2_ALPHA */ - 1474, /* GL_SOURCE3_ALPHA_NV */ - 1069, /* GL_OPERAND0_RGB */ - 1075, /* GL_OPERAND1_RGB */ - 1081, /* GL_OPERAND2_RGB */ - 1085, /* GL_OPERAND3_RGB_NV */ - 1066, /* GL_OPERAND0_ALPHA */ - 1072, /* GL_OPERAND1_ALPHA */ - 1078, /* GL_OPERAND2_ALPHA */ - 1084, /* GL_OPERAND3_ALPHA_NV */ - 1813, /* GL_VERTEX_ARRAY_BINDING */ - 1737, /* GL_TEXTURE_RANGE_LENGTH_APPLE */ - 1738, /* GL_TEXTURE_RANGE_POINTER_APPLE */ - 1879, /* GL_YCBCR_422_APPLE */ - 1802, /* GL_UNSIGNED_SHORT_8_8_APPLE */ - 1804, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ - 1747, /* GL_TEXTURE_STORAGE_HINT_APPLE */ - 1540, /* GL_STORAGE_PRIVATE_APPLE */ - 1539, /* GL_STORAGE_CACHED_APPLE */ - 1541, /* GL_STORAGE_SHARED_APPLE */ - 1446, /* GL_SLICE_ACCUM_SUN */ - 1288, /* GL_QUAD_MESH_SUN */ - 1771, /* GL_TRIANGLE_MESH_SUN */ - 1852, /* GL_VERTEX_PROGRAM_ARB */ - 1863, /* GL_VERTEX_STATE_PROGRAM_NV */ - 1839, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ - 1845, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ - 1847, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ - 1849, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ + 1228, /* GL_PRIMARY_COLOR */ + 1225, /* GL_PREVIOUS */ + 1460, /* GL_SOURCE0_RGB */ + 1466, /* GL_SOURCE1_RGB */ + 1472, /* GL_SOURCE2_RGB */ + 1476, /* GL_SOURCE3_RGB_NV */ + 1457, /* GL_SOURCE0_ALPHA */ + 1463, /* GL_SOURCE1_ALPHA */ + 1469, /* GL_SOURCE2_ALPHA */ + 1475, /* GL_SOURCE3_ALPHA_NV */ + 1070, /* GL_OPERAND0_RGB */ + 1076, /* GL_OPERAND1_RGB */ + 1082, /* GL_OPERAND2_RGB */ + 1086, /* GL_OPERAND3_RGB_NV */ + 1067, /* GL_OPERAND0_ALPHA */ + 1073, /* GL_OPERAND1_ALPHA */ + 1079, /* GL_OPERAND2_ALPHA */ + 1085, /* GL_OPERAND3_ALPHA_NV */ + 1814, /* GL_VERTEX_ARRAY_BINDING */ + 1738, /* GL_TEXTURE_RANGE_LENGTH_APPLE */ + 1739, /* GL_TEXTURE_RANGE_POINTER_APPLE */ + 1880, /* GL_YCBCR_422_APPLE */ + 1803, /* GL_UNSIGNED_SHORT_8_8_APPLE */ + 1805, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */ + 1748, /* GL_TEXTURE_STORAGE_HINT_APPLE */ + 1541, /* GL_STORAGE_PRIVATE_APPLE */ + 1540, /* GL_STORAGE_CACHED_APPLE */ + 1542, /* GL_STORAGE_SHARED_APPLE */ + 1447, /* GL_SLICE_ACCUM_SUN */ + 1289, /* GL_QUAD_MESH_SUN */ + 1772, /* GL_TRIANGLE_MESH_SUN */ + 1853, /* GL_VERTEX_PROGRAM_ARB */ + 1864, /* GL_VERTEX_STATE_PROGRAM_NV */ + 1840, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */ + 1846, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */ + 1848, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */ + 1850, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */ 334, /* GL_CURRENT_VERTEX_ATTRIB */ - 1240, /* GL_PROGRAM_LENGTH_ARB */ - 1254, /* GL_PROGRAM_STRING_ARB */ - 998, /* GL_MODELVIEW_PROJECTION_NV */ - 623, /* GL_IDENTITY_NV */ - 670, /* GL_INVERSE_NV */ - 1764, /* GL_TRANSPOSE_NV */ - 671, /* GL_INVERSE_TRANSPOSE_NV */ - 903, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ - 902, /* GL_MAX_PROGRAM_MATRICES_ARB */ - 809, /* GL_MATRIX0_NV */ - 821, /* GL_MATRIX1_NV */ - 833, /* GL_MATRIX2_NV */ - 837, /* GL_MATRIX3_NV */ - 839, /* GL_MATRIX4_NV */ - 841, /* GL_MATRIX5_NV */ - 843, /* GL_MATRIX6_NV */ - 845, /* GL_MATRIX7_NV */ + 1241, /* GL_PROGRAM_LENGTH_ARB */ + 1255, /* GL_PROGRAM_STRING_ARB */ + 999, /* GL_MODELVIEW_PROJECTION_NV */ + 624, /* GL_IDENTITY_NV */ + 671, /* GL_INVERSE_NV */ + 1765, /* GL_TRANSPOSE_NV */ + 672, /* GL_INVERSE_TRANSPOSE_NV */ + 904, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */ + 903, /* GL_MAX_PROGRAM_MATRICES_ARB */ + 810, /* GL_MATRIX0_NV */ + 822, /* GL_MATRIX1_NV */ + 834, /* GL_MATRIX2_NV */ + 838, /* GL_MATRIX3_NV */ + 840, /* GL_MATRIX4_NV */ + 842, /* GL_MATRIX5_NV */ + 844, /* GL_MATRIX6_NV */ + 846, /* GL_MATRIX7_NV */ 318, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */ 315, /* GL_CURRENT_MATRIX_ARB */ - 1855, /* GL_VERTEX_PROGRAM_POINT_SIZE */ - 1858, /* GL_VERTEX_PROGRAM_TWO_SIDE */ - 1252, /* GL_PROGRAM_PARAMETER_NV */ - 1843, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ - 1256, /* GL_PROGRAM_TARGET_NV */ - 1253, /* GL_PROGRAM_RESIDENT_NV */ - 1756, /* GL_TRACK_MATRIX_NV */ - 1757, /* GL_TRACK_MATRIX_TRANSFORM_NV */ - 1853, /* GL_VERTEX_PROGRAM_BINDING_NV */ - 1234, /* GL_PROGRAM_ERROR_POSITION_ARB */ + 1856, /* GL_VERTEX_PROGRAM_POINT_SIZE */ + 1859, /* GL_VERTEX_PROGRAM_TWO_SIDE */ + 1253, /* GL_PROGRAM_PARAMETER_NV */ + 1844, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */ + 1257, /* GL_PROGRAM_TARGET_NV */ + 1254, /* GL_PROGRAM_RESIDENT_NV */ + 1757, /* GL_TRACK_MATRIX_NV */ + 1758, /* GL_TRACK_MATRIX_TRANSFORM_NV */ + 1854, /* GL_VERTEX_PROGRAM_BINDING_NV */ + 1235, /* GL_PROGRAM_ERROR_POSITION_ARB */ 356, /* GL_DEPTH_CLAMP */ - 1821, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ - 1828, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ - 1829, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ - 1830, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ - 1831, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ - 1832, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ - 1833, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ - 1834, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ - 1835, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ - 1836, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ - 1822, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ - 1823, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ - 1824, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ - 1825, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ - 1826, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ - 1827, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ - 757, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ - 764, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ - 765, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ - 766, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ - 767, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ - 768, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ - 769, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ - 770, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ - 771, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ - 772, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ - 758, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ - 759, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ - 760, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ - 761, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ - 762, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ - 763, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ - 784, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ - 791, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ - 792, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ - 793, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ - 794, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ - 795, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ - 796, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ - 1233, /* GL_PROGRAM_BINDING_ARB */ - 798, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ - 799, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ - 785, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ - 786, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ - 787, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ - 788, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ - 789, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ - 790, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ - 1672, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ - 1669, /* GL_TEXTURE_COMPRESSED */ - 1037, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ + 1822, /* GL_VERTEX_ATTRIB_ARRAY0_NV */ + 1829, /* GL_VERTEX_ATTRIB_ARRAY1_NV */ + 1830, /* GL_VERTEX_ATTRIB_ARRAY2_NV */ + 1831, /* GL_VERTEX_ATTRIB_ARRAY3_NV */ + 1832, /* GL_VERTEX_ATTRIB_ARRAY4_NV */ + 1833, /* GL_VERTEX_ATTRIB_ARRAY5_NV */ + 1834, /* GL_VERTEX_ATTRIB_ARRAY6_NV */ + 1835, /* GL_VERTEX_ATTRIB_ARRAY7_NV */ + 1836, /* GL_VERTEX_ATTRIB_ARRAY8_NV */ + 1837, /* GL_VERTEX_ATTRIB_ARRAY9_NV */ + 1823, /* GL_VERTEX_ATTRIB_ARRAY10_NV */ + 1824, /* GL_VERTEX_ATTRIB_ARRAY11_NV */ + 1825, /* GL_VERTEX_ATTRIB_ARRAY12_NV */ + 1826, /* GL_VERTEX_ATTRIB_ARRAY13_NV */ + 1827, /* GL_VERTEX_ATTRIB_ARRAY14_NV */ + 1828, /* GL_VERTEX_ATTRIB_ARRAY15_NV */ + 758, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */ + 765, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */ + 766, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */ + 767, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */ + 768, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */ + 769, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */ + 770, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */ + 771, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */ + 772, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */ + 773, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */ + 759, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */ + 760, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */ + 761, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */ + 762, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */ + 763, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */ + 764, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */ + 785, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */ + 792, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */ + 793, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */ + 794, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */ + 795, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */ + 796, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */ + 797, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */ + 1234, /* GL_PROGRAM_BINDING_ARB */ + 799, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */ + 800, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */ + 786, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */ + 787, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */ + 788, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */ + 789, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */ + 790, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */ + 791, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */ + 1673, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */ + 1670, /* GL_TEXTURE_COMPRESSED */ + 1038, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */ 269, /* GL_COMPRESSED_TEXTURE_FORMATS */ - 946, /* GL_MAX_VERTEX_UNITS_ARB */ + 947, /* GL_MAX_VERTEX_UNITS_ARB */ 22, /* GL_ACTIVE_VERTEX_UNITS_ARB */ - 1874, /* GL_WEIGHT_SUM_UNITY_ARB */ - 1851, /* GL_VERTEX_BLEND_ARB */ + 1875, /* GL_WEIGHT_SUM_UNITY_ARB */ + 1852, /* GL_VERTEX_BLEND_ARB */ 336, /* GL_CURRENT_WEIGHT_ARB */ - 1873, /* GL_WEIGHT_ARRAY_TYPE_ARB */ - 1872, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ - 1871, /* GL_WEIGHT_ARRAY_SIZE_ARB */ - 1870, /* GL_WEIGHT_ARRAY_POINTER_ARB */ - 1867, /* GL_WEIGHT_ARRAY_ARB */ + 1874, /* GL_WEIGHT_ARRAY_TYPE_ARB */ + 1873, /* GL_WEIGHT_ARRAY_STRIDE_ARB */ + 1872, /* GL_WEIGHT_ARRAY_SIZE_ARB */ + 1871, /* GL_WEIGHT_ARRAY_POINTER_ARB */ + 1868, /* GL_WEIGHT_ARRAY_ARB */ 386, /* GL_DOT3_RGB */ 387, /* GL_DOT3_RGBA */ 263, /* GL_COMPRESSED_RGB_FXT1_3DFX */ 258, /* GL_COMPRESSED_RGBA_FXT1_3DFX */ - 1006, /* GL_MULTISAMPLE_3DFX */ - 1408, /* GL_SAMPLE_BUFFERS_3DFX */ - 1399, /* GL_SAMPLES_3DFX */ - 987, /* GL_MODELVIEW2_ARB */ - 990, /* GL_MODELVIEW3_ARB */ - 991, /* GL_MODELVIEW4_ARB */ - 992, /* GL_MODELVIEW5_ARB */ - 993, /* GL_MODELVIEW6_ARB */ - 994, /* GL_MODELVIEW7_ARB */ - 995, /* GL_MODELVIEW8_ARB */ - 996, /* GL_MODELVIEW9_ARB */ - 966, /* GL_MODELVIEW10_ARB */ - 967, /* GL_MODELVIEW11_ARB */ - 968, /* GL_MODELVIEW12_ARB */ - 969, /* GL_MODELVIEW13_ARB */ - 970, /* GL_MODELVIEW14_ARB */ - 971, /* GL_MODELVIEW15_ARB */ - 972, /* GL_MODELVIEW16_ARB */ - 973, /* GL_MODELVIEW17_ARB */ - 974, /* GL_MODELVIEW18_ARB */ - 975, /* GL_MODELVIEW19_ARB */ - 977, /* GL_MODELVIEW20_ARB */ - 978, /* GL_MODELVIEW21_ARB */ - 979, /* GL_MODELVIEW22_ARB */ - 980, /* GL_MODELVIEW23_ARB */ - 981, /* GL_MODELVIEW24_ARB */ - 982, /* GL_MODELVIEW25_ARB */ - 983, /* GL_MODELVIEW26_ARB */ - 984, /* GL_MODELVIEW27_ARB */ - 985, /* GL_MODELVIEW28_ARB */ - 986, /* GL_MODELVIEW29_ARB */ - 988, /* GL_MODELVIEW30_ARB */ - 989, /* GL_MODELVIEW31_ARB */ + 1007, /* GL_MULTISAMPLE_3DFX */ + 1409, /* GL_SAMPLE_BUFFERS_3DFX */ + 1400, /* GL_SAMPLES_3DFX */ + 988, /* GL_MODELVIEW2_ARB */ + 991, /* GL_MODELVIEW3_ARB */ + 992, /* GL_MODELVIEW4_ARB */ + 993, /* GL_MODELVIEW5_ARB */ + 994, /* GL_MODELVIEW6_ARB */ + 995, /* GL_MODELVIEW7_ARB */ + 996, /* GL_MODELVIEW8_ARB */ + 997, /* GL_MODELVIEW9_ARB */ + 967, /* GL_MODELVIEW10_ARB */ + 968, /* GL_MODELVIEW11_ARB */ + 969, /* GL_MODELVIEW12_ARB */ + 970, /* GL_MODELVIEW13_ARB */ + 971, /* GL_MODELVIEW14_ARB */ + 972, /* GL_MODELVIEW15_ARB */ + 973, /* GL_MODELVIEW16_ARB */ + 974, /* GL_MODELVIEW17_ARB */ + 975, /* GL_MODELVIEW18_ARB */ + 976, /* GL_MODELVIEW19_ARB */ + 978, /* GL_MODELVIEW20_ARB */ + 979, /* GL_MODELVIEW21_ARB */ + 980, /* GL_MODELVIEW22_ARB */ + 981, /* GL_MODELVIEW23_ARB */ + 982, /* GL_MODELVIEW24_ARB */ + 983, /* GL_MODELVIEW25_ARB */ + 984, /* GL_MODELVIEW26_ARB */ + 985, /* GL_MODELVIEW27_ARB */ + 986, /* GL_MODELVIEW28_ARB */ + 987, /* GL_MODELVIEW29_ARB */ + 989, /* GL_MODELVIEW30_ARB */ + 990, /* GL_MODELVIEW31_ARB */ 391, /* GL_DOT3_RGB_EXT */ 389, /* GL_DOT3_RGBA_EXT */ - 960, /* GL_MIRROR_CLAMP_EXT */ - 963, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ - 1001, /* GL_MODULATE_ADD_ATI */ - 1002, /* GL_MODULATE_SIGNED_ADD_ATI */ - 1003, /* GL_MODULATE_SUBTRACT_ATI */ - 1880, /* GL_YCBCR_MESA */ - 1093, /* GL_PACK_INVERT_MESA */ + 961, /* GL_MIRROR_CLAMP_EXT */ + 964, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */ + 1002, /* GL_MODULATE_ADD_ATI */ + 1003, /* GL_MODULATE_SIGNED_ADD_ATI */ + 1004, /* GL_MODULATE_SUBTRACT_ATI */ + 1881, /* GL_YCBCR_MESA */ + 1094, /* GL_PACK_INVERT_MESA */ 339, /* GL_DEBUG_OBJECT_MESA */ 340, /* GL_DEBUG_PRINT_MESA */ 338, /* GL_DEBUG_ASSERT_MESA */ @@ -4810,24 +4813,24 @@ static const unsigned reduced_enums[1350] = 450, /* GL_DU8DV8_ATI */ 114, /* GL_BUMP_ENVMAP_ATI */ 118, /* GL_BUMP_TARGET_ATI */ - 1507, /* GL_STENCIL_BACK_FUNC */ - 1505, /* GL_STENCIL_BACK_FAIL */ - 1509, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ - 1511, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ + 1508, /* GL_STENCIL_BACK_FUNC */ + 1506, /* GL_STENCIL_BACK_FAIL */ + 1510, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */ + 1512, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */ 536, /* GL_FRAGMENT_PROGRAM_ARB */ - 1231, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ - 1259, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ - 1258, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ - 1243, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - 1249, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - 1248, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - 892, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ - 915, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ - 914, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ - 905, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ - 911, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ - 910, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ - 875, /* GL_MAX_DRAW_BUFFERS */ + 1232, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */ + 1260, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */ + 1259, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */ + 1244, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ + 1250, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ + 1249, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ + 893, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */ + 916, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */ + 915, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */ + 906, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */ + 912, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */ + 911, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */ + 876, /* GL_MAX_DRAW_BUFFERS */ 395, /* GL_DRAW_BUFFER0 */ 398, /* GL_DRAW_BUFFER1 */ 419, /* GL_DRAW_BUFFER2 */ @@ -4845,161 +4848,161 @@ static const unsigned reduced_enums[1350] = 411, /* GL_DRAW_BUFFER14 */ 414, /* GL_DRAW_BUFFER15 */ 82, /* GL_BLEND_EQUATION_ALPHA */ - 854, /* GL_MATRIX_PALETTE_ARB */ - 886, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ - 889, /* GL_MAX_PALETTE_MATRICES_ARB */ + 855, /* GL_MATRIX_PALETTE_ARB */ + 887, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */ + 890, /* GL_MAX_PALETTE_MATRICES_ARB */ 321, /* GL_CURRENT_PALETTE_MATRIX_ARB */ - 848, /* GL_MATRIX_INDEX_ARRAY_ARB */ + 849, /* GL_MATRIX_INDEX_ARRAY_ARB */ 316, /* GL_CURRENT_MATRIX_INDEX_ARB */ - 850, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ - 852, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ - 851, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ - 849, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ - 1699, /* GL_TEXTURE_DEPTH_SIZE */ + 851, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */ + 853, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */ + 852, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */ + 850, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */ + 1700, /* GL_TEXTURE_DEPTH_SIZE */ 379, /* GL_DEPTH_TEXTURE_MODE */ - 1664, /* GL_TEXTURE_COMPARE_MODE */ - 1662, /* GL_TEXTURE_COMPARE_FUNC */ + 1665, /* GL_TEXTURE_COMPARE_MODE */ + 1663, /* GL_TEXTURE_COMPARE_FUNC */ 242, /* GL_COMPARE_R_TO_TEXTURE */ - 1165, /* GL_POINT_SPRITE */ + 1166, /* GL_POINT_SPRITE */ 296, /* GL_COORD_REPLACE */ - 1169, /* GL_POINT_SPRITE_R_MODE_NV */ - 1292, /* GL_QUERY_COUNTER_BITS */ + 1170, /* GL_POINT_SPRITE_R_MODE_NV */ + 1293, /* GL_QUERY_COUNTER_BITS */ 323, /* GL_CURRENT_QUERY */ - 1295, /* GL_QUERY_RESULT */ - 1297, /* GL_QUERY_RESULT_AVAILABLE */ - 940, /* GL_MAX_VERTEX_ATTRIBS */ - 1841, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ + 1296, /* GL_QUERY_RESULT */ + 1298, /* GL_QUERY_RESULT_AVAILABLE */ + 941, /* GL_MAX_VERTEX_ATTRIBS */ + 1842, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */ 377, /* GL_DEPTH_STENCIL_TO_RGBA_NV */ 376, /* GL_DEPTH_STENCIL_TO_BGRA_NV */ - 926, /* GL_MAX_TEXTURE_COORDS */ - 928, /* GL_MAX_TEXTURE_IMAGE_UNITS */ - 1236, /* GL_PROGRAM_ERROR_STRING_ARB */ - 1238, /* GL_PROGRAM_FORMAT_ASCII_ARB */ - 1237, /* GL_PROGRAM_FORMAT_ARB */ - 1749, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ + 927, /* GL_MAX_TEXTURE_COORDS */ + 929, /* GL_MAX_TEXTURE_IMAGE_UNITS */ + 1237, /* GL_PROGRAM_ERROR_STRING_ARB */ + 1239, /* GL_PROGRAM_FORMAT_ASCII_ARB */ + 1238, /* GL_PROGRAM_FORMAT_ARB */ + 1750, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */ 354, /* GL_DEPTH_BOUNDS_TEST_EXT */ 353, /* GL_DEPTH_BOUNDS_EXT */ 53, /* GL_ARRAY_BUFFER */ 464, /* GL_ELEMENT_ARRAY_BUFFER */ 54, /* GL_ARRAY_BUFFER_BINDING */ 465, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */ - 1815, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ - 1027, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ + 1816, /* GL_VERTEX_ARRAY_BUFFER_BINDING */ + 1028, /* GL_NORMAL_ARRAY_BUFFER_BINDING */ 149, /* GL_COLOR_ARRAY_BUFFER_BINDING */ - 632, /* GL_INDEX_ARRAY_BUFFER_BINDING */ - 1677, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ + 633, /* GL_INDEX_ARRAY_BUFFER_BINDING */ + 1678, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */ 460, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */ - 1420, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ + 1421, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */ 514, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */ - 1868, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ - 1837, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ - 1239, /* GL_PROGRAM_INSTRUCTIONS_ARB */ - 898, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ - 1245, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - 907, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ - 1257, /* GL_PROGRAM_TEMPORARIES_ARB */ - 913, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ - 1247, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ - 909, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ - 1251, /* GL_PROGRAM_PARAMETERS_ARB */ - 912, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ - 1246, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ - 908, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ - 1232, /* GL_PROGRAM_ATTRIBS_ARB */ - 893, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ - 1244, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ - 906, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ - 1230, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ - 891, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ - 1242, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - 904, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ - 899, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ - 895, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ - 1260, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ - 1761, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ - 1308, /* GL_READ_ONLY */ - 1876, /* GL_WRITE_ONLY */ - 1310, /* GL_READ_WRITE */ + 1869, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */ + 1838, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */ + 1240, /* GL_PROGRAM_INSTRUCTIONS_ARB */ + 899, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */ + 1246, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ + 908, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */ + 1258, /* GL_PROGRAM_TEMPORARIES_ARB */ + 914, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */ + 1248, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */ + 910, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */ + 1252, /* GL_PROGRAM_PARAMETERS_ARB */ + 913, /* GL_MAX_PROGRAM_PARAMETERS_ARB */ + 1247, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */ + 909, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */ + 1233, /* GL_PROGRAM_ATTRIBS_ARB */ + 894, /* GL_MAX_PROGRAM_ATTRIBS_ARB */ + 1245, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */ + 907, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */ + 1231, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */ + 892, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */ + 1243, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ + 905, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */ + 900, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */ + 896, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */ + 1261, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */ + 1762, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */ + 1309, /* GL_READ_ONLY */ + 1877, /* GL_WRITE_ONLY */ + 1311, /* GL_READ_WRITE */ 102, /* GL_BUFFER_ACCESS */ 105, /* GL_BUFFER_MAPPED */ 107, /* GL_BUFFER_MAP_POINTER */ - 1755, /* GL_TIME_ELAPSED_EXT */ - 808, /* GL_MATRIX0_ARB */ - 820, /* GL_MATRIX1_ARB */ - 832, /* GL_MATRIX2_ARB */ - 836, /* GL_MATRIX3_ARB */ - 838, /* GL_MATRIX4_ARB */ - 840, /* GL_MATRIX5_ARB */ - 842, /* GL_MATRIX6_ARB */ - 844, /* GL_MATRIX7_ARB */ - 846, /* GL_MATRIX8_ARB */ - 847, /* GL_MATRIX9_ARB */ - 810, /* GL_MATRIX10_ARB */ - 811, /* GL_MATRIX11_ARB */ - 812, /* GL_MATRIX12_ARB */ - 813, /* GL_MATRIX13_ARB */ - 814, /* GL_MATRIX14_ARB */ - 815, /* GL_MATRIX15_ARB */ - 816, /* GL_MATRIX16_ARB */ - 817, /* GL_MATRIX17_ARB */ - 818, /* GL_MATRIX18_ARB */ - 819, /* GL_MATRIX19_ARB */ - 822, /* GL_MATRIX20_ARB */ - 823, /* GL_MATRIX21_ARB */ - 824, /* GL_MATRIX22_ARB */ - 825, /* GL_MATRIX23_ARB */ - 826, /* GL_MATRIX24_ARB */ - 827, /* GL_MATRIX25_ARB */ - 828, /* GL_MATRIX26_ARB */ - 829, /* GL_MATRIX27_ARB */ - 830, /* GL_MATRIX28_ARB */ - 831, /* GL_MATRIX29_ARB */ - 834, /* GL_MATRIX30_ARB */ - 835, /* GL_MATRIX31_ARB */ - 1544, /* GL_STREAM_DRAW */ - 1546, /* GL_STREAM_READ */ - 1542, /* GL_STREAM_COPY */ - 1498, /* GL_STATIC_DRAW */ - 1500, /* GL_STATIC_READ */ - 1496, /* GL_STATIC_COPY */ + 1756, /* GL_TIME_ELAPSED_EXT */ + 809, /* GL_MATRIX0_ARB */ + 821, /* GL_MATRIX1_ARB */ + 833, /* GL_MATRIX2_ARB */ + 837, /* GL_MATRIX3_ARB */ + 839, /* GL_MATRIX4_ARB */ + 841, /* GL_MATRIX5_ARB */ + 843, /* GL_MATRIX6_ARB */ + 845, /* GL_MATRIX7_ARB */ + 847, /* GL_MATRIX8_ARB */ + 848, /* GL_MATRIX9_ARB */ + 811, /* GL_MATRIX10_ARB */ + 812, /* GL_MATRIX11_ARB */ + 813, /* GL_MATRIX12_ARB */ + 814, /* GL_MATRIX13_ARB */ + 815, /* GL_MATRIX14_ARB */ + 816, /* GL_MATRIX15_ARB */ + 817, /* GL_MATRIX16_ARB */ + 818, /* GL_MATRIX17_ARB */ + 819, /* GL_MATRIX18_ARB */ + 820, /* GL_MATRIX19_ARB */ + 823, /* GL_MATRIX20_ARB */ + 824, /* GL_MATRIX21_ARB */ + 825, /* GL_MATRIX22_ARB */ + 826, /* GL_MATRIX23_ARB */ + 827, /* GL_MATRIX24_ARB */ + 828, /* GL_MATRIX25_ARB */ + 829, /* GL_MATRIX26_ARB */ + 830, /* GL_MATRIX27_ARB */ + 831, /* GL_MATRIX28_ARB */ + 832, /* GL_MATRIX29_ARB */ + 835, /* GL_MATRIX30_ARB */ + 836, /* GL_MATRIX31_ARB */ + 1545, /* GL_STREAM_DRAW */ + 1547, /* GL_STREAM_READ */ + 1543, /* GL_STREAM_COPY */ + 1499, /* GL_STATIC_DRAW */ + 1501, /* GL_STATIC_READ */ + 1497, /* GL_STATIC_COPY */ 454, /* GL_DYNAMIC_DRAW */ 456, /* GL_DYNAMIC_READ */ 452, /* GL_DYNAMIC_COPY */ - 1133, /* GL_PIXEL_PACK_BUFFER */ - 1137, /* GL_PIXEL_UNPACK_BUFFER */ - 1134, /* GL_PIXEL_PACK_BUFFER_BINDING */ - 1138, /* GL_PIXEL_UNPACK_BUFFER_BINDING */ + 1134, /* GL_PIXEL_PACK_BUFFER */ + 1138, /* GL_PIXEL_UNPACK_BUFFER */ + 1135, /* GL_PIXEL_PACK_BUFFER_BINDING */ + 1139, /* GL_PIXEL_UNPACK_BUFFER_BINDING */ 347, /* GL_DEPTH24_STENCIL8 */ - 1745, /* GL_TEXTURE_STENCIL_SIZE */ - 1697, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */ - 894, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ - 897, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ - 901, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ - 900, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ - 857, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ - 1535, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ + 1746, /* GL_TEXTURE_STENCIL_SIZE */ + 1698, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */ + 895, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */ + 898, /* GL_MAX_PROGRAM_IF_DEPTH_NV */ + 902, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */ + 901, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */ + 858, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */ + 1536, /* GL_STENCIL_TEST_TWO_SIDE_EXT */ 17, /* GL_ACTIVE_STENCIL_FACE_EXT */ - 961, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ - 1401, /* GL_SAMPLES_PASSED */ + 962, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */ + 1402, /* GL_SAMPLES_PASSED */ 109, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */ 104, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */ 537, /* GL_FRAGMENT_SHADER */ - 1861, /* GL_VERTEX_SHADER */ - 1250, /* GL_PROGRAM_OBJECT_ARB */ - 1433, /* GL_SHADER_OBJECT_ARB */ - 882, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ - 944, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ - 938, /* GL_MAX_VARYING_FLOATS */ - 942, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ - 867, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ - 1053, /* GL_OBJECT_TYPE_ARB */ - 1435, /* GL_SHADER_TYPE */ + 1862, /* GL_VERTEX_SHADER */ + 1251, /* GL_PROGRAM_OBJECT_ARB */ + 1434, /* GL_SHADER_OBJECT_ARB */ + 883, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */ + 945, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */ + 939, /* GL_MAX_VARYING_FLOATS */ + 943, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */ + 868, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */ + 1054, /* GL_OBJECT_TYPE_ARB */ + 1436, /* GL_SHADER_TYPE */ 502, /* GL_FLOAT_VEC2 */ 504, /* GL_FLOAT_VEC3 */ 506, /* GL_FLOAT_VEC4 */ - 659, /* GL_INT_VEC2 */ - 661, /* GL_INT_VEC3 */ - 663, /* GL_INT_VEC4 */ + 660, /* GL_INT_VEC2 */ + 662, /* GL_INT_VEC3 */ + 664, /* GL_INT_VEC4 */ 94, /* GL_BOOL */ 96, /* GL_BOOL_VEC2 */ 98, /* GL_BOOL_VEC3 */ @@ -5007,12 +5010,12 @@ static const unsigned reduced_enums[1350] = 490, /* GL_FLOAT_MAT2 */ 494, /* GL_FLOAT_MAT3 */ 498, /* GL_FLOAT_MAT4 */ - 1392, /* GL_SAMPLER_1D */ - 1394, /* GL_SAMPLER_2D */ - 1396, /* GL_SAMPLER_3D */ - 1397, /* GL_SAMPLER_CUBE */ - 1393, /* GL_SAMPLER_1D_SHADOW */ - 1395, /* GL_SAMPLER_2D_SHADOW */ + 1393, /* GL_SAMPLER_1D */ + 1395, /* GL_SAMPLER_2D */ + 1397, /* GL_SAMPLER_3D */ + 1398, /* GL_SAMPLER_CUBE */ + 1394, /* GL_SAMPLER_1D_SHADOW */ + 1396, /* GL_SAMPLER_2D_SHADOW */ 492, /* GL_FLOAT_MAT2x3 */ 493, /* GL_FLOAT_MAT2x4 */ 496, /* GL_FLOAT_MAT3x2 */ @@ -5021,61 +5024,61 @@ static const unsigned reduced_enums[1350] = 501, /* GL_FLOAT_MAT4x3 */ 345, /* GL_DELETE_STATUS */ 246, /* GL_COMPILE_STATUS */ - 715, /* GL_LINK_STATUS */ - 1809, /* GL_VALIDATE_STATUS */ - 644, /* GL_INFO_LOG_LENGTH */ + 716, /* GL_LINK_STATUS */ + 1810, /* GL_VALIDATE_STATUS */ + 645, /* GL_INFO_LOG_LENGTH */ 56, /* GL_ATTACHED_SHADERS */ 20, /* GL_ACTIVE_UNIFORMS */ 21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */ - 1434, /* GL_SHADER_SOURCE_LENGTH */ + 1435, /* GL_SHADER_SOURCE_LENGTH */ 15, /* GL_ACTIVE_ATTRIBUTES */ 16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */ 539, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */ - 1437, /* GL_SHADING_LANGUAGE_VERSION */ + 1438, /* GL_SHADING_LANGUAGE_VERSION */ 322, /* GL_CURRENT_PROGRAM */ - 1102, /* GL_PALETTE4_RGB8_OES */ - 1104, /* GL_PALETTE4_RGBA8_OES */ - 1100, /* GL_PALETTE4_R5_G6_B5_OES */ - 1103, /* GL_PALETTE4_RGBA4_OES */ - 1101, /* GL_PALETTE4_RGB5_A1_OES */ - 1107, /* GL_PALETTE8_RGB8_OES */ - 1109, /* GL_PALETTE8_RGBA8_OES */ - 1105, /* GL_PALETTE8_R5_G6_B5_OES */ - 1108, /* GL_PALETTE8_RGBA4_OES */ - 1106, /* GL_PALETTE8_RGB5_A1_OES */ - 626, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ - 625, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ - 1794, /* GL_UNSIGNED_NORMALIZED */ - 1632, /* GL_TEXTURE_1D_ARRAY_EXT */ - 1272, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ - 1634, /* GL_TEXTURE_2D_ARRAY_EXT */ - 1275, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ - 1640, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ - 1642, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ - 1490, /* GL_SRGB */ - 1491, /* GL_SRGB8 */ - 1493, /* GL_SRGB_ALPHA */ - 1492, /* GL_SRGB8_ALPHA8 */ - 1450, /* GL_SLUMINANCE_ALPHA */ - 1449, /* GL_SLUMINANCE8_ALPHA8 */ - 1447, /* GL_SLUMINANCE */ - 1448, /* GL_SLUMINANCE8 */ + 1103, /* GL_PALETTE4_RGB8_OES */ + 1105, /* GL_PALETTE4_RGBA8_OES */ + 1101, /* GL_PALETTE4_R5_G6_B5_OES */ + 1104, /* GL_PALETTE4_RGBA4_OES */ + 1102, /* GL_PALETTE4_RGB5_A1_OES */ + 1108, /* GL_PALETTE8_RGB8_OES */ + 1110, /* GL_PALETTE8_RGBA8_OES */ + 1106, /* GL_PALETTE8_R5_G6_B5_OES */ + 1109, /* GL_PALETTE8_RGBA4_OES */ + 1107, /* GL_PALETTE8_RGB5_A1_OES */ + 627, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */ + 626, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */ + 1795, /* GL_UNSIGNED_NORMALIZED */ + 1633, /* GL_TEXTURE_1D_ARRAY_EXT */ + 1273, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */ + 1635, /* GL_TEXTURE_2D_ARRAY_EXT */ + 1276, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */ + 1641, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */ + 1643, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */ + 1491, /* GL_SRGB */ + 1492, /* GL_SRGB8 */ + 1494, /* GL_SRGB_ALPHA */ + 1493, /* GL_SRGB8_ALPHA8 */ + 1451, /* GL_SLUMINANCE_ALPHA */ + 1450, /* GL_SLUMINANCE8_ALPHA8 */ + 1448, /* GL_SLUMINANCE */ + 1449, /* GL_SLUMINANCE8 */ 267, /* GL_COMPRESSED_SRGB */ 268, /* GL_COMPRESSED_SRGB_ALPHA */ 265, /* GL_COMPRESSED_SLUMINANCE */ 266, /* GL_COMPRESSED_SLUMINANCE_ALPHA */ - 1167, /* GL_POINT_SPRITE_COORD_ORIGIN */ - 723, /* GL_LOWER_LEFT */ - 1806, /* GL_UPPER_LEFT */ - 1513, /* GL_STENCIL_BACK_REF */ - 1514, /* GL_STENCIL_BACK_VALUE_MASK */ - 1515, /* GL_STENCIL_BACK_WRITEMASK */ + 1168, /* GL_POINT_SPRITE_COORD_ORIGIN */ + 724, /* GL_LOWER_LEFT */ + 1807, /* GL_UPPER_LEFT */ + 1514, /* GL_STENCIL_BACK_REF */ + 1515, /* GL_STENCIL_BACK_VALUE_MASK */ + 1516, /* GL_STENCIL_BACK_WRITEMASK */ 444, /* GL_DRAW_FRAMEBUFFER_BINDING */ - 1324, /* GL_RENDERBUFFER_BINDING */ - 1304, /* GL_READ_FRAMEBUFFER */ + 1325, /* GL_RENDERBUFFER_BINDING */ + 1305, /* GL_READ_FRAMEBUFFER */ 443, /* GL_DRAW_FRAMEBUFFER */ - 1305, /* GL_READ_FRAMEBUFFER_BINDING */ - 1335, /* GL_RENDERBUFFER_SAMPLES */ + 1306, /* GL_READ_FRAMEBUFFER_BINDING */ + 1336, /* GL_RENDERBUFFER_SAMPLES */ 549, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ 547, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ 558, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ @@ -5091,7 +5094,7 @@ static const unsigned reduced_enums[1350] = 577, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ 581, /* GL_FRAMEBUFFER_UNSUPPORTED */ 579, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */ - 863, /* GL_MAX_COLOR_ATTACHMENTS */ + 864, /* GL_MAX_COLOR_ATTACHMENTS */ 155, /* GL_COLOR_ATTACHMENT0 */ 157, /* GL_COLOR_ATTACHMENT1 */ 171, /* GL_COLOR_ATTACHMENT2 */ @@ -5109,58 +5112,58 @@ static const unsigned reduced_enums[1350] = 166, /* GL_COLOR_ATTACHMENT14 */ 168, /* GL_COLOR_ATTACHMENT15 */ 349, /* GL_DEPTH_ATTACHMENT */ - 1503, /* GL_STENCIL_ATTACHMENT */ + 1504, /* GL_STENCIL_ATTACHMENT */ 540, /* GL_FRAMEBUFFER */ - 1322, /* GL_RENDERBUFFER */ - 1338, /* GL_RENDERBUFFER_WIDTH */ - 1330, /* GL_RENDERBUFFER_HEIGHT */ - 1332, /* GL_RENDERBUFFER_INTERNAL_FORMAT */ - 1530, /* GL_STENCIL_INDEX_EXT */ - 1522, /* GL_STENCIL_INDEX1 */ - 1526, /* GL_STENCIL_INDEX4 */ - 1528, /* GL_STENCIL_INDEX8 */ - 1523, /* GL_STENCIL_INDEX16 */ - 1334, /* GL_RENDERBUFFER_RED_SIZE */ - 1329, /* GL_RENDERBUFFER_GREEN_SIZE */ - 1326, /* GL_RENDERBUFFER_BLUE_SIZE */ - 1323, /* GL_RENDERBUFFER_ALPHA_SIZE */ - 1327, /* GL_RENDERBUFFER_DEPTH_SIZE */ - 1337, /* GL_RENDERBUFFER_STENCIL_SIZE */ + 1323, /* GL_RENDERBUFFER */ + 1339, /* GL_RENDERBUFFER_WIDTH */ + 1331, /* GL_RENDERBUFFER_HEIGHT */ + 1333, /* GL_RENDERBUFFER_INTERNAL_FORMAT */ + 1531, /* GL_STENCIL_INDEX_EXT */ + 1523, /* GL_STENCIL_INDEX1 */ + 1527, /* GL_STENCIL_INDEX4 */ + 1529, /* GL_STENCIL_INDEX8 */ + 1524, /* GL_STENCIL_INDEX16 */ + 1335, /* GL_RENDERBUFFER_RED_SIZE */ + 1330, /* GL_RENDERBUFFER_GREEN_SIZE */ + 1327, /* GL_RENDERBUFFER_BLUE_SIZE */ + 1324, /* GL_RENDERBUFFER_ALPHA_SIZE */ + 1328, /* GL_RENDERBUFFER_DEPTH_SIZE */ + 1338, /* GL_RENDERBUFFER_STENCIL_SIZE */ 575, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ - 921, /* GL_MAX_SAMPLES */ - 1299, /* GL_QUERY_WAIT_NV */ - 1294, /* GL_QUERY_NO_WAIT_NV */ - 1291, /* GL_QUERY_BY_REGION_WAIT_NV */ - 1290, /* GL_QUERY_BY_REGION_NO_WAIT_NV */ - 1286, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ + 922, /* GL_MAX_SAMPLES */ + 1300, /* GL_QUERY_WAIT_NV */ + 1295, /* GL_QUERY_NO_WAIT_NV */ + 1292, /* GL_QUERY_BY_REGION_WAIT_NV */ + 1291, /* GL_QUERY_BY_REGION_NO_WAIT_NV */ + 1287, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ 486, /* GL_FIRST_VERTEX_CONVENTION */ - 674, /* GL_LAST_VERTEX_CONVENTION */ - 1264, /* GL_PROVOKING_VERTEX */ + 675, /* GL_LAST_VERTEX_CONVENTION */ + 1265, /* GL_PROVOKING_VERTEX */ 302, /* GL_COPY_READ_BUFFER */ 303, /* GL_COPY_WRITE_BUFFER */ - 1385, /* GL_RGBA_SNORM */ - 1381, /* GL_RGBA8_SNORM */ - 1443, /* GL_SIGNED_NORMALIZED */ - 923, /* GL_MAX_SERVER_WAIT_TIMEOUT */ - 1052, /* GL_OBJECT_TYPE */ - 1551, /* GL_SYNC_CONDITION */ - 1556, /* GL_SYNC_STATUS */ - 1553, /* GL_SYNC_FLAGS */ - 1552, /* GL_SYNC_FENCE */ - 1555, /* GL_SYNC_GPU_COMMANDS_COMPLETE */ - 1782, /* GL_UNSIGNALED */ - 1442, /* GL_SIGNALED */ + 1386, /* GL_RGBA_SNORM */ + 1382, /* GL_RGBA8_SNORM */ + 1444, /* GL_SIGNED_NORMALIZED */ + 924, /* GL_MAX_SERVER_WAIT_TIMEOUT */ + 1053, /* GL_OBJECT_TYPE */ + 1552, /* GL_SYNC_CONDITION */ + 1557, /* GL_SYNC_STATUS */ + 1554, /* GL_SYNC_FLAGS */ + 1553, /* GL_SYNC_FENCE */ + 1556, /* GL_SYNC_GPU_COMMANDS_COMPLETE */ + 1783, /* GL_UNSIGNALED */ + 1443, /* GL_SIGNALED */ 46, /* GL_ALREADY_SIGNALED */ - 1754, /* GL_TIMEOUT_EXPIRED */ + 1755, /* GL_TIMEOUT_EXPIRED */ 270, /* GL_CONDITION_SATISFIED */ - 1866, /* GL_WAIT_FAILED */ + 1867, /* GL_WAIT_FAILED */ 471, /* GL_EVAL_BIT */ - 1302, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ - 717, /* GL_LIST_BIT */ - 1648, /* GL_TEXTURE_BIT */ - 1416, /* GL_SCISSOR_BIT */ + 1303, /* GL_RASTER_POSITION_UNCLIPPED_IBM */ + 718, /* GL_LIST_BIT */ + 1649, /* GL_TEXTURE_BIT */ + 1417, /* GL_SCISSOR_BIT */ 29, /* GL_ALL_ATTRIB_BITS */ - 1008, /* GL_MULTISAMPLE_BIT */ + 1009, /* GL_MULTISAMPLE_BIT */ 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ }; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 5fc0b1cfde..e1320224a8 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -50,11 +50,14 @@ static const struct { { OFF, "GL_ARB_depth_clamp", F(ARB_depth_clamp) }, { ON, "GL_ARB_draw_buffers", F(ARB_draw_buffers) }, { OFF, "GL_ARB_draw_elements_base_vertex", F(ARB_draw_elements_base_vertex) }, + /* TODO: uncomment the following line once GLSL layout(...) support is implemented */ + /* { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) }, */ { OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) }, { OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) }, { OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) }, { OFF, "GL_ARB_framebuffer_object", F(ARB_framebuffer_object) }, { OFF, "GL_ARB_half_float_pixel", F(ARB_half_float_pixel) }, + { OFF, "GL_ARB_half_float_vertex", F(ARB_half_float_vertex) }, { OFF, "GL_ARB_imaging", F(ARB_imaging) }, { OFF, "GL_ARB_map_buffer_range", F(ARB_map_buffer_range) }, { ON, "GL_ARB_multisample", F(ARB_multisample) }, @@ -189,6 +192,9 @@ static const struct { { ON, "GL_SGIS_texture_lod", F(SGIS_texture_lod) }, { ON, "GL_SUN_multi_draw_arrays", F(EXT_multi_draw_arrays) }, { OFF, "GL_S3_s3tc", F(S3_s3tc) }, +#if FEATURE_OES_draw_texture + { OFF, "GL_OES_draw_texture", F(OES_draw_texture) }, +#endif /* FEATURE_OES_draw_texture */ }; @@ -216,6 +222,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.ARB_framebuffer_object = GL_TRUE; #endif ctx->Extensions.ARB_half_float_pixel = GL_TRUE; + ctx->Extensions.ARB_half_float_vertex = GL_TRUE; ctx->Extensions.ARB_imaging = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; ctx->Extensions.ARB_multitexture = GL_TRUE; diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 7b3599f932..0e6f69f573 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -40,13 +40,10 @@ #include "framebuffer.h" #include "hash.h" #include "macros.h" -#include "mipmap.h" #include "renderbuffer.h" #include "state.h" #include "teximage.h" #include "texobj.h" -#include "texstore.h" -#include "texstate.h" /** Set this to 1 to help debug FBO incompleteness problems */ @@ -861,6 +858,9 @@ _mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers) * * \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT * GL_DEPTH_STENCIL_EXT or zero if error. + * + * XXX in the future when we support red-only and red-green formats + * we'll also return GL_RED and GL_RG. */ GLenum _mesa_base_fbo_format(GLcontext *ctx, GLenum internalFormat) @@ -954,7 +954,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* NumSamples == 0 indicates non-multisampling */ samples = 0; } - else if (samples > ctx->Const.MaxSamples) { + else if (samples > (GLsizei) ctx->Const.MaxSamples) { /* note: driver may choose to use more samples than what's requested */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func); return; @@ -1353,15 +1353,26 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]); /* check if deleting currently bound framebuffer object */ - if (fb == ctx->DrawBuffer) { - /* bind default */ - ASSERT(fb->RefCount >= 2); - _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + if (ctx->Extensions.EXT_framebuffer_blit) { + /* separate draw/read binding points */ + if (fb == ctx->DrawBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + } + if (fb == ctx->ReadBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + } } - if (fb == ctx->ReadBuffer) { - /* bind default */ - ASSERT(fb->RefCount >= 2); - _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + else { + /* only one binding point for read/draw buffers */ + if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) { + /* bind default */ + ASSERT(fb->RefCount >= 2); + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } } /* remove from hash table immediately, to free the ID */ diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 5983f00e2d..d0c9c0028b 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -27,7 +27,6 @@ #include "imports.h" #include "formats.h" #include "config.h" -#include "texstore.h" /** diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index d958dbf7d4..96e5344383 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -88,7 +88,7 @@ _mesa_create_framebuffer(const GLvisual *visual) struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); assert(visual); if (fb) { - _mesa_initialize_framebuffer(fb, visual); + _mesa_initialize_window_framebuffer(fb, visual); } return fb; } @@ -109,15 +109,7 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) assert(name != 0); fb = CALLOC_STRUCT(gl_framebuffer); if (fb) { - fb->Name = name; - fb->RefCount = 1; - fb->_NumColorDrawBuffers = 1; - fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; - fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; - fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; - fb->_ColorReadBufferIndex = BUFFER_COLOR0; - fb->Delete = _mesa_destroy_framebuffer; - _glthread_INIT_MUTEX(fb->Mutex); + _mesa_initialize_user_framebuffer(fb, name); } return fb; } @@ -126,10 +118,11 @@ _mesa_new_framebuffer(GLcontext *ctx, GLuint name) /** * Initialize a gl_framebuffer object. Typically used to initialize * window system-created framebuffers, not user-created framebuffers. - * \sa _mesa_create_framebuffer + * \sa _mesa_initialize_user_framebuffer */ void -_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) +_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, + const GLvisual *visual) { assert(fb); assert(visual); @@ -167,6 +160,30 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) /** + * Initialize a user-created gl_framebuffer object. + * \sa _mesa_initialize_window_framebuffer + */ +void +_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name) +{ + assert(fb); + assert(name); + + _mesa_bzero(fb, sizeof(struct gl_framebuffer)); + + fb->Name = name; + fb->RefCount = 1; + fb->_NumColorDrawBuffers = 1; + fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorDrawBufferIndexes[0] = BUFFER_COLOR0; + fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorReadBufferIndex = BUFFER_COLOR0; + fb->Delete = _mesa_destroy_framebuffer; + _glthread_INIT_MUTEX(fb->Mutex); +} + + +/** * Deallocate buffer and everything attached to it. * Typically called via the gl_framebuffer->Delete() method. */ diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index ef21dd98e8..960513812c 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -34,7 +34,11 @@ extern struct gl_framebuffer * _mesa_new_framebuffer(GLcontext *ctx, GLuint name); extern void -_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual); +_mesa_initialize_window_framebuffer(struct gl_framebuffer *fb, + const GLvisual *visual); + +extern void +_mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name); extern void _mesa_destroy_framebuffer(struct gl_framebuffer *buffer); diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 22cf75f79d..2724774ca2 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -270,11 +270,16 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_CURRENT_RASTER_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[texUnit][3]); + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(raster tex coords, unit %u)", unit); + return; + } + params[0] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[unit][0]); + params[1] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[unit][1]); + params[2] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[unit][2]); + params[3] = FLOAT_TO_BOOLEAN(ctx->Current.RasterTexCoords[unit][3]); } break; case GL_CURRENT_RASTER_POSITION_VALID: @@ -282,12 +287,17 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_CURRENT_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(current tex coords, unit %u)", unit); + return; + } FLUSH_CURRENT(ctx, 0); - params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]); - params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]); - params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]); - params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]); + params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]); + params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]); + params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]); + params[3] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]); } break; case GL_DEPTH_BIAS: @@ -922,7 +932,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_TEXTURE_MATRIX: { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; + const GLfloat *matrix; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGet(texture matrix %u)", + unit); + return; + } + matrix = ctx->TextureMatrixStack[unit].Top->m; params[0] = FLOAT_TO_BOOLEAN(matrix[0]); params[1] = FLOAT_TO_BOOLEAN(matrix[1]); params[2] = FLOAT_TO_BOOLEAN(matrix[2]); @@ -942,7 +959,15 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) } break; case GL_TEXTURE_STACK_DEPTH: - params[0] = INT_TO_BOOLEAN(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1); + { + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(texture stack depth, unit %u)", unit); + return; + } + params[0] = INT_TO_BOOLEAN(ctx->TextureMatrixStack[unit].Depth + 1); + } break; case GL_UNPACK_ALIGNMENT: params[0] = INT_TO_BOOLEAN(ctx->Unpack.Alignment); @@ -2114,11 +2139,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_CURRENT_RASTER_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = ctx->Current.RasterTexCoords[texUnit][0]; - params[1] = ctx->Current.RasterTexCoords[texUnit][1]; - params[2] = ctx->Current.RasterTexCoords[texUnit][2]; - params[3] = ctx->Current.RasterTexCoords[texUnit][3]; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(raster tex coords, unit %u)", unit); + return; + } + params[0] = ctx->Current.RasterTexCoords[unit][0]; + params[1] = ctx->Current.RasterTexCoords[unit][1]; + params[2] = ctx->Current.RasterTexCoords[unit][2]; + params[3] = ctx->Current.RasterTexCoords[unit][3]; } break; case GL_CURRENT_RASTER_POSITION_VALID: @@ -2126,12 +2156,17 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_CURRENT_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(current tex coords, unit %u)", unit); + return; + } FLUSH_CURRENT(ctx, 0); - params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]; - params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]; - params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]; - params[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]; + params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]; + params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]; + params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]; + params[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]; } break; case GL_DEPTH_BIAS: @@ -2766,7 +2801,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_TEXTURE_MATRIX: { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; + const GLfloat *matrix; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGet(texture matrix %u)", + unit); + return; + } + matrix = ctx->TextureMatrixStack[unit].Top->m; params[0] = matrix[0]; params[1] = matrix[1]; params[2] = matrix[2]; @@ -2786,7 +2828,15 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) } break; case GL_TEXTURE_STACK_DEPTH: - params[0] = (GLfloat)(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1); + { + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(texture stack depth, unit %u)", unit); + return; + } + params[0] = (GLfloat)(ctx->TextureMatrixStack[unit].Depth + 1); + } break; case GL_UNPACK_ALIGNMENT: params[0] = (GLfloat)(ctx->Unpack.Alignment); @@ -3958,11 +4008,16 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_CURRENT_RASTER_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = IROUND(ctx->Current.RasterTexCoords[texUnit][0]); - params[1] = IROUND(ctx->Current.RasterTexCoords[texUnit][1]); - params[2] = IROUND(ctx->Current.RasterTexCoords[texUnit][2]); - params[3] = IROUND(ctx->Current.RasterTexCoords[texUnit][3]); + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(raster tex coords, unit %u)", unit); + return; + } + params[0] = IROUND(ctx->Current.RasterTexCoords[unit][0]); + params[1] = IROUND(ctx->Current.RasterTexCoords[unit][1]); + params[2] = IROUND(ctx->Current.RasterTexCoords[unit][2]); + params[3] = IROUND(ctx->Current.RasterTexCoords[unit][3]); } break; case GL_CURRENT_RASTER_POSITION_VALID: @@ -3970,12 +4025,17 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_CURRENT_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(current tex coords, unit %u)", unit); + return; + } FLUSH_CURRENT(ctx, 0); - params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]); - params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]); - params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]); - params[3] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]); + params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]); + params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]); + params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]); + params[3] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]); } break; case GL_DEPTH_BIAS: @@ -4610,7 +4670,14 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_TEXTURE_MATRIX: { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; + const GLfloat *matrix; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGet(texture matrix %u)", + unit); + return; + } + matrix = ctx->TextureMatrixStack[unit].Top->m; params[0] = IROUND(matrix[0]); params[1] = IROUND(matrix[1]); params[2] = IROUND(matrix[2]); @@ -4630,7 +4697,15 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) } break; case GL_TEXTURE_STACK_DEPTH: - params[0] = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1; + { + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(texture stack depth, unit %u)", unit); + return; + } + params[0] = ctx->TextureMatrixStack[unit].Depth + 1; + } break; case GL_UNPACK_ALIGNMENT: params[0] = ctx->Unpack.Alignment; @@ -5803,11 +5878,16 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) break; case GL_CURRENT_RASTER_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; - params[0] = IROUND64(ctx->Current.RasterTexCoords[texUnit][0]); - params[1] = IROUND64(ctx->Current.RasterTexCoords[texUnit][1]); - params[2] = IROUND64(ctx->Current.RasterTexCoords[texUnit][2]); - params[3] = IROUND64(ctx->Current.RasterTexCoords[texUnit][3]); + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(raster tex coords, unit %u)", unit); + return; + } + params[0] = IROUND64(ctx->Current.RasterTexCoords[unit][0]); + params[1] = IROUND64(ctx->Current.RasterTexCoords[unit][1]); + params[2] = IROUND64(ctx->Current.RasterTexCoords[unit][2]); + params[3] = IROUND64(ctx->Current.RasterTexCoords[unit][3]); } break; case GL_CURRENT_RASTER_POSITION_VALID: @@ -5815,12 +5895,17 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) break; case GL_CURRENT_TEXTURE_COORDS: { - const GLuint texUnit = ctx->Texture.CurrentUnit; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(current tex coords, unit %u)", unit); + return; + } FLUSH_CURRENT(ctx, 0); - params[0] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]); - params[1] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]); - params[2] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]); - params[3] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]); + params[0] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]); + params[1] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]); + params[2] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]); + params[3] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]); } break; case GL_DEPTH_BIAS: @@ -6455,7 +6540,14 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) break; case GL_TEXTURE_MATRIX: { - const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m; + const GLfloat *matrix; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGet(texture matrix %u)", + unit); + return; + } + matrix = ctx->TextureMatrixStack[unit].Top->m; params[0] = IROUND64(matrix[0]); params[1] = IROUND64(matrix[1]); params[2] = IROUND64(matrix[2]); @@ -6475,7 +6567,15 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) } break; case GL_TEXTURE_STACK_DEPTH: - params[0] = (GLint64)(ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1); + { + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(texture stack depth, unit %u)", unit); + return; + } + params[0] = (GLint64)(ctx->TextureMatrixStack[unit].Depth + 1); + } break; case GL_UNPACK_ALIGNMENT: params[0] = (GLint64)(ctx->Unpack.Alignment); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index b0beb59207..9ae3ce0096 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -166,20 +166,32 @@ StateVars = [ "ctx->Current.RasterSecondaryColor[2]", "ctx->Current.RasterSecondaryColor[3]"], "", None ), ( "GL_CURRENT_RASTER_TEXTURE_COORDS", GLfloat, - ["ctx->Current.RasterTexCoords[texUnit][0]", - "ctx->Current.RasterTexCoords[texUnit][1]", - "ctx->Current.RasterTexCoords[texUnit][2]", - "ctx->Current.RasterTexCoords[texUnit][3]"], - "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ), + ["ctx->Current.RasterTexCoords[unit][0]", + "ctx->Current.RasterTexCoords[unit][1]", + "ctx->Current.RasterTexCoords[unit][2]", + "ctx->Current.RasterTexCoords[unit][3]"], + """const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(raster tex coords, unit %u)", unit); + return; + }""", + None ), ( "GL_CURRENT_RASTER_POSITION_VALID", GLboolean, ["ctx->Current.RasterPosValid"], "", None ), ( "GL_CURRENT_TEXTURE_COORDS", GLfloat, - ["ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]", - "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]", - "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]", - "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"], - """const GLuint texUnit = ctx->Texture.CurrentUnit; - FLUSH_CURRENT(ctx, 0);""", None ), + ["ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][0]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][1]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2]", + "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3]"], + """const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(current tex coords, unit %u)", unit); + return; + } + FLUSH_CURRENT(ctx, 0);""", + None ), ( "GL_DEPTH_BIAS", GLfloat, ["ctx->Pixel.DepthBias"], "", None ), ( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"], "", None ), @@ -457,9 +469,24 @@ StateVars = [ "matrix[4]", "matrix[5]", "matrix[6]", "matrix[7]", "matrix[8]", "matrix[9]", "matrix[10]", "matrix[11]", "matrix[12]", "matrix[13]", "matrix[14]", "matrix[15]" ], - "const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;", None ), + """const GLfloat *matrix; + const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGet(texture matrix %u)", + unit); + return; + } + matrix = ctx->TextureMatrixStack[unit].Top->m;""", + None ), ( "GL_TEXTURE_STACK_DEPTH", GLint, - ["ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1"], "", None ), + ["ctx->TextureMatrixStack[unit].Depth + 1"], + """const GLuint unit = ctx->Texture.CurrentUnit; + if (unit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGet(texture stack depth, unit %u)", unit); + return; + }""", + None ), ( "GL_UNPACK_ALIGNMENT", GLint, ["ctx->Unpack.Alignment"], "", None ), ( "GL_UNPACK_LSB_FIRST", GLboolean, ["ctx->Unpack.LsbFirst"], "", None ), ( "GL_UNPACK_ROW_LENGTH", GLint, ["ctx->Unpack.RowLength"], "", None ), diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index e76a790d0a..51dd5f7795 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -27,7 +27,6 @@ #include "glheader.h" #include "context.h" #include "get.h" -#include "version.h" #include "enums.h" #include "extensions.h" @@ -191,6 +190,11 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params ) case GL_SELECTION_BUFFER_POINTER: *params = ctx->Select.Buffer; break; +#if FEATURE_point_size_array + case GL_POINT_SIZE_ARRAY_POINTER_OES: + *params = (GLvoid *) ctx->Array.ArrayObj->PointSize.Ptr; + break; +#endif default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); return; diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index 81d4ccf919..77544c88c6 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -57,6 +57,13 @@ #ifndef GL_FIXED #define GL_FIXED 0x140C +typedef int GLfixed; +typedef int GLclampx; +#endif + + +#ifndef GL_OES_EGL_image +typedef void *GLeglImageOES; #endif diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index fc278bb8af..81993e7063 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -37,7 +37,6 @@ #include "image.h" #include "imports.h" #include "macros.h" -#include "pixel.h" /** diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index b01fe5b0ab..3843f50036 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -405,6 +405,54 @@ _mesa_is_pow_two(int x) return !(x & (x - 1)); } +/** + * Round given integer to next higer power of two + * If X is zero result is undefined. + * + * Source for the fallback implementation is + * Sean Eron Anderson's webpage "Bit Twiddling Hacks" + * http://graphics.stanford.edu/~seander/bithacks.html + */ +static INLINE int32_t +_mesa_next_pow_two_32(uint32_t x) +{ +#ifdef __GNUC__ + x--; + return 1 << ((__builtin_clz(x) ^ 31) + 1); +#else + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return x; +#endif +} + +static INLINE int64_t +_mesa_next_pow_two_64(uint64_t x) +{ +#ifdef __GNUC__ + x--; + if (sizeof(x) == sizeof(long)) + return 1 << ((__builtin_clzl(x) ^ 63) + 1); + else + return 1 << ((__builtin_clzll(x) ^ 63) + 1); +#else + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x++; + return x; +#endif +} + /*** *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index 81d0d33abb..cc63a759ec 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -25,10 +25,8 @@ #include "glheader.h" #include "context.h" -#include "depth.h" #include "lines.h" #include "macros.h" -#include "texstate.h" #include "mtypes.h" diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index ebc3cbd59c..5c863f6f32 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -726,10 +726,10 @@ void _mesa_init_matrix( GLcontext * ctx ) _NEW_PROJECTION); init_matrix_stack(&ctx->ColorMatrixStack, MAX_COLOR_STACK_DEPTH, _NEW_COLOR_MATRIX); - for (i = 0; i < MAX_TEXTURE_UNITS; i++) + for (i = 0; i < Elements(ctx->TextureMatrixStack); i++) init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH, _NEW_TEXTURE_MATRIX); - for (i = 0; i < MAX_PROGRAM_MATRICES; i++) + for (i = 0; i < Elements(ctx->ProgramMatrixStack); i++) init_matrix_stack(&ctx->ProgramMatrixStack[i], MAX_PROGRAM_MATRIX_STACK_DEPTH, _NEW_TRACK_MATRIX); ctx->CurrentStack = &ctx->ModelviewMatrixStack; @@ -754,9 +754,9 @@ void _mesa_free_matrix_data( GLcontext *ctx ) free_matrix_stack(&ctx->ModelviewMatrixStack); free_matrix_stack(&ctx->ProjectionMatrixStack); free_matrix_stack(&ctx->ColorMatrixStack); - for (i = 0; i < MAX_TEXTURE_UNITS; i++) + for (i = 0; i < Elements(ctx->TextureMatrixStack); i++) free_matrix_stack(&ctx->TextureMatrixStack[i]); - for (i = 0; i < MAX_PROGRAM_MATRICES; i++) + for (i = 0; i < Elements(ctx->ProgramMatrixStack); i++) free_matrix_stack(&ctx->ProgramMatrixStack[i]); /* combined Modelview*Projection matrix */ _math_matrix_dtr( &ctx->_ModelProjectMatrix ); diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 7350c7a3d2..77cd1d4159 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -30,7 +30,6 @@ #include "imports.h" #include "formats.h" #include "mipmap.h" -#include "texcompress.h" #include "teximage.h" #include "texstore.h" #include "image.h" diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5227565f87..20035417b9 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -631,7 +631,7 @@ struct gl_current_attrib GLfloat RasterColor[4]; GLfloat RasterSecondaryColor[4]; GLfloat RasterIndex; - GLfloat RasterTexCoords[MAX_TEXTURE_UNITS][4]; + GLfloat RasterTexCoords[MAX_TEXTURE_COORD_UNITS][4]; GLboolean RasterPosValid; /*@}*/ }; @@ -963,7 +963,7 @@ struct gl_point_attrib GLfloat Threshold; /**< GL_EXT_point_parameters */ GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */ GLboolean PointSprite; /**< GL_NV/ARB_point_sprite */ - GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_ARB_point_sprite */ + GLboolean CoordReplace[MAX_TEXTURE_COORD_UNITS]; /**< GL_ARB_point_sprite*/ GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */ GLenum SpriteOrigin; /**< GL_ARB_point_sprite */ }; @@ -1361,7 +1361,7 @@ struct gl_texture_unit struct gl_texture_attrib { GLuint CurrentUnit; /**< GL_ACTIVE_TEXTURE */ - struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; + struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; @@ -1426,6 +1426,7 @@ struct gl_viewport_attrib */ struct gl_buffer_object { + _glthread_Mutex Mutex; GLint RefCount; GLuint Name; GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ @@ -1762,6 +1763,8 @@ struct gl_fragment_program struct gl_program Base; /**< base class */ GLenum FogOption; GLboolean UsesKill; /**< shader uses KIL instruction */ + GLboolean OriginUpperLeft; + GLboolean PixelCenterInteger; }; @@ -2395,11 +2398,13 @@ struct gl_extensions GLboolean ARB_depth_clamp; GLboolean ARB_draw_buffers; GLboolean ARB_draw_elements_base_vertex; + GLboolean ARB_fragment_coord_conventions; GLboolean ARB_fragment_program; GLboolean ARB_fragment_program_shadow; GLboolean ARB_fragment_shader; GLboolean ARB_framebuffer_object; GLboolean ARB_half_float_pixel; + GLboolean ARB_half_float_vertex; GLboolean ARB_imaging; GLboolean ARB_map_buffer_range; GLboolean ARB_multisample; @@ -2519,6 +2524,9 @@ struct gl_extensions GLboolean SGIS_texture_lod; GLboolean TDFX_texture_compression_FXT1; GLboolean S3_s3tc; +#if FEATURE_OES_draw_texture + GLboolean OES_draw_texture; +#endif /* FEATURE_OES_draw_texture */ /** The extension string */ const GLubyte *String; /** Number of supported extensions */ diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 3820ebd889..ca6ecd7bfb 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -32,7 +32,6 @@ #include "bufferobj.h" #include "colormac.h" #include "context.h" -#include "image.h" #include "macros.h" #include "pixel.h" #include "mtypes.h" @@ -151,13 +150,17 @@ validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack, GLboolean ok; /* Note, need to use DefaultPacking and Unpack's buffer object */ - ctx->DefaultPacking.BufferObj = pack->BufferObj; + _mesa_reference_buffer_object(ctx, + &ctx->DefaultPacking.BufferObj, + pack->BufferObj); ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, format, type, ptr); /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; + _mesa_reference_buffer_object(ctx, + &ctx->DefaultPacking.BufferObj, + ctx->Shared->NullBufferObj); if (!ok) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/src/mesa/main/pixelstore.c b/src/mesa/main/pixelstore.c index 6a641f83f2..ec585ef0cc 100644 --- a/src/mesa/main/pixelstore.c +++ b/src/mesa/main/pixelstore.c @@ -30,10 +30,7 @@ #include "glheader.h" #include "bufferobj.h" -#include "colormac.h" #include "context.h" -#include "image.h" -#include "macros.h" #include "pixelstore.h" #include "mtypes.h" diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index dcaeccd90d..eab9d13d6d 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -32,7 +32,6 @@ #include "context.h" #include "macros.h" #include "points.h" -#include "texstate.h" #include "mtypes.h" @@ -267,7 +266,7 @@ _mesa_init_point(GLcontext *ctx) ctx->Point.PointSprite = GL_FALSE; /* GL_ARB/NV_point_sprite */ ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */ ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */ - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { + for (i = 0; i < Elements(ctx->Point.CoordReplace); i++) { ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB/NV_point_sprite */ } } diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index 376a87a396..dcde6758c3 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -34,7 +34,6 @@ #include "context.h" #include "image.h" #include "enums.h" -#include "macros.h" #include "polygon.h" #include "mtypes.h" diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index 703b47ec74..be61dc265d 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -273,6 +273,7 @@ window_pos3f(GLfloat x, GLfloat y, GLfloat z) { GLuint texSet; for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) { + assert(texSet < Elements(ctx->Current.RasterTexCoords)); COPY_4FV( ctx->Current.RasterTexCoords[texSet], ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] ); } @@ -562,7 +563,7 @@ void _mesa_init_rastpos( GLcontext * ctx ) ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.RasterSecondaryColor, 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterIndex = 1.0; - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) + for (i = 0; i < Elements(ctx->Current.RasterTexCoords); i++) ASSIGN_4V( ctx->Current.RasterTexCoords[i], 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterPosValid = GL_TRUE; } diff --git a/src/mesa/main/remap.c b/src/mesa/main/remap.c index 0385ae8d7d..5f32a48258 100644 --- a/src/mesa/main/remap.c +++ b/src/mesa/main/remap.c @@ -45,7 +45,7 @@ #define need_MESA_remap_table -#include "remap_helper.h" +#include "main/remap_helper.h" #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #define MAX_ENTRY_POINTS 16 diff --git a/src/mesa/main/scissor.c b/src/mesa/main/scissor.c index b5f4cde789..523f3c3ab8 100644 --- a/src/mesa/main/scissor.c +++ b/src/mesa/main/scissor.c @@ -37,14 +37,14 @@ _mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height); + if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" ); return; } - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height); - _mesa_set_scissor(ctx, x, y, width, height); } diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 4d01e8abc6..b889364f0d 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -93,12 +93,8 @@ _mesa_alloc_shared_state(GLcontext *ctx) shared->BufferObjects = _mesa_NewHashTable(); #endif - /* Allocate the default buffer object and set refcount so high that - * it never gets deleted. - * XXX with recent/improved refcounting this may not longer be needed. - */ + /* Allocate the default buffer object */ shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0, 0); - shared->NullBufferObj->RefCount = 1000 * 1000 * 1000; /* Create default texture objects */ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { @@ -202,7 +198,7 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData) ctx->Driver.UnmapBuffer(ctx, 0, bufObj); bufObj->Pointer = NULL; } - ctx->Driver.DeleteBuffer(ctx, bufObj); + _mesa_reference_buffer_object(ctx, &bufObj, NULL); } @@ -288,8 +284,8 @@ delete_renderbuffer_cb(GLuint id, void *data, void *userData) * * \sa alloc_shared_state(). */ -void -_mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) +static void +free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) { GLuint i; @@ -335,7 +331,7 @@ _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) #endif #if FEATURE_ARB_vertex_buffer_object - ctx->Driver.DeleteBuffer(ctx, shared->NullBufferObj); + _mesa_reference_buffer_object(ctx, &shared->NullBufferObj, NULL); #endif #if FEATURE_ARB_sync @@ -368,3 +364,30 @@ _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) _mesa_free(shared); } + + +/** + * Decrement shared state object reference count and potentially free it + * and all children structures. + * + * \param ctx GL context. + * \param shared shared state pointer. + * + * \sa free_shared_state(). + */ +void +_mesa_release_shared_state(GLcontext *ctx, struct gl_shared_state *shared) +{ + GLint RefCount; + + _glthread_LOCK_MUTEX(shared->Mutex); + RefCount = --shared->RefCount; + _glthread_UNLOCK_MUTEX(shared->Mutex); + + assert(RefCount >= 0); + + if (RefCount == 0) { + /* free shared state */ + free_shared_state( ctx, shared ); + } +} diff --git a/src/mesa/main/shared.h b/src/mesa/main/shared.h index e59177e968..ef164a1459 100644 --- a/src/mesa/main/shared.h +++ b/src/mesa/main/shared.h @@ -31,7 +31,7 @@ _mesa_alloc_shared_state(GLcontext *ctx); void -_mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared); +_mesa_release_shared_state(GLcontext *ctx, struct gl_shared_state *shared); #endif diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index f10e6b04b7..5e07d1d2f1 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -48,7 +48,6 @@ #include "texenvprogram.h" #include "texobj.h" #include "texstate.h" -#include "viewport.h" static void @@ -83,12 +82,6 @@ compute_max_element(struct gl_client_array *array) } else { array->_MaxElement = 0; } - /* Compute the max element we can access in the VBO without going - * out of bounds. - */ - array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - - (GLsizeiptrARB) array->Ptr + array->StrideB - - array->_ElementSize) / array->StrideB; } else { /* user-space array, no idea how big it is */ diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index a4f1926ab3..cff6de89ee 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -35,10 +35,7 @@ #include "colormac.h" #include "context.h" #include "formats.h" -#include "image.h" -#include "mipmap.h" #include "texcompress.h" -#include "texstore.h" /** diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 499b7330d0..5cc5fdaebd 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -113,6 +113,8 @@ struct state_key { GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */ GLuint ModeA:5; /**< MODE_x */ + GLuint texture_cyl_wrap:1; /**< For gallium test/debug only */ + struct mode_opt OptRGB[MAX_COMBINER_TERMS]; struct mode_opt OptA[MAX_COMBINER_TERMS]; } unit[MAX_TEXTURE_UNITS]; @@ -464,6 +466,10 @@ static GLuint make_state_key( GLcontext *ctx, struct state_key *key ) key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; } + + /* this is a back-door for enabling cylindrical texture wrap mode */ + if (texObj->Priority == 0.125) + key->unit[i].texture_cyl_wrap = 1; } /* _NEW_LIGHT | _NEW_FOG */ @@ -1302,6 +1308,12 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit ) } else p->src_texture[unit] = get_zero(p); + + if (p->state->unit[unit].texture_cyl_wrap) { + /* set flag which is checked by Mesa->Gallium program translation */ + p->program->Base.InputFlags[0] |= PROG_PARAM_BIT_CYL_WRAP; + } + } } @@ -1535,8 +1547,15 @@ create_new_program(GLcontext *ctx, struct state_key *key, /* Notify driver the fragment program has (actually) changed. */ if (ctx->Driver.ProgramStringNotify) { - ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, - &p.program->Base ); + GLboolean ok = ctx->Driver.ProgramStringNotify(ctx, + GL_FRAGMENT_PROGRAM_ARB, + &p.program->Base); + /* Driver should be able to handle any texenv programs as long as + * the driver correctly reported max number of texture units correctly, + * etc. + */ + ASSERT(ok); + (void) ok; /* silence unused var warning */ } if (DISASSEM) { diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 1a374e7bee..096945a643 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -35,8 +35,6 @@ #include "context.h" #include "texcompress.h" -#include "texcompress_fxt1.h" -#include "texcompress_s3tc.h" #include "texformat.h" diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c index be4e03bc56..2ae839b2a6 100644 --- a/src/mesa/main/texgen.c +++ b/src/mesa/main/texgen.c @@ -210,7 +210,7 @@ _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) } -static void GLAPIENTRY +void GLAPIENTRY _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) { GLfloat p[4]; @@ -269,7 +269,7 @@ _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) -static void GLAPIENTRY +void GLAPIENTRY _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) { struct gl_texture_unit *texUnit; diff --git a/src/mesa/main/texgen.h b/src/mesa/main/texgen.h index f6924ef722..eb4626033a 100644 --- a/src/mesa/main/texgen.h +++ b/src/mesa/main/texgen.h @@ -41,8 +41,14 @@ extern void GLAPIENTRY _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); extern void GLAPIENTRY +_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ); + +extern void GLAPIENTRY _mesa_TexGeni( GLenum coord, GLenum pname, GLint param ); +extern void GLAPIENTRY +_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); + extern void _mesa_init_texgen_dispatch(struct _glapi_table *disp); diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index d786c41d2e..66d01c15d0 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -35,37 +35,11 @@ #include "context.h" #include "formats.h" #include "image.h" -#include "texcompress.h" #include "texgetimage.h" #include "teximage.h" -#include "texstate.h" -#if FEATURE_EXT_texture_sRGB - -/** - * Convert a float value from linear space to a - * non-linear sRGB value in [0, 255]. - * Not terribly efficient. - */ -static INLINE GLfloat -linear_to_nonlinear(GLfloat cl) -{ - /* can't have values outside [0, 1] */ - GLfloat cs; - if (cl < 0.0031308f) { - cs = 12.92f * cl; - } - else { - cs = (GLfloat)(1.055 * _mesa_pow(cl, 0.41666) - 0.055); - } - return cs; -} - -#endif /* FEATURE_EXT_texture_sRGB */ - - /** * Can the given type represent negative values? */ @@ -233,6 +207,29 @@ get_tex_ycbcr(GLcontext *ctx, GLuint dimensions, } +#if FEATURE_EXT_texture_sRGB + + +/** + * Convert a float value from linear space to a + * non-linear sRGB value in [0, 255]. + * Not terribly efficient. + */ +static INLINE GLfloat +linear_to_nonlinear(GLfloat cl) +{ + /* can't have values outside [0, 1] */ + GLfloat cs; + if (cl < 0.0031308f) { + cs = 12.92f * cl; + } + else { + cs = (GLfloat)(1.055 * _mesa_pow(cl, 0.41666) - 0.055); + } + return cs; +} + + /** * glGetTexImagefor sRGB pixels; */ @@ -284,6 +281,21 @@ get_tex_srgb(GLcontext *ctx, GLuint dimensions, } +#else /* FEATURE_EXT_texture_sRGB */ + + +static INLINE void +get_tex_srgb(GLcontext *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_image *texImage) +{ + ASSERT_NO_FEATURE(); +} + + +#endif /* FEATURE_EXT_texture_sRGB */ + + /** * glGetTexImagefor RGBA, Luminance, etc. pixels. * This is the slow way since we use texture sampling. diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index b946f3c69d..da3c6f9841 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -46,7 +46,6 @@ #include "texfetch.h" #include "teximage.h" #include "texstate.h" -#include "texstore.h" #include "mtypes.h" @@ -3225,8 +3224,8 @@ compressed_subtexture_error_check2(GLcontext *ctx, GLuint dims, } if (((width == 1 || width == 2) && - (GLuint) width != texImage->Width) || - (width > texImage->Width)) { + width != (GLsizei) texImage->Width) || + (width > (GLsizei) texImage->Width)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(width=%d)", dims, width); return GL_TRUE; @@ -3234,8 +3233,8 @@ compressed_subtexture_error_check2(GLcontext *ctx, GLuint dims, if (dims >= 2) { if (((height == 1 || height == 2) && - (GLuint) height != texImage->Height) || - (height > texImage->Height)) { + height != (GLsizei) texImage->Height) || + (height > (GLsizei) texImage->Height)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(height=%d)", dims, height); return GL_TRUE; @@ -3244,8 +3243,8 @@ compressed_subtexture_error_check2(GLcontext *ctx, GLuint dims, if (dims >= 3) { if (((depth == 1 || depth == 2) && - (GLuint) depth != texImage->Depth) || - (depth > texImage->Depth)) { + depth != (GLsizei) texImage->Depth) || + (depth > (GLsizei) texImage->Depth)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(depth=%d)", dims, depth); return GL_TRUE; diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 7f0a246025..9db95814d0 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -38,7 +38,6 @@ #include "imports.h" #include "macros.h" #include "teximage.h" -#include "texstate.h" #include "texobj.h" #include "mtypes.h" #include "shader/prog_instruction.h" diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index d917e21e74..0fde89b507 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -33,7 +33,6 @@ #include "main/glheader.h" #include "main/colormac.h" #include "main/context.h" -#include "main/enums.h" #include "main/formats.h" #include "main/macros.h" #include "main/texcompress.h" @@ -88,7 +87,7 @@ get_texobj(GLcontext *ctx, GLenum target, GLboolean get) { struct gl_texture_unit *texUnit; - if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "gl%sTexParameter(current unit)", get ? "Get" : ""); return NULL; @@ -816,7 +815,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameteriv(current unit)"); return; diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index c735e18aff..8c4399a430 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -35,11 +35,9 @@ #include "context.h" #include "enums.h" #include "macros.h" -#include "texcompress.h" #include "texobj.h" #include "teximage.h" #include "texstate.h" -#include "texenvprogram.h" #include "mtypes.h" @@ -79,7 +77,7 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) dst->Texture.SharedPalette = src->Texture.SharedPalette; /* per-unit state */ - for (u = 0; u < src->Const.MaxTextureImageUnits; u++) { + for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) { dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled; dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode; COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor); @@ -284,16 +282,25 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, void GLAPIENTRY _mesa_ActiveTextureARB(GLenum texture) { - GET_CURRENT_CONTEXT(ctx); const GLuint texUnit = texture - GL_TEXTURE0; + GLuint k; + GET_CURRENT_CONTEXT(ctx); + + /* See OpenGL spec for glActiveTexture: */ + k = MAX2(ctx->Const.MaxCombinedTextureImageUnits, + ctx->Const.MaxTextureCoordUnits); + + ASSERT(k <= Elements(ctx->Texture.Unit)); + ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glActiveTexture %s\n", _mesa_lookup_enum_by_nr(texture)); - if (texUnit >= ctx->Const.MaxTextureImageUnits) { - _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)"); + if (texUnit >= k) { + _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)", + _mesa_lookup_enum_by_nr(texture)); return; } @@ -357,6 +364,7 @@ update_texture_matrices( GLcontext *ctx ) ctx->Texture._TexMatEnabled = 0x0; for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + ASSERT(u < Elements(ctx->TextureMatrixStack)); if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) { _math_matrix_analyse( ctx->TextureMatrixStack[u].Top ); @@ -510,7 +518,7 @@ update_texture_state( GLcontext *ctx ) /* * Update texture unit state. */ - for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) { + for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLbitfield enabledVertTargets = 0x0; GLbitfield enabledFragTargets = 0x0; @@ -628,6 +636,7 @@ update_texture_state( GLcontext *ctx ) ctx->Texture._GenFlags |= texUnit->_GenFlags; } + ASSERT(unit < Elements(ctx->TextureMatrixStack)); if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit); } @@ -759,14 +768,15 @@ _mesa_init_texture(GLcontext *ctx) ctx->Texture.SharedPalette = GL_FALSE; _mesa_init_colortable(&ctx->Texture.Palette); - for (u = 0; u < MAX_TEXTURE_UNITS; u++) + for (u = 0; u < Elements(ctx->Texture.Unit); u++) init_texture_unit(ctx, u); /* After we're done initializing the context's texture state the default - * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. + * texture objects' refcounts should be at least + * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1. */ assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount - >= MAX_TEXTURE_UNITS + 1); + >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1); /* Allocate proxy textures */ if (!alloc_proxy_textures( ctx )) @@ -785,7 +795,7 @@ _mesa_free_texture_data(GLcontext *ctx) GLuint u, tgt; /* unreference current textures */ - for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + for (u = 0; u < Elements(ctx->Texture.Unit); u++) { /* The _Current texture could account for another reference */ _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL); @@ -798,7 +808,7 @@ _mesa_free_texture_data(GLcontext *ctx) for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); - for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) + for (u = 0; u < Elements(ctx->Texture.Unit); u++) _mesa_free_colortable_data(&ctx->Texture.Unit[u].ColorTable); } @@ -813,7 +823,7 @@ _mesa_update_default_objects_texture(GLcontext *ctx) { GLuint u, tex; - for (u = 0; u < MAX_TEXTURE_UNITS; u++) { + for (u = 0; u < Elements(ctx->Texture.Unit); u++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { _mesa_reference_texobj(&texUnit->CurrentTex[tex], diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 792c83141e..fcd0a56d76 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -263,7 +263,7 @@ compute_component_mapping(GLenum inFormat, GLenum outFormat, map[ZERO] = ZERO; map[ONE] = ONE; -/* +#if 0 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", inFormat, _mesa_lookup_enum_by_nr(inFormat), outFormat, _mesa_lookup_enum_by_nr(outFormat), @@ -273,7 +273,7 @@ compute_component_mapping(GLenum inFormat, GLenum outFormat, map[3], map[4], map[5]); -*/ +#endif } diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index c2193074cd..818ed792e3 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -121,6 +121,9 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = size * sizeof(GLhalfARB); + break; #if FEATURE_fixedpt case GL_FIXED: elementSize = size * sizeof(GLfixed); @@ -174,6 +177,9 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) case GL_DOUBLE: elementSize = 3 * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = 3 * sizeof(GLhalfARB); + break; #if FEATURE_fixedpt case GL_FIXED: elementSize = 3 * sizeof(GLfixed); @@ -250,6 +256,9 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = size * sizeof(GLhalfARB); + break; #if FEATURE_fixedpt case GL_FIXED: elementSize = size * sizeof(GLfixed); @@ -285,6 +294,9 @@ _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) case GL_DOUBLE: elementSize = sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = sizeof(GLhalfARB); + break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" ); return; @@ -394,6 +406,9 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = size * sizeof(GLhalfARB); + break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)", _mesa_lookup_enum_by_nr(type)); @@ -441,6 +456,9 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = size * sizeof(GLhalfARB); + break; #if FEATURE_fixedpt case GL_FIXED: elementSize = size * sizeof(GLfixed); @@ -457,6 +475,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, return; } + ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord)); + update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit), elementSize, size, type, GL_RGBA, stride, GL_FALSE, ptr); @@ -670,6 +690,9 @@ _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; + case GL_HALF_FLOAT: + elementSize = size * sizeof(GLhalfARB); + break; #if FEATURE_fixedpt case GL_FIXED: elementSize = size * sizeof(GLfixed); diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c index c9eea8ab83..0dd3e5e52e 100644 --- a/src/mesa/main/vtxfmt.c +++ b/src/mesa/main/vtxfmt.c @@ -28,11 +28,9 @@ #include "glheader.h" #include "api_arrayelt.h" -#include "api_loopback.h" #include "context.h" #include "imports.h" #include "mtypes.h" -#include "state.h" #include "vtxfmt.h" #include "eval.h" #include "dlist.h" diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index a09be71020..bdd26b7f3a 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -54,10 +54,8 @@ having three separate program parameter arrays. #include "main/glheader.h" #include "main/imports.h" #include "main/context.h" -#include "main/macros.h" #include "main/mtypes.h" #include "arbprogparse.h" -#include "program.h" #include "programopt.h" #include "prog_parameter.h" #include "prog_statevars.h" @@ -123,6 +121,8 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break; default: program->FogOption = GL_NONE; break; } + program->OriginUpperLeft = state.option.OriginUpperLeft; + program->PixelCenterInteger = state.option.PixelCenterInteger; program->UsesKill = state.fragment.UsesKill; diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index eb537cd1b9..7e3040a6ef 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -180,23 +180,24 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids) } else if (prog) { /* Unbind program if necessary */ - if (prog->Target == GL_VERTEX_PROGRAM_ARB || /* == GL_VERTEX_PROGRAM_NV */ - prog->Target == GL_VERTEX_STATE_PROGRAM_NV) { + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + case GL_VERTEX_STATE_PROGRAM_NV: if (ctx->VertexProgram.Current && ctx->VertexProgram.Current->Base.Id == ids[i]) { /* unbind this currently bound program */ _mesa_BindProgram(prog->Target, 0); } - } - else if (prog->Target == GL_FRAGMENT_PROGRAM_NV || - prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + break; + case GL_FRAGMENT_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: if (ctx->FragmentProgram.Current && ctx->FragmentProgram.Current->Base.Id == ids[i]) { /* unbind this currently bound program */ _mesa_BindProgram(prog->Target, 0); } - } - else { + break; + default: _mesa_problem(ctx, "bad target in glDeleteProgramsNV"); return; } @@ -488,8 +489,13 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, return; } - if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify) - ctx->Driver.ProgramStringNotify( ctx, target, base ); + if (ctx->Program.ErrorPos == -1) { + /* finally, give the program to the driver for translation/checking */ + if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glProgramStringARB(rejected by driver"); + } + } } @@ -561,6 +567,8 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, } } + + /** * Set a program env parameter register. * \note Called from the GL API dispatcher. @@ -569,10 +577,35 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, */ void GLAPIENTRY _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params) + const GLfloat *params) { - _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1], - params[2], params[3]); + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); + + if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { + _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); + return; + } + memcpy(ctx->FragmentProgram.Parameters[index], params, + 4 * sizeof(GLfloat)); + } + else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ + && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { + if (index >= ctx->Const.VertexProgram.MaxEnvParams) { + _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); + return; + } + memcpy(ctx->VertexProgram.Parameters[index], params, + 4 * sizeof(GLfloat)); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)"); + return; + } } @@ -581,7 +614,6 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - GLint i; GLfloat * dest; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -612,11 +644,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, return; } - for ( i = 0 ; i < count ; i++ ) { - COPY_4V(dest, params); - params += 4; - dest += 4; - } + memcpy(dest, params, count * 4 * sizeof(GLfloat)); } @@ -729,8 +757,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - struct gl_program *prog; - GLint i; + GLfloat *dest; ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); @@ -745,7 +772,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); return; } - prog = &(ctx->FragmentProgram.Current->Base); + dest = ctx->FragmentProgram.Current->Base.LocalParams[index]; } else if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { @@ -753,18 +780,14 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); return; } - prog = &(ctx->VertexProgram.Current->Base); + dest = ctx->VertexProgram.Current->Base.LocalParams[index]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)"); return; } - for (i = 0; i < count; i++) { - ASSERT((index + i) < MAX_PROGRAM_LOCAL_PARAMS); - COPY_4V(prog->LocalParams[index + i], params); - params += 4; - } + memcpy(dest, params, count * 4 * sizeof(GLfloat)); } diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c index e04a05b22f..ab7b2030d1 100644 --- a/src/mesa/shader/atifragshader.c +++ b/src/mesa/shader/atifragshader.c @@ -378,8 +378,11 @@ _mesa_EndFragmentShaderATI(void) } if (ctx->ATIFragmentShader.Current->cur_pass > 1) ctx->ATIFragmentShader.Current->NumPasses = 2; - else ctx->ATIFragmentShader.Current->NumPasses = 1; - ctx->ATIFragmentShader.Current->cur_pass=0; + else + ctx->ATIFragmentShader.Current->NumPasses = 1; + + ctx->ATIFragmentShader.Current->cur_pass = 0; + #if MESA_DEBUG_ATI_FS for (j = 0; j < MAX_NUM_PASSES_ATI; j++) { for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) { @@ -402,8 +405,13 @@ _mesa_EndFragmentShaderATI(void) } } #endif - if (ctx->Driver.ProgramStringNotify) - ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL ); + + if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) { + ctx->ATIFragmentShader.Current->isValid = GL_FALSE; + /* XXX is this the right error? */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glEndFragmentShaderATI(driver rejected shader)"); + } } void GLAPIENTRY diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c index 68543ae2e1..d1af35fedb 100644 --- a/src/mesa/shader/lex.yy.c +++ b/src/mesa/shader/lex.yy.c @@ -1043,12 +1043,12 @@ static yyconst flex_int16_t yy_chk[1368] = */ #include "main/glheader.h" #include "main/imports.h" -#include "prog_instruction.h" -#include "prog_statevars.h" +#include "shader/prog_instruction.h" +#include "shader/prog_statevars.h" -#include "symbol_table.h" -#include "program_parser.h" -#include "program_parse.tab.h" +#include "shader/symbol_table.h" +#include "shader/program_parser.h" +#include "shader/program_parse.tab.h" #define require_ARB_vp (yyextra->mode == ARB_vertex) #define require_ARB_fp (yyextra->mode == ARB_fragment) diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index fd6cbb0f40..87f295e39a 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -515,7 +515,7 @@ _mesa_emit_nv_temp_initialization(GLcontext *ctx, struct gl_program *program) { struct prog_instruction *inst; - int i; + GLuint i; if (!ctx->Shader.EmitNVTempInitialization) return; @@ -559,7 +559,7 @@ _mesa_emit_nv_temp_initialization(GLcontext *ctx, void _mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program) { - int i; + GLuint i; program->NumTemporaries = 0; for (i = 0; i < program->NumInstructions; i++) { diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index 8574016050..baff7658d1 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -40,7 +40,6 @@ #include "main/glheader.h" #include "main/context.h" #include "main/imports.h" -#include "main/macros.h" #include "nvprogram.h" #include "nvvertparse.h" #include "prog_instruction.h" diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 7f034520cd..7781cb3f7f 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -38,7 +38,6 @@ #include "main/glheader.h" #include "main/colormac.h" #include "main/context.h" -#include "program.h" #include "prog_execute.h" #include "prog_instruction.h" #include "prog_parameter.h" @@ -352,6 +351,28 @@ fetch_vector1(const struct prog_src_register *source, } +static GLuint +fetch_vector1ui(const struct prog_src_register *source, + const struct gl_program_machine *machine) +{ + const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); + GLuint result; + + ASSERT(src); + + result = src[GET_SWZ(source->Swizzle, 0)]; + + if (source->Abs) { + result = FABSF(result); + } + if (source->Negate) { + result = -result; + } + + return result; +} + + /** * Fetch texel from texture. Use partial derivatives when possible. */ @@ -680,6 +701,9 @@ _mesa_execute_program(GLcontext * ctx, GLfloat t[4]; fetch_vector4(&inst->SrcReg[0], machine, t); machine->AddressReg[0][0] = IFLOOR(t[0]); + if (DEBUG_PROG) { + printf("ARL %d\n", machine->AddressReg[0][0]); + } } break; case OPCODE_BGNLOOP: @@ -996,12 +1020,12 @@ _mesa_execute_program(GLcontext * ctx, /* XXX we could probably just use pow() here */ if (a[0] > 0.0F) { if (a[1] == 0.0 && a[3] == 0.0) - result[2] = 1.0; + result[2] = 1.0F; else result[2] = (GLfloat) _mesa_pow(a[1], a[3]); } else { - result[2] = 0.0; + result[2] = 0.0F; } result[3] = 1.0F; store_vector4(inst, machine, result); @@ -1668,13 +1692,11 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP2H: /* unpack two 16-bit floats */ { - GLfloat a[4], result[4]; - fi_type fi; - GLhalfNV hx, hy; - fetch_vector1(&inst->SrcReg[0], machine, a); - fi.f = a[0]; - hx = fi.i & 0xffff; - hy = fi.i >> 16; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; + GLushort hx, hy; + hx = raw & 0xffff; + hy = raw >> 16; result[0] = result[2] = _mesa_half_to_float(hx); result[1] = result[3] = _mesa_half_to_float(hy); store_vector4(inst, machine, result); @@ -1682,13 +1704,11 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP2US: /* unpack two GLushorts */ { - GLfloat a[4], result[4]; - fi_type fi; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; GLushort usx, usy; - fetch_vector1(&inst->SrcReg[0], machine, a); - fi.f = a[0]; - usx = fi.i & 0xffff; - usy = fi.i >> 16; + usx = raw & 0xffff; + usy = raw >> 16; result[0] = result[2] = usx * (1.0f / 65535.0f); result[1] = result[3] = usy * (1.0f / 65535.0f); store_vector4(inst, machine, result); @@ -1696,27 +1716,23 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP4B: /* unpack four GLbytes */ { - GLfloat a[4], result[4]; - fi_type fi; - fetch_vector1(&inst->SrcReg[0], machine, a); - fi.f = a[0]; - result[0] = (((fi.i >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((fi.i >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((fi.i >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((fi.i >> 24) & 0xff) - 128) / 127.0F; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; + result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F; + result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F; + result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F; + result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F; store_vector4(inst, machine, result); } break; case OPCODE_UP4UB: /* unpack four GLubytes */ { - GLfloat a[4], result[4]; - fi_type fi; - fetch_vector1(&inst->SrcReg[0], machine, a); - fi.f = a[0]; - result[0] = ((fi.i >> 0) & 0xff) / 255.0F; - result[1] = ((fi.i >> 8) & 0xff) / 255.0F; - result[2] = ((fi.i >> 16) & 0xff) / 255.0F; - result[3] = ((fi.i >> 24) & 0xff) / 255.0F; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; + result[0] = ((raw >> 0) & 0xff) / 255.0F; + result[1] = ((raw >> 8) & 0xff) / 255.0F; + result[2] = ((raw >> 16) & 0xff) / 255.0F; + result[3] = ((raw >> 24) & 0xff) / 255.0F; store_vector4(inst, machine, result); } break; diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c index ce411731b2..e1ec52254c 100644 --- a/src/mesa/shader/prog_optimize.c +++ b/src/mesa/shader/prog_optimize.c @@ -459,7 +459,7 @@ _mesa_remove_extra_move_use(struct gl_program *prog) */ for (j = i + 1; j < prog->NumInstructions; j++) { struct prog_instruction *inst2 = prog->Instructions + j; - int arg; + GLuint arg; if (_mesa_is_flow_control_opcode(inst2->Opcode)) break; @@ -867,7 +867,7 @@ find_live_intervals(struct gl_program *prog, _mesa_printf("Reg[%d] live [%d, %d]:", inv->Reg, inv->Start, inv->End); if (1) { - int j; + GLuint j; for (j = 0; j < inv->Start; j++) _mesa_printf(" "); for (j = inv->Start; j <= inv->End; j++) @@ -945,7 +945,7 @@ _mesa_reallocate_registers(struct gl_program *prog) */ { GLint j; - for (j = 0; j < activeIntervals.Num; j++) { + for (j = 0; j < (GLint) activeIntervals.Num; j++) { const struct interval *inv = activeIntervals.Intervals + j; if (inv->End >= live->Start) { /* Stop now. Since the activeInterval list is sorted @@ -994,7 +994,7 @@ _mesa_reallocate_registers(struct gl_program *prog) } } - if (maxTemp + 1 < liveIntervals.Num) { + if (maxTemp + 1 < (GLint) liveIntervals.Num) { /* OK, we've reduced the number of registers needed. * Scan the program and replace all the old temporary register * indexes with the new indexes. diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 699cb0c735..1111c85976 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -43,6 +43,7 @@ #define PROG_PARAM_BIT_INVARIANT 0x2 /**< for varying vars (GLSL 1.20) */ #define PROG_PARAM_BIT_FLAT 0x4 /**< for varying vars (GLSL 1.30) */ #define PROG_PARAM_BIT_LINEAR 0x8 /**< for varying vars (GLSL 1.30) */ +#define PROG_PARAM_BIT_CYL_WRAP 0x10 /**< XXX gallium debug */ /*@}*/ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 9f9789e010..54fd88ad4f 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -150,6 +150,10 @@ arb_input_attrib_string(GLint index, GLenum progType) "fragment.varying[7]" }; + /* sanity checks */ + assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0); + assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0); + if (progType == GL_VERTEX_PROGRAM_ARB) { assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0])); return vertAttribs[index]; @@ -162,6 +166,43 @@ arb_input_attrib_string(GLint index, GLenum progType) /** + * Print a vertex program's InputsRead field in human-readable format. + * For debugging. + */ +void +_mesa_print_vp_inputs(GLbitfield inputs) +{ + _mesa_printf("VP Inputs 0x%x: \n", inputs); + while (inputs) { + GLint attr = _mesa_ffs(inputs) - 1; + const char *name = arb_input_attrib_string(attr, + GL_VERTEX_PROGRAM_ARB); + _mesa_printf(" %d: %s\n", attr, name); + inputs &= ~(1 << attr); + } +} + + +/** + * Print a fragment program's InputsRead field in human-readable format. + * For debugging. + */ +void +_mesa_print_fp_inputs(GLbitfield inputs) +{ + _mesa_printf("FP Inputs 0x%x: \n", inputs); + while (inputs) { + GLint attr = _mesa_ffs(inputs) - 1; + const char *name = arb_input_attrib_string(attr, + GL_FRAGMENT_PROGRAM_ARB); + _mesa_printf(" %d: %s\n", attr, name); + inputs &= ~(1 << attr); + } +} + + + +/** * Return ARB_v/f_prog-style output attrib string. */ static const char * diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index fc286ded54..9ab7456016 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -37,6 +37,12 @@ typedef enum { } gl_prog_print_mode; +extern void +_mesa_print_vp_inputs(GLbitfield inputs); + +extern void +_mesa_print_fp_inputs(GLbitfield inputs); + extern const char * _mesa_condcode_string(GLuint condcode); diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 460ecd44a8..a0be1acfca 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -31,7 +31,6 @@ #include "main/glheader.h" #include "main/context.h" -#include "main/hash.h" #include "main/imports.h" #include "main/macros.h" #include "main/mtypes.h" @@ -303,9 +302,11 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], matrix = &ctx->_ModelProjectMatrix; } else if (mat == STATE_TEXTURE_MATRIX) { + ASSERT(index < Elements(ctx->TextureMatrixStack)); matrix = ctx->TextureMatrixStack[index].Top; } else if (mat == STATE_PROGRAM_MATRIX) { + ASSERT(index < Elements(ctx->ProgramMatrixStack)); matrix = ctx->ProgramMatrixStack[index].Top; } else if (mat == STATE_COLOR_MATRIX) { @@ -1140,7 +1141,9 @@ _mesa_load_tracked_matrices(GLcontext *ctx) mat = ctx->ProjectionMatrixStack.Top; } else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) { - mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top; + GLuint unit = MIN2(ctx->Texture.CurrentUnit, + Elements(ctx->TextureMatrixStack) - 1); + mat = ctx->TextureMatrixStack[unit].Top; } else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) { mat = ctx->ColorMatrixStack.Top; @@ -1152,7 +1155,7 @@ _mesa_load_tracked_matrices(GLcontext *ctx) else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV && ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) { GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV; - ASSERT(n < MAX_PROGRAM_MATRICES); + ASSERT(n < Elements(ctx->ProgramMatrixStack)); mat = ctx->ProgramMatrixStack[n].Top; } else { diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 6b8d94e661..aaf5f96e2a 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -580,7 +580,7 @@ _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count) for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; if (inst->BranchTarget > 0) { - if (inst->BranchTarget > start) { + if (inst->BranchTarget > (GLint) start) { inst->BranchTarget -= count; } } @@ -677,6 +677,8 @@ _mesa_combine_programs(GLcontext *ctx, const GLuint lenB = progB->NumInstructions; const GLuint numParamsA = _mesa_num_parameters(progA->Parameters); const GLuint newLength = lenA + lenB; + GLboolean usedTemps[MAX_PROGRAM_TEMPS]; + GLuint firstTemp = 0; GLbitfield inputsB; GLuint i; @@ -698,6 +700,10 @@ _mesa_combine_programs(GLcontext *ctx, newProg->Instructions = newInst; newProg->NumInstructions = newLength; + /* find used temp regs (we may need new temps below) */ + _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY, + usedTemps, MAX_PROGRAM_TEMPS); + if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprogA, *fprogB, *newFprog; GLbitfield progB_inputsRead = progB->InputsRead; @@ -741,12 +747,15 @@ _mesa_combine_programs(GLcontext *ctx, */ if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) && (progB_inputsRead & FRAG_BIT_COL0)) { - GLint tempReg = _mesa_find_free_register(newProg, PROGRAM_TEMPORARY); + GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS, + firstTemp); if (tempReg < 0) { _mesa_problem(ctx, "No free temp regs found in " "_mesa_combine_programs(), using 31"); tempReg = 31; } + firstTemp = tempReg + 1; + /* replace writes to result.color[0] with tempReg */ replace_registers(newInst, lenA, PROGRAM_OUTPUT, FRAG_RESULT_COLOR, @@ -784,53 +793,64 @@ _mesa_combine_programs(GLcontext *ctx, } - - /** - * Scan the given program to find a free register of the given type. - * \param regFile - PROGRAM_INPUT, PROGRAM_OUTPUT or PROGRAM_TEMPORARY + * Populate the 'used' array with flags indicating which registers (TEMPs, + * INPUTs, OUTPUTs, etc, are used by the given program. + * \param file type of register to scan for + * \param used returns true/false flags for in use / free + * \param usedSize size of the 'used' array */ -GLint -_mesa_find_free_register(const struct gl_program *prog, GLuint regFile) +void +_mesa_find_used_registers(const struct gl_program *prog, + gl_register_file file, + GLboolean used[], GLuint usedSize) { - GLboolean used[MAX_PROGRAM_TEMPS]; - GLuint i, k; - - assert(regFile == PROGRAM_INPUT || - regFile == PROGRAM_OUTPUT || - regFile == PROGRAM_TEMPORARY); + GLuint i, j; - _mesa_memset(used, 0, sizeof(used)); + _mesa_memset(used, 0, usedSize); for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); - /* check dst reg first */ - if (inst->DstReg.File == regFile) { + if (inst->DstReg.File == file) { used[inst->DstReg.Index] = GL_TRUE; } - else { - /* check src regs otherwise */ - for (k = 0; k < n; k++) { - if (inst->SrcReg[k].File == regFile) { - used[inst->SrcReg[k].Index] = GL_TRUE; - break; - } + + for (j = 0; j < n; j++) { + if (inst->SrcReg[j].File == file) { + used[inst->SrcReg[j].Index] = GL_TRUE; } } } +} - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { + +/** + * Scan the given 'used' register flag array for the first entry + * that's >= firstReg. + * \param used vector of flags indicating registers in use (as returned + * by _mesa_find_used_registers()) + * \param usedSize size of the 'used' array + * \param firstReg first register to start searching at + * \return index of unused register, or -1 if none. + */ +GLint +_mesa_find_free_register(const GLboolean used[], + GLuint usedSize, GLuint firstReg) +{ + GLuint i; + + assert(firstReg < usedSize); + + for (i = firstReg; i < usedSize; i++) if (!used[i]) return i; - } return -1; } - /** * "Post-process" a GPU program. This is intended to be used for debugging. * Example actions include no-op'ing instructions or changing instruction diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 56a4191f57..0187a2c55f 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -119,8 +119,14 @@ _mesa_combine_programs(GLcontext *ctx, const struct gl_program *progA, const struct gl_program *progB); +extern void +_mesa_find_used_registers(const struct gl_program *prog, + gl_register_file file, + GLboolean used[], GLuint usedSize); + extern GLint -_mesa_find_free_register(const struct gl_program *prog, GLuint regFile); +_mesa_find_free_register(const GLboolean used[], + GLuint maxRegs, GLuint firstReg); extern void _mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog); diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l index e2acb3c0c9..83bc5089d9 100644 --- a/src/mesa/shader/program_lexer.l +++ b/src/mesa/shader/program_lexer.l @@ -23,12 +23,12 @@ */ #include "main/glheader.h" #include "main/imports.h" -#include "prog_instruction.h" -#include "prog_statevars.h" +#include "shader/prog_instruction.h" +#include "shader/prog_statevars.h" -#include "symbol_table.h" -#include "program_parser.h" -#include "program_parse.tab.h" +#include "shader/symbol_table.h" +#include "shader/program_parser.h" +#include "shader/program_parse.tab.h" #define require_ARB_vp (yyextra->mode == ARB_vertex) #define require_ARB_fp (yyextra->mode == ARB_fragment) diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c index b12dcee9df..2adfb40973 100644 --- a/src/mesa/shader/program_parse.tab.c +++ b/src/mesa/shader/program_parse.tab.c @@ -98,14 +98,14 @@ #include "main/mtypes.h" #include "main/imports.h" -#include "program.h" -#include "prog_parameter.h" -#include "prog_parameter_layout.h" -#include "prog_statevars.h" -#include "prog_instruction.h" - -#include "symbol_table.h" -#include "program_parser.h" +#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_parameter_layout.h" +#include "shader/prog_statevars.h" +#include "shader/prog_instruction.h" + +#include "shader/symbol_table.h" +#include "shader/program_parser.h" extern void *yy_scan_string(char *); extern void yy_delete_buffer(void *); diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index 5c5d8d7590..3880d54917 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -27,14 +27,14 @@ #include "main/mtypes.h" #include "main/imports.h" -#include "program.h" -#include "prog_parameter.h" -#include "prog_parameter_layout.h" -#include "prog_statevars.h" -#include "prog_instruction.h" - -#include "symbol_table.h" -#include "program_parser.h" +#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_parameter_layout.h" +#include "shader/prog_statevars.h" +#include "shader/prog_instruction.h" + +#include "shader/symbol_table.h" +#include "shader/program_parser.h" extern void *yy_scan_string(char *); extern void yy_delete_buffer(void *); diff --git a/src/mesa/shader/program_parse_extra.c b/src/mesa/shader/program_parse_extra.c index 0656c5eaa8..ae98b782b7 100644 --- a/src/mesa/shader/program_parse_extra.c +++ b/src/mesa/shader/program_parse_extra.c @@ -216,6 +216,18 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) state->option.Shadow = 1; return 1; } + } else if (strncmp(option, "fragment_coord_", 15) == 0) { + option += 15; + if (state->ctx->Extensions.ARB_fragment_coord_conventions) { + if (strcmp(option, "origin_upper_left") == 0) { + state->option.OriginUpperLeft = 1; + return 1; + } + else if (strcmp(option, "pixel_center_integer") == 0) { + state->option.PixelCenterInteger = 1; + return 1; + } + } } } else if (strncmp(option, "NV_fragment_program", 19) == 0) { option += 19; diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h index 69396ca2c0..730466c30f 100644 --- a/src/mesa/shader/program_parser.h +++ b/src/mesa/shader/program_parser.h @@ -209,6 +209,8 @@ struct asm_parser_state { unsigned TexRect:1; unsigned TexArray:1; unsigned NV_fragment:1; + unsigned OriginUpperLeft:1; + unsigned PixelCenterInteger:1; } option; struct { diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 9514545709..fb2ebe6338 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -495,6 +495,11 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) GLuint i; GLint outputMap[VERT_RESULT_MAX]; GLuint numVaryingReads = 0; + GLboolean usedTemps[MAX_PROGRAM_TEMPS]; + GLuint firstTemp = 0; + + _mesa_find_used_registers(prog, PROGRAM_TEMPORARY, + usedTemps, MAX_PROGRAM_TEMPS); assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); @@ -513,8 +518,10 @@ _mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) const GLuint var = inst->SrcReg[j].Index; if (outputMap[var] == -1) { numVaryingReads++; - outputMap[var] = _mesa_find_free_register(prog, - PROGRAM_TEMPORARY); + outputMap[var] = _mesa_find_free_register(usedTemps, + MAX_PROGRAM_TEMPS, + firstTemp); + firstTemp = outputMap[var] + 1; } inst->SrcReg[j].File = PROGRAM_TEMPORARY; inst->SrcReg[j].Index = outputMap[var]; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 453cd3964a..e8eaa9c103 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -39,10 +39,8 @@ #include "main/glheader.h" #include "main/context.h" #include "main/hash.h" -#include "main/macros.h" #include "shader/program.h" #include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "shader/prog_statevars.h" #include "shader/prog_uniform.h" #include "shader/shader_api.h" @@ -957,7 +955,7 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, if (size) { GLint typeSize = sizeof_glsl_type(param->DataType); - if (param->Size > typeSize) { + if ((GLint) param->Size > typeSize) { /* This is an array. * Array elements are placed on vector[4] boundaries so they're * a multiple of four floats. We round typeSize up to next multiple @@ -1717,7 +1715,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, */ FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); _mesa_update_shader_textures_used(program); - ctx->Driver.ProgramStringNotify(ctx, program->Target, program); + /* Do we need to care about the return value here? + * This should not be the first time the driver was notified of + * this program. + */ + (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program); } } else { @@ -1728,7 +1730,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, const GLint typeSize = sizeof_glsl_type(param->DataType); GLsizei k, i; - if (param->Size > typeSize) { + if ((GLint) param->Size > typeSize) { /* an array */ /* we'll ignore extra data below */ } @@ -1913,7 +1915,7 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, GLuint mat, row, col; GLuint src = 0; const struct gl_program_parameter * param = &program->Parameters->Parameters[index]; - const GLint slots = (param->Size + 3) / 4; + const GLuint slots = (param->Size + 3) / 4; const GLint typeSize = sizeof_glsl_type(param->DataType); GLint nr, nc; @@ -1925,7 +1927,7 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, return; } - if (param->Size <= typeSize) { + if ((GLint) param->Size <= typeSize) { /* non-array: count must be at most one; count == 0 is handled by the loop below */ if (count > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index e5809509c9..0a9f0b97fb 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -36,7 +36,6 @@ #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" #include "shader/slang/slang_ir.h" -#include "shader/slang/slang_emit.h" #include "shader/slang/slang_builtin.h" diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 372a9acdd0..83098b7350 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -3196,7 +3196,7 @@ _slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) newOper = slang_operation_new(1); newOper->type = SLANG_OPER_LITERAL_INT; newOper->literal_size = 1; - newOper->literal[0] = iter; + newOper->literal[0] = (GLfloat) iter; /* replace instances of the loop variable with newOper */ slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE); diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 6499cfcb2f..63d10f4597 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -40,14 +40,11 @@ #include "slang_codegen.h" #include "slang_compile.h" #include "slang_storage.h" -#include "slang_emit.h" #include "slang_log.h" #include "slang_mem.h" #include "slang_vartable.h" #include "slang_simplify.h" -#include "slang_print.h" - /* * This is a straightforward implementation of the slang front-end * compiler. Lots of error-checking functionality is missing but diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index ce3f6ab7ea..c9ecbd275b 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -38,7 +38,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/macros.h" #include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index ed27821a95..df524ce078 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -31,7 +31,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/hash.h" #include "main/macros.h" #include "shader/program.h" #include "shader/prog_instruction.h" @@ -720,6 +719,7 @@ _slang_link(GLcontext *ctx, { const struct gl_vertex_program *vertProg = NULL; const struct gl_fragment_program *fragProg = NULL; + GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE; GLuint numSamplers = 0; GLuint i; @@ -872,8 +872,8 @@ _slang_link(GLcontext *ctx, _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base); /* notify driver that a new fragment program has been compiled/linked */ - ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, - &shProg->FragmentProgram->Base); + vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, + &shProg->FragmentProgram->Base); if (ctx->Shader.Flags & GLSL_DUMP) { _mesa_printf("Mesa pre-link fragment program:\n"); _mesa_print_program(&fragProg->Base); @@ -890,8 +890,8 @@ _slang_link(GLcontext *ctx, _mesa_update_shader_textures_used(&shProg->VertexProgram->Base); /* notify driver that a new vertex program has been compiled/linked */ - ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, - &shProg->VertexProgram->Base); + fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, + &shProg->VertexProgram->Base); if (ctx->Shader.Flags & GLSL_DUMP) { _mesa_printf("Mesa pre-link vertex program:\n"); _mesa_print_program(&vertProg->Base); @@ -919,6 +919,12 @@ _slang_link(GLcontext *ctx, } } - shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); + if (!vertNotify || !fragNotify) { + /* driver rejected one/both of the vertex/fragment programs */ + link_error(shProg, "Vertex and/or fragment program rejected by driver\n"); + } + else { + shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); + } } diff --git a/src/mesa/shader/slang/slang_log.c b/src/mesa/shader/slang/slang_log.c index d7d2b4fbfd..4f6b8541c5 100644 --- a/src/mesa/shader/slang/slang_log.c +++ b/src/mesa/shader/slang/slang_log.c @@ -24,7 +24,6 @@ */ #include "main/imports.h" -#include "main/context.h" #include "slang_log.h" #include "slang_utility.h" diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index c42f61af5e..12d4c2831d 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -89,6 +89,7 @@ GLAPI_SOURCES = \ main/dispatch.c \ glapi/glapi.c \ glapi/glapi_getproc.c \ + glapi/glapi_nop.c \ glapi/glthread.c MATH_SOURCES = \ @@ -204,7 +205,6 @@ STATETRACKER_SOURCES = \ state_tracker/st_cb_strings.c \ state_tracker/st_cb_texture.c \ state_tracker/st_cb_viewport.c \ - state_tracker/st_api.c \ state_tracker/st_context.c \ state_tracker/st_debug.c \ state_tracker/st_draw.c \ diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 43e62c29f3..1511b88dd1 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -152,14 +152,54 @@ translate_logicop(GLenum logicop) } } +/** + * Figure out if colormasks are different per rt. + */ +static GLboolean +colormask_per_rt(GLcontext *ctx) +{ + /* a bit suboptimal have to compare lots of values */ + unsigned i; + for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { + if (memcmp(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i], 4)) { + return GL_TRUE; + } + } + return GL_FALSE; +} + +/** + * Figure out if blend enables are different per rt. + */ +static GLboolean +blend_per_rt(GLcontext *ctx) +{ + if (ctx->Color.BlendEnabled && + (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { + return GL_TRUE; + } + return GL_FALSE; +} static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + unsigned num_state = 1; + unsigned i; memset(blend, 0, sizeof(*blend)); + if (blend_per_rt(st->ctx) || colormask_per_rt(st->ctx)) { + num_state = st->ctx->Const.MaxDrawBuffers; + blend->independent_blend_enable = 1; + } + /* Note it is impossible to correctly deal with EXT_blend_logic_op and + EXT_draw_buffers2/EXT_blend_equation_separate at the same time. + These combinations would require support for per-rt logicop enables + and separate alpha/rgb logicop/blend support respectively. Neither + possible in gallium nor most hardware. Assume these combinations + don't happen. */ if (st->ctx->Color.ColorLogicOpEnabled || (st->ctx->Color.BlendEnabled && st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) { @@ -169,30 +209,33 @@ update_blend( struct st_context *st ) } else if (st->ctx->Color.BlendEnabled) { /* blending enabled */ - blend->blend_enable = 1; - - blend->rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); - if (st->ctx->Color.BlendEquationRGB == GL_MIN || - st->ctx->Color.BlendEquationRGB == GL_MAX) { - /* Min/max are special */ - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); - blend->rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); - } + for (i = 0; i < num_state; i++) { - blend->alpha_func = translate_blend(st->ctx->Color.BlendEquationA); - if (st->ctx->Color.BlendEquationA == GL_MIN || - st->ctx->Color.BlendEquationA == GL_MAX) { - /* Min/max are special */ - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); - blend->alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + + blend->rt[i].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); + if (st->ctx->Color.BlendEquationRGB == GL_MIN || + st->ctx->Color.BlendEquationRGB == GL_MAX) { + /* Min/max are special */ + blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); + blend->rt[i].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); + } + + blend->rt[i].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); + if (st->ctx->Color.BlendEquationA == GL_MIN || + st->ctx->Color.BlendEquationA == GL_MAX) { + /* Min/max are special */ + blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); + blend->rt[i].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + } } } else { @@ -200,14 +243,16 @@ update_blend( struct st_context *st ) } /* Colormask - maybe reverse these bits? */ - if (st->ctx->Color.ColorMask[0][0]) - blend->colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[0][1]) - blend->colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[0][2]) - blend->colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[0][3]) - blend->colormask |= PIPE_MASK_A; + for (i = 0; i < num_state; i++) { + if (st->ctx->Color.ColorMask[i][0]) + blend->rt[i].colormask |= PIPE_MASK_R; + if (st->ctx->Color.ColorMask[i][1]) + blend->rt[i].colormask |= PIPE_MASK_G; + if (st->ctx->Color.ColorMask[i][2]) + blend->rt[i].colormask |= PIPE_MASK_B; + if (st->ctx->Color.ColorMask[i][3]) + blend->rt[i].colormask |= PIPE_MASK_A; + } if (st->ctx->Color.DitherFlag) blend->dither = 1; diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 77153889b6..d975cd66f7 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -37,7 +37,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "st_debug.h" #include "st_context.h" @@ -57,7 +57,7 @@ void st_upload_constants( struct st_context *st, unsigned shader_type) { struct pipe_context *pipe = st->pipe; - struct pipe_constant_buffer *cbuf = &st->state.constants[shader_type]; + struct pipe_buffer **cbuf = &st->state.constants[shader_type]; assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT); @@ -71,8 +71,8 @@ void st_upload_constants( struct st_context *st, /* We always need to get a new buffer, to keep the drivers simple and * avoid gratuitous rendering synchronization. */ - pipe_buffer_reference(&cbuf->buffer, NULL ); - cbuf->buffer = pipe_buffer_create(pipe->screen, 16, + pipe_buffer_reference(cbuf, NULL ); + *cbuf = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT, paramBytes ); @@ -84,12 +84,12 @@ void st_upload_constants( struct st_context *st, } /* load Mesa constants into the constant buffer */ - if (cbuf->buffer) - st_no_flush_pipe_buffer_write(st, cbuf->buffer, + if (cbuf) + st_no_flush_pipe_buffer_write(st, *cbuf, 0, paramBytes, params->ParameterValues); - st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf); + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, *cbuf); } else { st->constants.tracked_state[shader_type].dirty.mesa = 0x0; diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 8ca4335e33..fba7bfe2ce 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -37,10 +37,10 @@ #include "st_public.h" #include "st_texture.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_rect.h" #include "util/u_math.h" +#include "util/u_inlines.h" diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 6a5854e9ba..0b2e3f5381 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -43,7 +43,6 @@ #include "st_context.h" #include "st_format.h" -#include "st_program.h" #include "st_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 7b84a86ba4..9d63f1c6ab 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -37,7 +37,6 @@ #include "st_context.h" #include "st_cb_texture.h" #include "st_atom.h" -#include "st_program.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index 3fd59e1945..5e0c51cff0 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -31,6 +31,7 @@ */ +#include "main/macros.h" #include "st_context.h" #include "pipe/p_context.h" #include "st_atom.h" @@ -52,15 +53,19 @@ update_scissor( struct st_context *st ) scissor.maxy = fb->Height; if (st->ctx->Scissor.Enabled) { - if ((GLuint)st->ctx->Scissor.X > scissor.minx) + /* need to be careful here with xmax or ymax < 0 */ + GLint xmax = MAX2(0, st->ctx->Scissor.X + st->ctx->Scissor.Width); + GLint ymax = MAX2(0, st->ctx->Scissor.Y + st->ctx->Scissor.Height); + + if (st->ctx->Scissor.X > (GLint)scissor.minx) scissor.minx = st->ctx->Scissor.X; - if ((GLuint)st->ctx->Scissor.Y > scissor.miny) + if (st->ctx->Scissor.Y > (GLint)scissor.miny) scissor.miny = st->ctx->Scissor.Y; - if ((GLuint)st->ctx->Scissor.X + st->ctx->Scissor.Width < scissor.maxx) - scissor.maxx = st->ctx->Scissor.X + st->ctx->Scissor.Width; - if ((GLuint)st->ctx->Scissor.Y + st->ctx->Scissor.Height < scissor.maxy) - scissor.maxy = st->ctx->Scissor.Y + st->ctx->Scissor.Height; + if (xmax < (GLint) scissor.maxx) + scissor.maxx = xmax; + if (ymax < (GLint) scissor.maxy) + scissor.maxy = ymax; /* check for null space */ if (scissor.minx >= scissor.maxx || scissor.miny >= scissor.maxy) diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 46c8cbb309..ea16719ba0 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -35,11 +35,8 @@ * Brian Paul */ - - #include "main/imports.h" #include "main/mtypes.h" -#include "main/macros.h" #include "shader/program.h" #include "pipe/p_context.h" @@ -52,40 +49,20 @@ #include "st_context.h" #include "st_atom.h" #include "st_program.h" -#include "st_atom_shader.h" -#include "st_mesa_to_tgsi.h" - - -/* +/** * Translate fragment program if needed. */ static void translate_fp(struct st_context *st, struct st_fragment_program *stfp) { - const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead; - if (!stfp->state.tokens) { - GLuint inAttr, numIn = 0; - - for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) { - if (fragInputsRead & (1 << inAttr)) { - stfp->input_to_slot[inAttr] = numIn; - numIn++; - } - else { - stfp->input_to_slot[inAttr] = -1; - } - } - - stfp->num_input_slots = numIn; + assert(stfp->Base.Base.NumInstructions > 0); - assert(stfp->Base.Base.NumInstructions > 1); - - st_translate_fragment_program(st, stfp, stfp->input_to_slot); + st_translate_fragment_program(st, stfp); } } @@ -155,8 +132,10 @@ find_translated_vp(struct st_context *st, } - - +/** + * Return pointer to a pass-through fragment shader. + * This shader is used when a texture is missing/incomplete. + */ static void * get_passthrough_fs(struct st_context *st) { @@ -168,6 +147,11 @@ get_passthrough_fs(struct st_context *st) return st->passthrough_fs; } + +/** + * Update fragment program state/atom. This involves translating the + * Mesa fragment program into a gallium fragment program and binding it. + */ static void update_fp( struct st_context *st ) { @@ -191,6 +175,7 @@ update_fp( struct st_context *st ) } } + const struct st_tracked_state st_update_fp = { "st_update_fp", /* name */ { /* dirty */ @@ -202,7 +187,10 @@ const struct st_tracked_state st_update_fp = { - +/** + * Update vertex program state/atom. This involves translating the + * Mesa vertex program into a gallium fragment program and binding it. + */ static void update_vp( struct st_context *st ) { diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 0b68447d21..57b71c1e7b 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -39,6 +39,7 @@ #include "st_texture.h" #include "st_cb_texture.h" #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "cso_cache/cso_context.h" diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c index 27ec2eb033..0b6c34ca2c 100644 --- a/src/mesa/state_tracker/st_atom_viewport.c +++ b/src/mesa/state_tracker/st_atom_viewport.c @@ -27,7 +27,6 @@ #include "main/context.h" -#include "main/colormac.h" #include "st_context.h" #include "st_atom.h" #include "pipe/p_context.h" @@ -62,9 +61,9 @@ update_viewport( struct st_context *st ) GLfloat x = (GLfloat)ctx->Viewport.X; GLfloat y = (GLfloat)ctx->Viewport.Y; GLfloat z = ctx->Viewport.Near; - GLfloat half_width = (GLfloat)ctx->Viewport.Width / 2.0f; - GLfloat half_height = (GLfloat)ctx->Viewport.Height / 2.0f; - GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) / 2.0f; + GLfloat half_width = (GLfloat)ctx->Viewport.Width * 0.5f; + GLfloat half_height = (GLfloat)ctx->Viewport.Height * 0.5f; + GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) * 0.5f; st->state.viewport.scale[0] = half_width; st->state.viewport.scale[1] = half_height * yScale; diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index da7b97d325..1be72e729e 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -38,14 +38,12 @@ #include "st_context.h" #include "st_cb_accum.h" #include "st_cb_fbo.h" -#include "st_draw.h" #include "st_public.h" -#include "st_format.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_tile.h" diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 1bdeaccda3..85420a950f 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -34,9 +34,7 @@ #include "main/image.h" #include "main/bufferobj.h" #include "main/macros.h" -#include "main/texformat.h" #include "shader/program.h" -#include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "st_context.h" @@ -44,15 +42,12 @@ #include "st_atom_constbuf.h" #include "st_program.h" #include "st_cb_bitmap.h" -#include "st_cb_program.h" -#include "st_mesa_to_tgsi.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "util/u_tile.h" +#include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_simple_shaders.h" #include "shader/prog_instruction.h" @@ -226,7 +221,7 @@ combined_bitmap_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp->bitmap_program, NULL); + st_translate_fragment_program(st, stfp->bitmap_program); } return stfp->bitmap_program; @@ -386,11 +381,11 @@ setup_bitmap_vertex_data(struct st_context *st, } /* put vertex data into vbuf */ - st_no_flush_pipe_buffer_write(st, - st->bitmap.vbuf, - st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, - sizeof st->bitmap.vertices, - st->bitmap.vertices); + st_no_flush_pipe_buffer_write_nooverlap(st, + st->bitmap.vbuf, + st->bitmap.vbuf_slot * sizeof st->bitmap.vertices, + sizeof st->bitmap.vertices, + st->bitmap.vertices); return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices; } diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 563615ed0d..36e03018d9 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -33,20 +33,15 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" -#include "main/texformat.h" #include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "st_context.h" #include "st_texture.h" -#include "st_program.h" #include "st_cb_blit.h" #include "st_cb_fbo.h" #include "util/u_blit.h" - -#include "cso_cache/cso_context.h" +#include "util/u_inlines.h" void diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 0102d8a6f7..f1b4f11c05 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -42,7 +42,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" /** @@ -75,6 +75,8 @@ st_bufferobj_free(GLcontext *ctx, struct gl_buffer_object *obj) { struct st_buffer_object *st_obj = st_buffer_object(obj); + assert(obj->RefCount == 0); + if (st_obj->buffer) pipe_buffer_reference(&st_obj->buffer, NULL); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 192d765f45..0c7bcb8597 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -42,18 +42,15 @@ #include "st_cb_accum.h" #include "st_cb_clear.h" #include "st_cb_fbo.h" -#include "st_draw.h" #include "st_program.h" #include "st_public.h" -#include "st_mesa_to_tgsi.h" #include "st_inlines.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" -#include "util/u_pack_color.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" @@ -166,10 +163,10 @@ draw_quad(GLcontext *ctx, } /* put vertex data into vbuf */ - st_no_flush_pipe_buffer_write(st, st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), - sizeof(st->clear.vertices), - st->clear.vertices); + st_no_flush_pipe_buffer_write_nooverlap(st, st->clear.vbuf, + st->clear.vbuf_slot * sizeof(st->clear.vertices), + sizeof(st->clear.vertices), + st->clear.vertices); /* draw */ util_draw_vertex_buffer(pipe, @@ -227,19 +224,19 @@ clear_with_quad(GLcontext *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { if (ctx->Color.ColorMask[0][0]) - blend.colormask |= PIPE_MASK_R; + blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[0][1]) - blend.colormask |= PIPE_MASK_G; + blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->Color.ColorMask[0][2]) - blend.colormask |= PIPE_MASK_B; + blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->Color.ColorMask[0][3]) - blend.colormask |= PIPE_MASK_A; + blend.rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; } diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c index 780b40c206..8483b93bd8 100644 --- a/src/mesa/state_tracker/st_cb_condrender.c +++ b/src/mesa/state_tracker/st_cb_condrender.c @@ -69,6 +69,7 @@ st_BeginConditionalRender(GLcontext *ctx, struct gl_query_object *q, break; default: assert(0 && "bad mode in st_BeginConditionalRender"); + m = PIPE_RENDER_COND_WAIT; } pipe->render_condition(pipe, stq->pq, m); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 7c664267d4..2a084ca577 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -36,30 +36,24 @@ #include "main/macros.h" #include "main/texformat.h" #include "main/texstore.h" -#include "main/state.h" #include "shader/program.h" -#include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "st_debug.h" #include "st_context.h" #include "st_atom.h" #include "st_atom_constbuf.h" -#include "st_draw.h" #include "st_program.h" #include "st_cb_drawpixels.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" -#include "st_cb_texture.h" -#include "st_draw.h" #include "st_format.h" -#include "st_mesa_to_tgsi.h" #include "st_texture.h" #include "st_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "tgsi/tgsi_ureg.h" #include "util/u_tile.h" #include "util/u_draw_quad.h" @@ -146,7 +140,7 @@ combined_drawpix_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp, NULL); + st_translate_fragment_program(st, stfp); /* save new program, update serial numbers */ st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo; @@ -227,7 +221,7 @@ make_fragment_shader_z(struct st_context *st) p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ st->drawpix.z_shader = (struct st_fragment_program *) p; - st_translate_fragment_program(st, st->drawpix.z_shader, NULL); + st_translate_fragment_program(st, st->drawpix.z_shader); return st->drawpix.z_shader; } @@ -1138,6 +1132,8 @@ st_destroy_drawpix(struct st_context *st) { st_reference_fragprog(st, &st->drawpix.z_shader, NULL); st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL); - st_reference_vertprog(st, &st->drawpix.vert_shaders[0], NULL); - st_reference_vertprog(st, &st->drawpix.vert_shaders[1], NULL); + if (st->drawpix.vert_shaders[0]) + free(st->drawpix.vert_shaders[0]); + if (st->drawpix.vert_shaders[1]) + free(st->drawpix.vert_shaders[1]); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 45ce34a85f..9f2fe7420d 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -44,13 +44,13 @@ #include "pipe/p_screen.h" #include "st_context.h" #include "st_cb_fbo.h" -#include "st_cb_texture.h" #include "st_format.h" #include "st_public.h" #include "st_texture.h" #include "util/u_format.h" #include "util/u_rect.h" +#include "util/u_inlines.h" /** diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c index 93f7145219..edf26473d4 100644 --- a/src/mesa/state_tracker/st_cb_feedback.c +++ b/src/mesa/state_tracker/st_cb_feedback.c @@ -40,19 +40,15 @@ #include "main/imports.h" #include "main/context.h" #include "main/feedback.h" -#include "main/macros.h" #include "vbo/vbo.h" #include "st_context.h" -#include "st_atom.h" #include "st_draw.h" #include "st_cb_feedback.h" -#include "st_cb_bufferobjects.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "cso_cache/cso_cache.h" #include "draw/draw_context.h" #include "draw/draw_pipe.h" diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 8c276f8128..82ef5572e1 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -36,7 +36,6 @@ #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/program.h" -#include "shader/programopt.h" #include "shader/shader_api.h" #include "cso_cache/cso_context.h" @@ -44,7 +43,6 @@ #include "st_context.h" #include "st_program.h" -#include "st_atom_shader.h" #include "st_mesa_to_tgsi.h" #include "st_cb_program.h" @@ -179,9 +177,9 @@ static GLboolean st_is_program_native( GLcontext *ctx, } -static void st_program_string_notify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) +static GLboolean st_program_string_notify( GLcontext *ctx, + GLenum target, + struct gl_program *prog ) { struct st_context *st = st_context(ctx); @@ -213,6 +211,9 @@ static void st_program_string_notify( GLcontext *ctx, if (st->vp == stvp) st->dirty.st |= ST_NEW_VERTEX_PROGRAM; } + + /* XXX check if program is legal, within limits */ + return GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index 10629e9225..2281d10e99 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -41,7 +41,6 @@ #include "pipe/p_defines.h" #include "st_context.h" #include "st_cb_queryobj.h" -#include "st_public.h" static struct gl_query_object * diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index d82b2a2035..42a1377809 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -47,7 +47,6 @@ #include "st_draw.h" #include "draw/draw_context.h" #include "draw/draw_pipe.h" -#include "shader/prog_instruction.h" #include "vbo/vbo.h" diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 6fa7bb64f2..6b1fdf3ecd 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -40,15 +40,13 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_tile.h" #include "st_debug.h" #include "st_context.h" -#include "st_cb_bitmap.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" -#include "st_format.h" #include "st_public.h" #include "st_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_cb_strings.c b/src/mesa/state_tracker/st_cb_strings.c index bb931f17c4..0fcb427f30 100644 --- a/src/mesa/state_tracker/st_cb_strings.c +++ b/src/mesa/state_tracker/st_cb_strings.c @@ -33,13 +33,13 @@ #include "main/glheader.h" #include "main/macros.h" -#include "main/version.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" +#include "util/u_string.h" #include "st_context.h" #include "st_cb_strings.h" -#define ST_VERSION_STRING "0.3" +#define ST_VERSION_STRING "0.4" static const GLubyte * st_get_string(GLcontext * ctx, GLenum name) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index f01053cdac..13f050900a 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -31,15 +31,14 @@ #include "main/convolve.h" #endif #include "main/enums.h" +#include "main/fbobject.h" #include "main/formats.h" #include "main/image.h" #include "main/imports.h" #include "main/macros.h" #include "main/mipmap.h" -#include "main/pixel.h" #include "main/texcompress.h" #include "main/texfetch.h" -#include "main/texformat.h" #include "main/texgetimage.h" #include "main/teximage.h" #include "main/texobj.h" @@ -58,7 +57,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_shader_tokens.h" #include "util/u_tile.h" #include "util/u_blit.h" @@ -544,22 +543,15 @@ st_TexImage(GLcontext * ctx, _mesa_align_free(texImage->Data); } - if (width == 0 || height == 0 || depth == 0) { - /* stop after freeing old image */ - return; - } - - /* If this is the only mipmap level in the texture, could call - * bmBufferData with NULL data to free the old block and avoid - * waiting on any outstanding fences. + /* + * See if the new image is somehow incompatible with the existing + * mipmap. If so, free the old mipmap. */ if (stObj->pt) { if (stObj->teximage_realloc || level > (GLint) stObj->pt->last_level || - (stObj->pt->last_level == level && - stObj->pt->target != PIPE_TEXTURE_CUBE && - !st_texture_match_image(stObj->pt, &stImage->base, - stImage->face, stImage->level))) { + !st_texture_match_image(stObj->pt, &stImage->base, + stImage->face, stImage->level)) { DBG("release it\n"); pipe_texture_reference(&stObj->pt, NULL); assert(!stObj->pt); @@ -567,6 +559,11 @@ st_TexImage(GLcontext * ctx, } } + if (width == 0 || height == 0 || depth == 0) { + /* stop after freeing old image */ + return; + } + if (!stObj->pt) { guess_and_alloc_texture(ctx->st, stObj, stImage); if (!stObj->pt) { @@ -687,9 +684,11 @@ st_TexImage(GLcontext * ctx, { char *dst = texImage->Data; const char *src = pixels; - int i; + GLuint i, bw, bh, lines; + _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); + lines = (height + bh - 1) / bh; - for(i = 0; i < height; ++i) + for(i = 0; i < lines; ++i) { memcpy(dst, src, srcImageStride); dst += dstRowStride; @@ -1368,33 +1367,64 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level, } + +/** + * If the format of the src renderbuffer and the format of the dest + * texture are compatible (in terms of blitting), return a TGSI writemask + * to be used during the blit. + * If the src/dest are incompatible, return 0. + */ static unsigned -compatible_src_dst_formats(const struct gl_renderbuffer *src, +compatible_src_dst_formats(GLcontext *ctx, + const struct gl_renderbuffer *src, const struct gl_texture_image *dst) { - const GLenum srcFormat = _mesa_get_format_base_format(src->Format); - const GLenum dstLogicalFormat = _mesa_get_format_base_format(dst->TexFormat); + /* Get logical base formats for the src and dest. + * That is, use the user-requested formats and not the actual, device- + * chosen formats. + * For example, the user may have requested an A8 texture but the + * driver may actually be using an RGBA texture format. When we + * copy/blit to that texture, we only want to copy the Alpha channel + * and not the RGB channels. + * + * Similarly, when the src FBO was created an RGB format may have been + * requested but the driver actually chose an RGBA format. In that case, + * we don't want to copy the undefined Alpha channel to the dest texture + * (it should be 1.0). + */ + const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); + const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); - if (srcFormat == dstLogicalFormat) { + /** + * XXX when we have red-only and red/green renderbuffers we'll need + * to add more cases here (or implement a general-purpose routine that + * queries the existance of the R,G,B,A channels in the src and dest). + */ + if (srcFormat == dstFormat) { /* This is the same as matching_base_formats, which should * always pass, as it did previously. */ return TGSI_WRITEMASK_XYZW; } - else if (srcFormat == GL_RGBA && - dstLogicalFormat == GL_RGB) { - /* Add a single special case to cope with RGBA->RGB transfers, - * setting A to 1.0 to cope with situations where the RGB - * destination is actually stored as RGBA. + else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { + /* Make sure that A in the dest is 1. The actual src format + * may be RGBA and have undefined A values. + */ + return TGSI_WRITEMASK_XYZ; + } + else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { + /* Make sure that A in the dest is 1. The actual dst format + * may be RGBA and will need A=1 to provide proper alpha values + * when sampled later. */ - return TGSI_WRITEMASK_XYZ; /* A ==> 1.0 */ + return TGSI_WRITEMASK_XYZ; } else { if (ST_DEBUG & DEBUG_FALLBACK) debug_printf("%s failed for src %s, dst %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(srcFormat), - _mesa_lookup_enum_by_nr(dstLogicalFormat)); + _mesa_lookup_enum_by_nr(dstFormat)); /* Otherwise fail. */ @@ -1505,7 +1535,7 @@ st_copy_texsubimage(GLcontext *ctx, matching_base_formats = (_mesa_get_format_base_format(strb->Base.Format) == _mesa_get_format_base_format(texImage->TexFormat)); - format_writemask = compatible_src_dst_formats(&strb->Base, texImage); + format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); if (ctx->_ImageTransferState == 0x0) { diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c index ab11c5b4fe..b29191abef 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/mesa/state_tracker/st_cb_viewport.c @@ -27,14 +27,11 @@ #include "main/glheader.h" #include "st_context.h" -#include "st_public.h" #include "st_cb_viewport.h" #include "pipe/p_context.h" -#include "pipe/p_inlines.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" static void st_viewport(GLcontext * ctx, GLint x, GLint y, diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index e4f18c842c..8f6a0c2423 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -27,11 +27,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/extensions.h" -#include "main/matrix.h" -#include "main/buffers.h" -#include "main/scissor.h" -#include "main/viewport.h" #include "vbo/vbo.h" #include "shader/shader_api.h" #include "glapi/glapi.h" @@ -48,7 +43,7 @@ #include "st_cb_drawpixels.h" #include "st_cb_rasterpos.h" #endif -#ifdef FEATURE_OES_draw_texture +#if FEATURE_OES_draw_texture #include "st_cb_drawtex.h" #endif #include "st_cb_fbo.h" @@ -68,8 +63,8 @@ #include "st_gen_mipmap.h" #include "st_program.h" #include "pipe/p_context.h" +#include "util/u_inlines.h" #include "draw/draw_context.h" -#include "cso_cache/cso_cache.h" #include "cso_cache/cso_context.h" @@ -209,7 +204,7 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_bitmap(st); st_destroy_drawpix(st); #endif -#ifdef FEATURE_OES_draw_texture +#if FEATURE_OES_draw_texture st_destroy_drawtex(st); #endif @@ -218,8 +213,8 @@ static void st_destroy_context_priv( struct st_context *st ) } for (i = 0; i < Elements(st->state.constants); i++) { - if (st->state.constants[i].buffer) { - pipe_buffer_reference(&st->state.constants[i].buffer, NULL); + if (st->state.constants[i]) { + pipe_buffer_reference(&st->state.constants[i], NULL); } } @@ -330,6 +325,11 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_drawpixels_functions(functions); st_init_rasterpos_functions(functions); #endif + +#if FEATURE_OES_draw_texture + st_init_drawtex_functions(functions); +#endif + st_init_fbo_functions(functions); #if FEATURE_feedback st_init_feedback_functions(functions); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 831909a3f8..50e98d7146 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -92,7 +92,7 @@ struct st_context struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS]; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[2]; + struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; struct pipe_texture *sampler_texture[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; @@ -159,7 +159,7 @@ struct st_context /** for glDraw/CopyPixels */ struct { struct st_fragment_program *z_shader; - struct st_vertex_program *vert_shaders[2]; + void *vert_shaders[2]; /**< ureg shaders */ } drawpix; /** for glClear */ diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index e54f21be60..e1dcb154c1 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -55,7 +55,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" static GLuint double_types[4] = { @@ -365,6 +365,7 @@ setup_interleaved_attribs(GLcontext *ctx, velements[attr].src_offset = (unsigned) (arrays[mesaAttr]->Ptr - offset0); + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = 0; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = @@ -454,6 +455,7 @@ setup_non_interleaved_attribs(GLcontext *ctx, /* common-case setup */ vbuffer[attr].stride = stride; /* in bytes */ vbuffer[attr].max_index = max_index; + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = attr; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format @@ -522,7 +524,6 @@ st_draw_vbo(GLcontext *ctx, struct pipe_context *pipe = ctx->st->pipe; const struct st_vertex_program *vp; const struct st_vp_varient *vpv; - const struct pipe_shader_state *vs; struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; GLuint attr; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; @@ -530,6 +531,9 @@ st_draw_vbo(GLcontext *ctx, GLboolean userSpace = GL_FALSE; GLboolean vertDataEdgeFlags; + /* Mesa core state should have been validated already */ + assert(ctx->NewState == 0x0); + /* Gallium probably doesn't want this in some cases. */ if (!index_bounds_valid) if (!vbo_all_varyings_in_vbos(arrays)) @@ -550,7 +554,6 @@ st_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; vpv = ctx->st->vp_varient; - vs = &vpv->state; #if 0 if (MESA_VERBOSE & VERBOSE_GLSL) { diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index cfc0caac98..75ad1a97cf 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" -#include "shader/prog_uniform.h" #include "vbo/vbo.h" @@ -40,7 +39,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "draw/draw_private.h" #include "draw/draw_context.h" @@ -177,6 +176,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* common-case setup */ vbuffers[attr].stride = arrays[mesaAttr]->StrideB; /* in bytes */ vbuffers[attr].max_index = max_index; + velements[attr].instance_divisor = 0; velements[attr].vertex_buffer_index = attr; velements[attr].nr_components = arrays[mesaAttr]->Size; velements[attr].src_format = @@ -239,11 +239,11 @@ st_feedback_draw_vbo(GLcontext *ctx, /* map constant buffers */ mapped_constants = pipe_buffer_map(pipe->screen, - st->state.constants[PIPE_SHADER_VERTEX].buffer, + st->state.constants[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, 0, mapped_constants, - st->state.constants[PIPE_SHADER_VERTEX].buffer->size); + st->state.constants[PIPE_SHADER_VERTEX]->size); /* draw here */ @@ -253,7 +253,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* unmap constant buffers */ - pipe_buffer_unmap(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX].buffer); + pipe_buffer_unmap(pipe->screen, st->state.constants[PIPE_SHADER_VERTEX]); /* * unmap vertex/index buffers diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index cf31a0c06e..d5f5854661 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/context.h" -#include "main/extensions.h" #include "main/macros.h" #include "pipe/p_context.h" @@ -157,6 +156,7 @@ void st_init_extensions(struct st_context *st) * Extensions that are supported by all Gallium drivers: */ ctx->Extensions.ARB_copy_buffer = GL_TRUE; + ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.ARB_fragment_program = GL_TRUE; ctx->Extensions.ARB_map_buffer_range = GL_TRUE; ctx->Extensions.ARB_multisample = GL_TRUE; @@ -177,6 +177,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_blend_subtract = GL_TRUE; ctx->Extensions.EXT_framebuffer_blit = GL_TRUE; ctx->Extensions.EXT_framebuffer_object = GL_TRUE; + ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE; ctx->Extensions.EXT_fog_coord = GL_TRUE; ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE; ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; @@ -196,6 +197,10 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.NV_texgen_reflection = GL_TRUE; ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; +#if FEATURE_OES_draw_texture + ctx->Extensions.OES_draw_texture = GL_TRUE; +#endif + ctx->Extensions.SGI_color_matrix = GL_TRUE; ctx->Extensions.SGIS_generate_mipmap = GL_TRUE; @@ -319,4 +324,14 @@ void st_init_extensions(struct st_context *st) if (st->pipe->render_condition) { ctx->Extensions.NV_conditional_render = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) { + ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; + } + +#if 0 /* not yet */ + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) { + ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE; + } +#endif } diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index d00b67a279..3ffc2aee2a 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -35,7 +35,6 @@ #include "main/imports.h" #include "main/context.h" #include "main/texstore.h" -#include "main/texformat.h" #include "main/enums.h" #include "main/macros.h" @@ -288,6 +287,8 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat) return MESA_FORMAT_XRGB8888; case PIPE_FORMAT_B8G8R8A8_UNORM: return MESA_FORMAT_ARGB8888_REV; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return MESA_FORMAT_XRGB8888_REV; case PIPE_FORMAT_A1R5G5B5_UNORM: return MESA_FORMAT_ARGB1555; case PIPE_FORMAT_A4R4G4B4_UNORM: diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c index a5d1ae3b03..4e225a123c 100644 --- a/src/mesa/state_tracker/st_framebuffer.c +++ b/src/mesa/state_tracker/st_framebuffer.c @@ -30,15 +30,12 @@ #include "main/buffers.h" #include "main/context.h" #include "main/framebuffer.h" -#include "main/matrix.h" #include "main/renderbuffer.h" -#include "main/scissor.h" -#include "main/viewport.h" #include "st_context.h" #include "st_cb_fbo.h" #include "st_public.h" #include "pipe/p_defines.h" -#include "pipe/p_context.h" +#include "util/u_inlines.h" struct st_framebuffer * @@ -57,7 +54,7 @@ st_create_framebuffer( const __GLcontextModes *visual, if (visual->sampleBuffers) samples = visual->samples; - _mesa_initialize_framebuffer(&stfb->Base, visual); + _mesa_initialize_window_framebuffer(&stfb->Base, visual); if (visual->doubleBufferMode) { struct gl_renderbuffer *rb diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 2c283d464a..f67d7b4cb5 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_gen_mipmap.h" #include "util/u_math.h" @@ -46,9 +46,7 @@ #include "st_debug.h" #include "st_context.h" -#include "st_draw.h" #include "st_gen_mipmap.h" -#include "st_program.h" #include "st_texture.h" #include "st_cb_texture.h" #include "st_inlines.h" diff --git a/src/mesa/state_tracker/st_inlines.h b/src/mesa/state_tracker/st_inlines.h index a41cfeb96f..e105870bc7 100644 --- a/src/mesa/state_tracker/st_inlines.h +++ b/src/mesa/state_tracker/st_inlines.h @@ -36,7 +36,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "pipe/p_state.h" #include "st_context.h" @@ -126,6 +126,16 @@ st_no_flush_pipe_buffer_write(struct st_context *st, } static INLINE void +st_no_flush_pipe_buffer_write_nooverlap(struct st_context *st, + struct pipe_buffer *buf, + unsigned int offset, + unsigned int size, + const void * data) +{ + pipe_buffer_write_nooverlap(st->pipe->screen, buf, offset, size, data); +} + +static INLINE void st_cond_flush_pipe_buffer_read(struct st_context *st, struct pipe_buffer *buf, unsigned int offset, diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index 4830a8f383..537a6a8648 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -34,11 +34,12 @@ #include "pipe/p_compiler.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" +#include "pipe/p_context.h" #include "tgsi/tgsi_ureg.h" #include "st_mesa_to_tgsi.h" +#include "st_context.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" -#include "shader/prog_print.h" #include "util/u_debug.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -48,6 +49,10 @@ struct label { unsigned token; }; + +/** + * Intermediate state used during shader translation. + */ struct st_translate { struct ureg_program *ureg; @@ -178,13 +183,13 @@ src_register( struct st_translate *t, t->temps[index] = ureg_DECL_temporary( t->ureg ); return ureg_src(t->temps[index]); - case PROGRAM_STATE_VAR: case PROGRAM_NAMED_PARAM: case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: ASSERT(index >= 0); return t->constants[index]; + case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: /* ie, immediate */ if (index < 0) return ureg_DECL_constant( t->ureg, 0 ); @@ -667,6 +672,22 @@ compile_instruction( } } +/** + * Emit the TGSI instructions to adjust the WPOS pixel center convention + */ +static void +emit_adjusted_wpos( struct st_translate *t, + const struct gl_program *program, GLfloat value) +{ + struct ureg_program *ureg = t->ureg; + struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); + struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; + + ureg_ADD(ureg, ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y), + wpos_input, ureg_imm1f(ureg, value)); + + t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); +} /** * Emit the TGSI instructions for inverting the WPOS y coordinate. @@ -692,12 +713,17 @@ emit_inverted_wpos( struct st_translate *t, winSizeState); struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst ); - struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); + struct ureg_dst wpos_temp; struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; /* MOV wpos_temp, input[wpos] */ - ureg_MOV( ureg, wpos_temp, wpos_input ); + if (wpos_input.File == TGSI_FILE_TEMPORARY) + wpos_temp = ureg_dst(wpos_input); + else { + wpos_temp = ureg_DECL_temporary( ureg ); + ureg_MOV( ureg, wpos_temp, wpos_input ); + } /* SUB wpos_temp.y, winsize_const, wpos_input */ @@ -736,6 +762,7 @@ emit_face_var( struct st_translate *t, t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); } + static void emit_edgeflags( struct st_translate *t, const struct gl_program *program ) @@ -747,6 +774,7 @@ emit_edgeflags( struct st_translate *t, ureg_MOV( ureg, edge_dst, edge_src ); } + /** * Translate Mesa program to TGSI format. * \param program the program to translate @@ -764,7 +792,7 @@ emit_edgeflags( struct st_translate *t, * \param outputSemanticIndex the semantic index (ex: which texcoord) for * each output * - * \return array of translated tokens, caller's responsibility to free + * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY */ enum pipe_error st_translate_mesa_program( @@ -785,6 +813,7 @@ st_translate_mesa_program( { struct st_translate translate, *t; unsigned i; + enum pipe_error ret = PIPE_OK; t = &translate; memset(t, 0, sizeof *t); @@ -802,18 +831,72 @@ st_translate_mesa_program( * Declare input attributes. */ if (procType == TGSI_PROCESSOR_FRAGMENT) { + struct gl_fragment_program* fp = (struct gl_fragment_program*)program; for (i = 0; i < numInputs; i++) { - t->inputs[i] = ureg_DECL_fs_input(ureg, - inputSemanticName[i], - inputSemanticIndex[i], - interpMode[i]); + if (program->InputFlags[0] & PROG_PARAM_BIT_CYL_WRAP) { + t->inputs[i] = ureg_DECL_fs_input_cyl(ureg, + inputSemanticName[i], + inputSemanticIndex[i], + interpMode[i], + TGSI_CYLINDRICAL_WRAP_X); + } + else { + t->inputs[i] = ureg_DECL_fs_input(ureg, + inputSemanticName[i], + inputSemanticIndex[i], + interpMode[i]); + } } if (program->InputsRead & FRAG_BIT_WPOS) { /* Must do this after setting up t->inputs, and before * emitting constant references, below: */ - emit_inverted_wpos( t, program ); + struct pipe_screen* pscreen = st_context(ctx)->pipe->screen; + boolean invert = FALSE; + + if (fp->OriginUpperLeft) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + invert = TRUE; + } + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) + ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) + invert = TRUE; + else + assert(0); + } + + if (fp->PixelCenterInteger) { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) + emit_adjusted_wpos(t, program, invert ? 0.5f : -0.5f); + else + assert(0); + } + else { + if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { + } + else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { + ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); + emit_adjusted_wpos(t, program, invert ? -0.5f : 0.5f); + } + else + assert(0); + } + + /* we invert after adjustment so that we avoid the MOV to temporary, + * and reuse the adjustment ADD instead */ + if (invert) + emit_inverted_wpos(t, program); } if (program->InputsRead & FRAG_BIT_FACE) { @@ -888,8 +971,10 @@ st_translate_mesa_program( t->constants = CALLOC( program->Parameters->NumParameters, sizeof t->constants[0] ); - if (t->constants == NULL) + if (t->constants == NULL) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; + } for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { @@ -956,8 +1041,6 @@ st_translate_mesa_program( t->insn[t->labels[i].branch_target] ); } - return PIPE_OK; - out: FREE(t->insn); FREE(t->labels); @@ -967,7 +1050,7 @@ out: debug_printf("%s: translate error flag set\n", __FUNCTION__); } - return PIPE_ERROR_OUT_OF_MEMORY; + return ret; } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6a869fae90..21ad6fef2b 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -44,7 +44,6 @@ #include "st_debug.h" #include "st_context.h" -#include "st_atom.h" #include "st_program.h" #include "st_mesa_to_tgsi.h" #include "cso_cache/cso_context.h" @@ -270,24 +269,20 @@ fail: /** * Translate a Mesa fragment shader into a TGSI shader. - * \param inputMapping to map fragment program input registers to TGSI - * input slots * \return pointer to cached pipe_shader object. */ void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *stfp, - const GLuint inputMapping[]) + struct st_fragment_program *stfp ) { struct pipe_context *pipe = st->pipe; GLuint outputMapping[FRAG_RESULT_MAX]; - GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; + GLuint inputMapping[FRAG_ATTRIB_MAX]; GLuint interpMode[16]; /* XXX size? */ GLuint attr; enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; struct ureg_program *ureg; - GLuint vslot = 0; uint fs_num_inputs = 0; @@ -295,24 +290,14 @@ st_translate_fragment_program(struct st_context *st, ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; uint fs_num_outputs = 0; - /* which vertex output goes to the first fragment input: */ - if (inputsRead & FRAG_BIT_WPOS) - vslot = 0; - else - vslot = 1; - /* * Convert Mesa program inputs to TGSI input register semantics. */ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) { if (inputsRead & (1 << attr)) { - const GLuint slot = fs_num_inputs; - - defaultInputMapping[attr] = slot; + const GLuint slot = fs_num_inputs++; - stfp->input_map[slot] = vslot++; - - fs_num_inputs++; + inputMapping[attr] = slot; switch (attr) { case FRAG_ATTRIB_WPOS: @@ -340,6 +325,16 @@ st_translate_fragment_program(struct st_context *st, stfp->input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; + case FRAG_ATTRIB_PNTC: + /* This is a hack. We really need a new semantic label for + * point coord. The draw module needs to know which fragment + * shader input is the point coord attribute so that it can set + * up the right vertex attribute values. + */ + stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + stfp->input_semantic_index[slot] = 0; + interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; + break; /* In most cases, there is nothing special about these * inputs, so adopt a convention to use the generic @@ -364,7 +359,6 @@ st_translate_fragment_program(struct st_context *st, case FRAG_ATTRIB_TEX5: case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: - case FRAG_ATTRIB_PNTC: case FRAG_ATTRIB_VAR0: default: /* Actually, let's try and zero-base this just for @@ -377,6 +371,9 @@ st_translate_fragment_program(struct st_context *st, break; } } + else { + inputMapping[attr] = -1; + } } /* @@ -418,9 +415,6 @@ st_translate_fragment_program(struct st_context *st, } } - if (!inputMapping) - inputMapping = defaultInputMapping; - ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); if (ureg == NULL) return; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 6b9a9226df..d9822e50f5 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -52,12 +52,6 @@ struct st_fragment_program struct gl_fragment_program Base; GLuint serialNo; - GLuint input_to_slot[FRAG_ATTRIB_MAX]; /**< Maps FRAG_ATTRIB_x to slot */ - GLuint num_input_slots; - - /** map FP input back to VP output */ - GLuint input_map[PIPE_MAX_SHADER_INPUTS]; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; @@ -171,8 +165,7 @@ st_reference_fragprog(struct st_context *st, extern void st_translate_fragment_program(struct st_context *st, - struct st_fragment_program *fp, - const GLuint inputMapping[]); + struct st_fragment_program *fp); /* Called after program string change, discard all previous diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 8a3e4cd3ac..5a45c4358a 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -35,14 +35,13 @@ #include "main/texfetch.h" #include "main/teximage.h" #include "main/texobj.h" -#include "main/texstore.h" #undef Elements /* fix re-defined macro warning */ #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" +#include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_rect.h" #include "util/u_math.h" diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index 0827b3db9e..a8b22c548f 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -220,11 +220,11 @@ #if defined(DO_ATTRIBS) /* compute attributes at left-most fragment */ - span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5, iy + 0.5, wPlane); + span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5F, iy + 0.5F, wPlane); ATTRIB_LOOP_BEGIN GLuint c; for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = solve_plane(ix + 0.5, iy + 0.5, attrPlane[attr][c]); + span.attrStart[attr][c] = solve_plane(ix + 0.5F, iy + 0.5F, attrPlane[attr][c]); } ATTRIB_LOOP_END #endif @@ -328,11 +328,11 @@ #if defined(DO_ATTRIBS) /* compute attributes at left-most fragment */ - span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5, wPlane); + span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5F, wPlane); ATTRIB_LOOP_BEGIN GLuint c; for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5, attrPlane[attr][c]); + span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5F, attrPlane[attr][c]); } ATTRIB_LOOP_END #endif diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c index 0e0876efcb..2dd9ca6348 100644 --- a/src/mesa/swrast/s_accum.c +++ b/src/mesa/swrast/s_accum.c @@ -27,7 +27,6 @@ #include "main/context.h" #include "main/macros.h" #include "main/imports.h" -#include "main/fbobject.h" #include "s_accum.h" #include "s_context.h" @@ -38,7 +37,7 @@ /* XXX this would have to change for accum buffers with more or less * than 16 bits per color channel. */ -#define ACCUM_SCALE16 32767.0 +#define ACCUM_SCALE16 32767.0F /* diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c index 5761bb00b4..509477433a 100644 --- a/src/mesa/swrast/s_alpha.c +++ b/src/mesa/swrast/s_alpha.c @@ -146,8 +146,8 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span) ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); } else { - const GLfloat alphaStep = span->alphaStep; - GLfloat alpha = span->alpha; + const GLfloat alphaStep = FixedToFloat(span->alphaStep); + GLfloat alpha = FixedToFloat(span->alpha); const GLfloat ref = ctx->Color.AlphaRef; ALPHA_TEST(alpha, alpha += alphaStep); } diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index e88ff19123..05da64de3a 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -23,7 +23,6 @@ #include "main/colormac.h" #include "main/context.h" #include "main/macros.h" -#include "shader/program.h" #include "shader/atifragshader.h" #include "swrast/s_atifragshader.h" @@ -83,10 +82,11 @@ apply_swizzle(GLfloat values[4], GLuint swizzle) break; case GL_SWIZZLE_STQ_DQ_ATI: /* make sure q is not 0 to avoid problems later with infinite values (texture lookup)? */ - if (q == 0.0F) q = 0.000000001; + if (q == 0.0F) + q = 0.000000001F; values[0] = s / q; values[1] = t / q; - values[2] = 1 / q; + values[2] = 1.0 / q; break; } values[3] = 0.0; @@ -172,27 +172,27 @@ apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val) val[i] = 8 * val[i]; break; case GL_HALF_BIT_ATI: - val[i] = val[i] * 0.5; + val[i] = val[i] * 0.5F; break; case GL_QUARTER_BIT_ATI: - val[i] = val[i] * 0.25; + val[i] = val[i] * 0.25F; break; case GL_EIGHTH_BIT_ATI: - val[i] = val[i] * 0.125; + val[i] = val[i] * 0.125F; break; } if (has_sat) { - if (val[i] < 0.0) - val[i] = 0; - else if (val[i] > 1.0) - val[i] = 1.0; + if (val[i] < 0.0F) + val[i] = 0.0F; + else if (val[i] > 1.0F) + val[i] = 1.0F; } else { - if (val[i] < -8.0) - val[i] = -8.0; - else if (val[i] > 8.0) - val[i] = 8.0; + if (val[i] < -8.0F) + val[i] = -8.0F; + else if (val[i] > 8.0F) + val[i] = 8.0F; } } } diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index 46c63aa645..59e26e9ea3 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -33,7 +33,6 @@ #include "main/condrender.h" #include "main/image.h" #include "main/macros.h" -#include "main/pixel.h" #include "s_context.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index f9092c215a..0d4680db9f 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -149,26 +149,26 @@ _swrast_update_polygon( GLcontext *ctx ) if (ctx->Polygon.CullFlag) { switch (ctx->Polygon.CullFaceMode) { case GL_BACK: - backface_sign = -1.0; + backface_sign = -1.0F; break; case GL_FRONT: - backface_sign = 1.0; + backface_sign = 1.0F; break; case GL_FRONT_AND_BACK: /* fallthrough */ default: - backface_sign = 0.0; + backface_sign = 0.0F; } } else { - backface_sign = 0.0; + backface_sign = 0.0F; } SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign; /* This is for front/back-face determination, but not for culling */ SWRAST_CONTEXT(ctx)->_BackfaceSign - = (ctx->Polygon.FrontFace == GL_CW) ? -1.0 : 1.0; + = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F; } diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 986b6aff4f..e881d1be30 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -28,11 +28,9 @@ #include "main/colormac.h" #include "main/condrender.h" #include "main/convolve.h" -#include "main/histogram.h" #include "main/image.h" #include "main/macros.h" #include "main/imports.h" -#include "main/pixel.h" #include "s_context.h" #include "s_depth.h" diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index c37a54eb3e..ac5dae2148 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -28,7 +28,6 @@ #include "main/formats.h" #include "main/macros.h" #include "main/imports.h" -#include "main/fbobject.h" #include "s_depth.h" #include "s_context.h" @@ -498,17 +497,24 @@ depth_test_span32( GLcontext *ctx, GLuint n, return passed; } -/* Apply ARB_depth_clamp to span of fragments. */ + + +/** + * Clamp fragment Z values to the depth near/far range (glDepthRange()). + * This is used when GL_ARB_depth_clamp/GL_DEPTH_CLAMP is turned on. + * In that case, vertexes are not clipped against the near/far planes + * so rasterization will produce fragment Z values outside the usual + * [0,1] range. + */ void _swrast_depth_clamp_span( GLcontext *ctx, SWspan *span ) { struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_renderbuffer *rb = fb->_DepthBuffer; const GLuint count = span->end; - GLuint *zValues = span->array->z; - GLuint min, max; + GLint *zValues = (GLint *) span->array->z; /* sign change */ + GLint min, max; GLfloat min_f, max_f; - int i; + GLuint i; if (ctx->Viewport.Near < ctx->Viewport.Far) { min_f = ctx->Viewport.Near; @@ -518,15 +524,21 @@ _swrast_depth_clamp_span( GLcontext *ctx, SWspan *span ) max_f = ctx->Viewport.Near; } - if (rb->DataType == GL_UNSIGNED_SHORT) { - CLAMPED_FLOAT_TO_USHORT(min, min_f); - CLAMPED_FLOAT_TO_USHORT(max, max_f); - } else { - assert(rb->DataType == GL_UNSIGNED_INT); - min = FLOAT_TO_UINT(min_f); - max = FLOAT_TO_UINT(max_f); - } - + /* Convert floating point values in [0,1] to device Z coordinates in + * [0, DepthMax]. + * ex: If the the Z buffer has 24 bits, DepthMax = 0xffffff. + * + * XXX this all falls apart if we have 31 or more bits of Z because + * the triangle rasterization code produces unsigned Z values. Negative + * vertex Z values come out as large fragment Z uints. + */ + min = (GLint) (min_f * fb->_DepthMaxF); + max = (GLint) (max_f * fb->_DepthMaxF); + if (max < 0) + max = 0x7fffffff; /* catch over flow for 30-bit z */ + + /* Note that we do the comparisons here using signed integers. + */ for (i = 0; i < count; i++) { if (zValues[i] < min) zValues[i] = min; diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 55a4c4c3c6..248d6cc1c0 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -31,7 +31,6 @@ #include "main/image.h" #include "main/macros.h" #include "main/imports.h" -#include "main/pixel.h" #include "main/state.h" #include "s_context.h" diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 47ed25ee10..2e6066983d 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -25,7 +25,6 @@ #include "main/glheader.h" #include "main/colormac.h" #include "main/context.h" -#include "main/enums.h" #include "main/feedback.h" #include "main/macros.h" diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index 77ed0cfef9..0472bbf553 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -172,14 +172,14 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) /* compute (scaled) fog color */ if (span->array->ChanType == GL_UNSIGNED_BYTE) { - rFog = ctx->Fog.Color[RCOMP] * 255.0; - gFog = ctx->Fog.Color[GCOMP] * 255.0; - bFog = ctx->Fog.Color[BCOMP] * 255.0; + rFog = ctx->Fog.Color[RCOMP] * 255.0F; + gFog = ctx->Fog.Color[GCOMP] * 255.0F; + bFog = ctx->Fog.Color[BCOMP] * 255.0F; } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - rFog = ctx->Fog.Color[RCOMP] * 65535.0; - gFog = ctx->Fog.Color[GCOMP] * 65535.0; - bFog = ctx->Fog.Color[BCOMP] * 65535.0; + rFog = ctx->Fog.Color[RCOMP] * 65535.0F; + gFog = ctx->Fog.Color[GCOMP] * 65535.0F; + bFog = ctx->Fog.Color[BCOMP] * 65535.0F; } else { rFog = ctx->Fog.Color[RCOMP]; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index a22d34415d..d31da4c402 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -25,7 +25,6 @@ #include "main/glheader.h" #include "main/colormac.h" #include "main/context.h" -#include "main/texstate.h" #include "shader/prog_instruction.h" #include "s_fragprog.h" @@ -145,12 +144,22 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, const struct gl_fragment_program *program, const SWspan *span, GLuint col) { + GLfloat *wpos = span->array->attribs[FRAG_ATTRIB_WPOS][col]; + if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero(machine->Temporaries, MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); } + /* ARB_fragment_coord_conventions */ + if (program->OriginUpperLeft) + wpos[1] = ctx->DrawBuffer->Height - 1 - wpos[1]; + if (!program->PixelCenterInteger) { + wpos[0] += 0.5F; + wpos[1] += 0.5F; + } + /* Setup pointer to input attributes */ machine->Attribs = span->array->attribs; @@ -163,7 +172,7 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { /* Store front/back facing value */ - machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0 - span->facing; + machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0F - span->facing; } machine->CurElement = col; diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index 23cb9b57ef..5411229d70 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -29,7 +29,6 @@ #include "main/macros.h" #include "s_aaline.h" #include "s_context.h" -#include "s_depth.h" #include "s_feedback.h" #include "s_lines.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 50ec2063a5..a9a704a16e 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -27,7 +27,6 @@ #include "main/colormac.h" #include "main/context.h" #include "main/macros.h" -#include "main/texstate.h" #include "s_context.h" #include "s_feedback.h" #include "s_points.h" @@ -126,16 +125,16 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) GLfloat s, r, dsdx; /* texcoord / pointcoord interpolants */ - s = 0.0; - dsdx = 1.0 / size; + s = 0.0F; + dsdx = 1.0F / size; if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) { - dtdy = 1.0 / size; - t0 = 0.5 * dtdy; + dtdy = 1.0F / size; + t0 = 0.5F * dtdy; } else { /* GL_UPPER_LEFT */ - dtdy = -1.0 / size; - t0 = 1.0 + 0.5 * dtdy; + dtdy = -1.0F / size; + t0 = 1.0F + 0.5F * dtdy; } ATTRIB_LOOP_BEGIN diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 44a11cd6dd..94fb974eab 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -33,7 +33,6 @@ #include "main/image.h" #include "main/macros.h" #include "main/imports.h" -#include "main/pixel.h" #include "main/state.h" #include "s_context.h" diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 4ea9547cd9..905cf3d550 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -645,7 +645,7 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) { GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; GLuint i; - const GLfloat zScale = 1.0 / ctx->DrawBuffer->_DepthMaxF; + const GLfloat zScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; GLfloat w, dw; if (span->arrayMask & SPAN_XY) { @@ -1316,6 +1316,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) ASSERT(span->end <= MAX_WIDTH); + /* Depth bounds test */ + if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { + if (!_swrast_depth_bounds_test(ctx, span)) { + return; + } + } + #ifdef DEBUG /* Make sure all fragments are within window bounds */ if (span->arrayMask & SPAN_XY) { diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 889164b986..95e2c082ba 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -29,7 +29,6 @@ #include "main/colormac.h" #include "main/image.h" #include "main/imports.h" -#include "main/pixel.h" #include "shader/prog_instruction.h" #include "s_context.h" @@ -317,18 +316,18 @@ texture_combine( GLcontext *ctx, GLuint unit, GLuint n, /* (a * b) + (c * d) - 0.5 */ for (i = 0; i < n; i++) { rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + - arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5) * scaleRGB; + arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB; rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + - arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5) * scaleRGB; + arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB; rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + - arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5) * scaleRGB; + arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB; } } else { for (i = 0; i < n; i++) { - rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * scaleRGB; - rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * scaleRGB; - rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * scaleRGB; + rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB; } } break; @@ -386,11 +385,11 @@ texture_combine( GLcontext *ctx, GLuint unit, GLuint n, case GL_MODULATE_SIGNED_ADD_ATI: for (i = 0; i < n; i++) { rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + - arg1[i][RCOMP] - 0.5) * scaleRGB; + arg1[i][RCOMP] - 0.5F) * scaleRGB; rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + - arg1[i][GCOMP] - 0.5) * scaleRGB; + arg1[i][GCOMP] - 0.5F) * scaleRGB; rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + - arg1[i][BCOMP] - 0.5) * scaleRGB; + arg1[i][BCOMP] - 0.5F) * scaleRGB; } break; case GL_MODULATE_SUBTRACT_ATI: @@ -457,7 +456,7 @@ texture_combine( GLcontext *ctx, GLuint unit, GLuint n, for (i = 0; i < n; i++) { rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + arg2[i][ACOMP] * arg3[i][ACOMP] - - 0.5) * scaleA; + 0.5F) * scaleA; } } else { diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index 76b65cc755..ff7deecc39 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -445,7 +445,7 @@ clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, switch (wrapMode) { case GL_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ - fcol = CLAMP(coord - 0.5F, 0.0, max-1); + fcol = CLAMP(coord - 0.5F, 0.0F, max - 1); i0 = IFLOOR(fcol); i1 = i0 + 1; break; diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index c183b315b6..c01cf7d1f0 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -75,12 +75,6 @@ typedef struct { } SWvertex; -/** - * Fixed point data type. - */ -typedef int GLfixed; - - #define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0 diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index db21b4589d..5a14e595a0 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -38,7 +38,6 @@ #include "tnl.h" #include "t_context.h" #include "t_pipeline.h" -#include "t_vp_build.h" #include "vbo/vbo.h" diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index d31b29b9b4..812d712b07 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -29,15 +29,11 @@ #include "main/condrender.h" #include "main/context.h" #include "main/imports.h" -#include "main/state.h" #include "main/mtypes.h" #include "main/macros.h" #include "main/enums.h" #include "t_context.h" -#include "t_pipeline.h" -#include "t_vp_build.h" -#include "t_vertex.h" #include "tnl.h" @@ -112,6 +108,22 @@ convert_bgra_to_float(const struct gl_client_array *input, } } +static void +convert_half_to_float(const struct gl_client_array *input, + const GLubyte *ptr, GLfloat *fptr, + GLuint count, GLuint sz) +{ + GLuint i, j; + + for (i = 0; i < count; i++) { + GLhalfARB *in = (GLhalfARB *)ptr; + + for (j = 0; j < sz; j++) { + *fptr++ = _mesa_half_to_float(in[j]); + } + ptr += input->StrideB; + } +} /* Adjust pointer to point at first requested element, convert to * floating point, populate VB->AttribPtr[]. @@ -159,6 +171,9 @@ static void _tnl_import_array( GLcontext *ctx, case GL_DOUBLE: CONVERT(GLdouble, (GLfloat)); break; + case GL_HALF_FLOAT: + convert_half_to_float(input, ptr, fptr, count, sz); + break; default: assert(0); break; @@ -384,9 +399,12 @@ void _tnl_draw_prims( GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); const GLuint TEST_SPLIT = 0; const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES; - GLuint max_basevertex = prim->basevertex; + GLint max_basevertex = prim->basevertex; GLuint i; + /* Mesa core state should have been validated already */ + assert(ctx->NewState == 0x0); + if (!_mesa_check_conditional_render(ctx)) return; /* don't draw */ diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c index 01b30babb4..946b29e250 100644 --- a/src/mesa/tnl/t_pipeline.c +++ b/src/mesa/tnl/t_pipeline.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/context.h" #include "main/imports.h" -#include "main/state.h" #include "main/mtypes.h" #include "t_context.h" diff --git a/src/mesa/tnl/t_rasterpos.c b/src/mesa/tnl/t_rasterpos.c index 99b6787455..13b84a7d77 100644 --- a/src/mesa/tnl/t_rasterpos.c +++ b/src/mesa/tnl/t_rasterpos.c @@ -29,7 +29,6 @@ #include "main/feedback.h" #include "main/light.h" #include "main/macros.h" -#include "main/rastpos.h" #include "main/simple_list.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c index a52505b4b8..ab8ea60cf2 100644 --- a/src/mesa/tnl/t_vb_points.c +++ b/src/mesa/tnl/t_vb_points.c @@ -64,7 +64,7 @@ run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) for (i = 0; i < VB->Count; i++) { const GLfloat dist = FABSF(*eyeCoord); const GLfloat q = p0 + dist * (p1 + dist * p2); - const GLfloat atten = (q != 0.0) ? SQRTF(1.0 / q) : 1.0; + const GLfloat atten = (q != 0.0F) ? SQRTF(1.0F / q) : 1.0F; size[i][0] = pointSize * atten; /* clamping done in rasterization */ eyeCoord += eyeCoordStride; } diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 15a8a67b91..44b64b17d1 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -40,7 +40,6 @@ #include "shader/prog_statevars.h" #include "shader/prog_execute.h" #include "swrast/s_context.h" -#include "swrast/s_texfilter.h" #include "tnl/tnl.h" #include "tnl/t_context.h" @@ -204,13 +203,14 @@ vp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, * Called via ctx->Driver.ProgramStringNotify() after a new vertex program * string has been parsed. */ -void +GLboolean _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program) { /* No-op. * If we had derived anything from the program that was private to this * stage we'd recompute/validate it here. */ + return GL_TRUE; } diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index fe4209ae57..d3955873dc 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -383,7 +383,7 @@ static void adjust_input_ptrs( GLcontext *ctx, GLint diff) struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); struct tnl_clipspace_attr *a = vtx->attr; const GLuint count = vtx->attr_count; - int j; + GLuint j; diff -= 1; for (j=0; j<count; ++j) { diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index 9c66d3b019..2c0d1fef73 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -66,7 +66,7 @@ _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value ); extern void _tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value ); -extern void +extern GLboolean _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program); struct _mesa_prim; diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 75c32e0b9b..a5b0070bd3 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -249,17 +249,25 @@ void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ) void _vbo_DestroyContext( GLcontext *ctx ) { + struct vbo_context *vbo = vbo_context(ctx); + if (ctx->aelt_context) { _ae_destroy_context( ctx ); ctx->aelt_context = NULL; } - if (vbo_context(ctx)) { + if (vbo) { + GLuint i; + + for (i = 0; i < VBO_ATTRIB_MAX; i++) { + _mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL); + } + vbo_exec_destroy(ctx); #if FEATURE_dlist vbo_save_destroy(ctx); #endif - FREE(vbo_context(ctx)); + FREE(vbo); ctx->swtnl_im = NULL; } } diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index e168a89ea5..a057befed0 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -28,9 +28,6 @@ #include "main/api_arrayelt.h" #include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/macros.h" #include "main/mtypes.h" #include "main/vtxfmt.h" diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index f0a7eeadd0..8ee14be261 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -759,6 +759,7 @@ void vbo_use_buffer_objects(GLcontext *ctx) } /* Allocate a real buffer object now */ + _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL); exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target); ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); } @@ -803,8 +804,19 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) { struct gl_client_array *arrays = exec->vtx.arrays; + unsigned i; + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + + for (i = 0; i < 16; ++i) { + arrays[i ].BufferObj = NULL; + arrays[i + 16].BufferObj = NULL; + _mesa_reference_buffer_object(ctx, &arrays[i ].BufferObj, + vbo->legacy_currval[i].BufferObj); + _mesa_reference_buffer_object(ctx, &arrays[i + 16].BufferObj, + vbo->generic_currval[i].BufferObj); + } } exec->vtx.vertex_size = 0; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 6de8f059b7..88502f3d35 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -35,7 +35,6 @@ #include "main/bufferobj.h" #include "main/enums.h" #include "main/macros.h" -#include "glapi/dispatch.h" #include "vbo_context.h" @@ -50,7 +49,7 @@ vbo_get_minmax_index(GLcontext *ctx, GLuint *min_index, GLuint *max_index) { GLuint i; - GLsizei count = prim->count; + GLuint count = prim->count; const void *indices; if (_mesa_is_bufferobj(ib->obj)) { @@ -133,7 +132,7 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array, case GL_FLOAT: { GLfloat *f = (GLfloat *) ((GLubyte *) data + array->StrideB * j); - GLuint k; + GLint k; for (k = 0; k < array->Size; k++) { if (IS_INF_OR_NAN(f[k]) || f[k] >= 1.0e20 || f[k] <= -1.0e10) { @@ -444,6 +443,13 @@ recalculate_input_bindings(GLcontext *ctx) } +/** + * 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_ARRAY dirty flag so state validation + * must be done after this call. + */ static void bind_arrays(GLcontext *ctx) { @@ -485,9 +491,6 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glDrawArrays")) { return; } @@ -543,7 +546,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_BYTE: { const GLubyte *us = (const GLubyte *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size; i++) { _mesa_printf("%02x ", us[i]); if (i % 32 == 31) @@ -555,7 +558,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_SHORT: { const GLushort *us = (const GLushort *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 2; i++) { _mesa_printf("%04x ", us[i]); if (i % 16 == 15) @@ -567,7 +570,7 @@ dump_element_buffer(GLcontext *ctx, GLenum type) case GL_UNSIGNED_INT: { const GLuint *us = (const GLuint *) map; - GLuint i; + GLint i; for (i = 0; i < ctx->Array.ElementArrayBufferObj->Size / 4; i++) { _mesa_printf("%08x ", us[i]); if (i % 8 == 7) @@ -601,18 +604,16 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) { return; } + bind_arrays( ctx ); + + /* check for dirty state again */ if (ctx->NewState) _mesa_update_state( ctx ); - bind_arrays( ctx ); - ib.count = count; ib.type = type; ib.obj = ctx->Array.ElementArrayBufferObj; @@ -689,6 +690,16 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, * 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 (end >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ warnCount++; @@ -713,8 +724,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, #ifdef DEBUG /* 'end' was out of bounds, but now let's check the actual array - * indexes to see if any of them are out of bounds. If so, warn - * and skip the draw to avoid potential segfault, etc. + * indexes to see if any of them are out of bounds. */ { GLuint max = _mesa_max_buffer_index(ctx, count, type, indices, @@ -731,7 +741,6 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, ctx->Array.ElementArrayBufferObj->Name, ctx->Array.ElementArrayBufferObj->Size); } - return; } /* XXX we could also find the min index and compare to 'start' * to see if start is correct. But it's more likely to get the @@ -739,6 +748,10 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, */ } #endif + + /* Set 'end' to the max possible legal value */ + assert(ctx->Array.ArrayObj->_MaxElement >= 1); + end = ctx->Array.ArrayObj->_MaxElement - 1; } else if (0) { _mesa_printf("glDraw[Range]Elements{,BaseVertex}" @@ -837,16 +850,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (ctx->NewState) - _mesa_update_state( ctx ); - if (!_mesa_valid_to_render(ctx, "glMultiDrawElements")) { return; } - if (ctx->NewState) - _mesa_update_state( ctx ); - prim = _mesa_calloc(primcount * sizeof(*prim)); if (prim == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); @@ -858,6 +865,10 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, */ bind_arrays( ctx ); + /* check for dirty state again */ + if (ctx->NewState) + _mesa_update_state( ctx ); + switch (type) { case GL_UNSIGNED_INT: index_type_size = 4; diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 4f43856016..d7dbbceb1b 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -30,7 +30,6 @@ #include "main/context.h" #include "main/enums.h" #include "main/state.h" -#include "main/macros.h" #include "vbo_context.h" diff --git a/src/mesa/vbo/vbo_save.c b/src/mesa/vbo/vbo_save.c index 9757c3d9f6..fd9a130270 100644 --- a/src/mesa/vbo/vbo_save.c +++ b/src/mesa/vbo/vbo_save.c @@ -28,8 +28,6 @@ #include "main/mtypes.h" #include "main/bufferobj.h" -#include "main/dlist.h" -#include "main/vtxfmt.h" #include "main/imports.h" #include "vbo_context.h" @@ -60,8 +58,19 @@ void vbo_save_init( GLcontext *ctx ) { struct gl_client_array *arrays = save->arrays; + unsigned i; + memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0])); memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0])); + + for (i = 0; i < 16; ++i) { + arrays[i ].BufferObj = NULL; + arrays[i + 16].BufferObj = NULL; + _mesa_reference_buffer_object(ctx, &arrays[i ].BufferObj, + vbo->legacy_currval[i].BufferObj); + _mesa_reference_buffer_object(ctx, &arrays[i + 16].BufferObj, + vbo->generic_currval[i].BufferObj); + } } ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c index b7a74e4535..f13a16e3b5 100644 --- a/src/mesa/vbo/vbo_save_loopback.c +++ b/src/mesa/vbo/vbo_save_loopback.c @@ -29,7 +29,6 @@ #include "main/glheader.h" #include "main/enums.h" #include "main/imports.h" -#include "main/macros.h" #include "main/mtypes.h" #include "glapi/dispatch.h" #include "glapi/glapi.h" diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c index c445acca7d..ce40cbbcc3 100644 --- a/src/mesa/vbo/vbo_split.c +++ b/src/mesa/vbo/vbo_split.c @@ -108,12 +108,14 @@ void vbo_split_prims( GLcontext *ctx, vbo_draw_func draw, const struct split_limits *limits ) { - GLuint max_basevertex = prim->basevertex; + GLint max_basevertex = prim->basevertex; GLuint i; for (i = 1; i < nr_prims; i++) max_basevertex = MAX2(max_basevertex, prim[i].basevertex); + /* XXX max_basevertex is computed but not used, why? */ + if (ib) { if (limits->max_indices == 0) { /* Could traverse the indices, re-emitting vertices in turn. diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index c45190b9dd..2ca111217c 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -34,7 +34,6 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" -#include "main/enums.h" #include "main/mtypes.h" #include "vbo_split.h" @@ -221,8 +220,6 @@ begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag ) { struct _mesa_prim *prim = ©->dstprim[copy->dstprim_nr]; -/* _mesa_printf("begin %s (%d)\n", _mesa_lookup_prim_by_nr(mode), begin_flag); */ - prim->mode = mode; prim->begin = begin_flag; } diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index da84eaa6ea..2fc866c577 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -30,12 +30,15 @@ #include "main/mtypes.h" #include "main/macros.h" #include "main/enums.h" +#include "main/image.h" #include "vbo_split.h" #define MAX_PRIM 32 -/* Used for splitting without copying. +/* Used for splitting without copying. No attempt is made to handle + * too large indexed vertex buffers: In general you need to copy to do + * that. */ struct split_context { GLcontext *ctx; @@ -48,6 +51,7 @@ struct split_context { vbo_draw_func draw; const struct split_limits *limits; + GLuint limit; struct _mesa_prim dstprim[MAX_PRIM]; GLuint dstprim_nr; @@ -58,38 +62,38 @@ struct split_context { static void flush_vertex( struct split_context *split ) { - GLuint min_index, max_index; + struct _mesa_index_buffer ib; GLuint i; if (!split->dstprim_nr) return; - min_index = split->dstprim[0].start; - max_index = min_index + split->dstprim[0].count - 1; + if (split->ib) { + ib = *split->ib; - for (i = 1; i < split->dstprim_nr; i++) { - GLuint tmp_min = split->dstprim[i].start; - GLuint tmp_max = tmp_min + split->dstprim[i].count - 1; + ib.count = split->max_index - split->min_index + 1; + ib.ptr = (const void *)((const char *)ib.ptr + + split->min_index * _mesa_sizeof_type(ib.type)); - if (tmp_min < min_index) - min_index = tmp_min; - - if (tmp_max > max_index) - max_index = tmp_max; + /* Rebase the primitives to save index buffer entries. */ + for (i = 0; i < split->dstprim_nr; i++) + split->dstprim[i].start -= split->min_index; } - assert(max_index >= min_index); + assert(split->max_index >= split->min_index); - split->draw( split->ctx, - split->array, - split->dstprim, - split->dstprim_nr, - NULL, - GL_TRUE, - min_index, - max_index); + split->draw(split->ctx, + split->array, + split->dstprim, + split->dstprim_nr, + split->ib ? &ib : NULL, + !split->ib, + split->min_index, + split->max_index); split->dstprim_nr = 0; + split->min_index = ~0; + split->max_index = 0; } @@ -106,62 +110,67 @@ static struct _mesa_prim *next_outprim( struct split_context *split ) } } -static int align(int value, int alignment) +static void update_index_bounds(struct split_context *split, + const struct _mesa_prim *prim) { - return (value + alignment - 1) & ~(alignment - 1); + split->min_index = MIN2(split->min_index, prim->start); + split->max_index = MAX2(split->max_index, prim->start + prim->count - 1); } - +/* Return the maximum amount of vertices that can be emitted for a + * primitive starting at 'prim->start', depending on the previous + * index bounds. + */ +static GLuint get_max_vertices(struct split_context *split, + const struct _mesa_prim *prim) +{ + if ((prim->start > split->min_index && + prim->start - split->min_index >= split->limit) || + (prim->start < split->max_index && + split->max_index - prim->start >= split->limit)) + /* "prim" starts too far away from the old range. */ + return 0; + + return MIN2(split->min_index, prim->start) + split->limit - prim->start; +} /* Break large primitives into smaller ones. If not possible, convert * the primitive to indexed and pass to split_elts(). */ static void split_prims( struct split_context *split) { - GLuint csr = 0; GLuint i; for (i = 0; i < split->nr_prims; i++) { const struct _mesa_prim *prim = &split->prim[i]; GLuint first, incr; GLboolean split_inplace = split_prim_inplace(prim->mode, &first, &incr); - GLuint count; - - /* Always wrap on an even numbered vertex to avoid problems with - * triangle strips. - */ - GLuint available = align(split->limits->max_verts - csr - 1, 2); - assert(split->limits->max_verts >= csr); + GLuint available = get_max_vertices(split, prim); + GLuint count = prim->count - (prim->count - first) % incr; if (prim->count < first) continue; - - count = prim->count - (prim->count - first) % incr; - - if ((available < count && !split_inplace) || + if ((available < count && !split_inplace) || (available < first && split_inplace)) { flush_vertex(split); - csr = 0; - available = align(split->limits->max_verts - csr - 1, 2); + available = get_max_vertices(split, prim); } if (available >= count) { struct _mesa_prim *outprim = next_outprim(split); + *outprim = *prim; - csr += prim->count; - available = align(split->limits->max_verts - csr - 1, 2); - } + update_index_bounds(split, outprim); + } else if (split_inplace) { GLuint j, nr; - for (j = 0 ; j < count ; ) { GLuint remaining = count - j; struct _mesa_prim *outprim = next_outprim(split); nr = MIN2( available, remaining ); - nr -= (nr - first) % incr; outprim->mode = prim->mode; @@ -169,21 +178,20 @@ static void split_prims( struct split_context *split) outprim->end = (nr == remaining && prim->end); outprim->start = prim->start + j; outprim->count = nr; - + + update_index_bounds(split, outprim); + if (nr == remaining) { /* Finished. */ - j += nr; - csr += nr; - available = align(split->limits->max_verts - csr - 1, 2); + j += nr; } else { /* Wrapped the primitive: */ j += nr - (first - incr); flush_vertex(split); - csr = 0; - available = align(split->limits->max_verts - csr - 1, 2); + available = get_max_vertices(split, prim); } } } @@ -260,10 +268,14 @@ void vbo_split_inplace( GLcontext *ctx, split.prim = prim; split.nr_prims = nr_prims; split.ib = ib; - split.min_index = min_index; - split.max_index = max_index; + + /* Empty interval, makes calculations simpler. */ + split.min_index = ~0; + split.max_index = 0; + split.draw = draw; split.limits = limits; + split.limit = ib ? limits->max_indices : limits->max_verts; split_prims( &split ); } diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S index bc83b5a0bd..8edb69bf84 100644 --- a/src/mesa/x86-64/glapi_x86-64.S +++ b/src/mesa/x86-64/glapi_x86-64.S @@ -29,7 +29,7 @@ * the symbol visibility mode to 'default'. */ -#include "../x86/assyntax.h" +#include "x86/assyntax.h" #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 # pragma GCC visibility push(default) diff --git a/src/mesa/x86/assyntax.h b/src/mesa/x86/assyntax.h index 524944f73a..de1f6a48de 100644 --- a/src/mesa/x86/assyntax.h +++ b/src/mesa/x86/assyntax.h @@ -1735,9 +1735,9 @@ SECTION _DATA public align=16 class=DATA use32 flat * If we build with gcc's -fvisibility=hidden flag, we'll need to change * the symbol visibility mode to 'default'. */ -#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) +#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) # define HIDDEN(x) .hidden x -#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 && !defined(__DJGPP__) && !defined(__MINGW32__) +#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 && !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) # pragma GCC visibility push(default) # define HIDDEN(x) .hidden x #else diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S index 6668852514..8030fdf90b 100644 --- a/src/mesa/x86/glapi_x86.S +++ b/src/mesa/x86/glapi_x86.S @@ -26,7 +26,7 @@ * SOFTWARE. */ -#include "assyntax.h" +#include "x86/assyntax.h" #include "glapi/glapioffsets.h" #if defined(STDCALL_API) @@ -46,7 +46,7 @@ #define GL_OFFSET(x) CODEPTR(REGOFF(4 * x, EAX)) -#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) +#if defined(GNU_ASSEMBLER) && !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) #define GLOBL_FN(x) GLOBL x ; .type x, function #else #define GLOBL_FN(x) GLOBL x diff --git a/src/mesa/x86/read_rgba_span_x86.S b/src/mesa/x86/read_rgba_span_x86.S index 92b1c2d902..3886a510bb 100644 --- a/src/mesa/x86/read_rgba_span_x86.S +++ b/src/mesa/x86/read_rgba_span_x86.S @@ -31,7 +31,7 @@ */ .file "read_rgba_span_x86.S" -#if !defined(__DJGPP__) && !defined(__MINGW32__) /* this one cries for assyntax.h */ +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) /* this one cries for assyntax.h */ /* Kevin F. Quinn 2nd July 2006 * Replaced data segment constants with text-segment instructions. */ @@ -671,7 +671,7 @@ _generic_read_RGBA_span_RGB565_MMX: emms #endif ret -#endif /* !defined(__DJGPP__) && !defined(__MINGW32__) */ +#endif /* !defined(__DJGPP__) && !defined(__MINGW32__) && !defined(__APPLE__) */ #if defined (__ELF__) && defined (__linux__) .section .note.GNU-stack,"",%progbits diff --git a/src/mesa/x86/sse_xform2.S b/src/mesa/x86/sse_xform2.S index b490d4c169..a443dad35c 100644 --- a/src/mesa/x86/sse_xform2.S +++ b/src/mesa/x86/sse_xform2.S @@ -186,7 +186,7 @@ GLNAME(_mesa_sse_transform_points2_3d_no_rot): MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ ADD_L( EDI, ECX ) /* count += dest ptr */ - PXOR( XMM0, XMM0 ) + XORPS( XMM0, XMM0 ) /* clean the working register */ ALIGNTEXT32 MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ diff --git a/src/mesa/x86/sse_xform3.S b/src/mesa/x86/sse_xform3.S index 8a79eeda18..4bc22d8a54 100644 --- a/src/mesa/x86/sse_xform3.S +++ b/src/mesa/x86/sse_xform3.S @@ -198,7 +198,7 @@ GLNAME(_mesa_sse_transform_points3_3d_no_rot): MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */ ADD_L( EDI, ECX ) /* count += dest ptr */ - PXOR( XMM0, XMM0 ) + XORPS( XMM0, XMM0 ) /* clean the working register */ ALIGNTEXT32 MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */ diff --git a/src/mesa/x86/x86_xform.c b/src/mesa/x86/x86_xform.c index 52f6b25d81..c834e2b468 100644 --- a/src/mesa/x86/x86_xform.c +++ b/src/mesa/x86/x86_xform.c @@ -30,7 +30,6 @@ #include "main/glheader.h" #include "main/context.h" #include "math/m_xform.h" -#include "tnl/t_context.h" #include "x86_xform.h" #include "common_x86_asm.h" |