summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-07-11 00:05:53 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-07-11 00:05:53 +1000
commit19171ab1d30f14ac0d39894125a3d53a91ca5b89 (patch)
tree7adb5b8317f9acfe1f4f0ba2e10dd79b228cd57d /src
parent225863aeb5f2dfe4980ae5887f5623ecb05e9ced (diff)
parent64f92e00c8292113f9a6372959febe903af09db6 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/xdri/Makefile4
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c93
-rw-r--r--src/egl/main/eglconfig.h8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c2
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer.h2
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c15
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c38
-rw-r--r--src/gallium/winsys/common/intel_drm/intel_be_device.c33
-rw-r--r--src/gallium/winsys/common/intel_drm/intel_be_device.h13
-rw-r--r--src/gallium/winsys/dri/intel/intel_screen.c22
-rw-r--r--src/gallium/winsys/egl_drm/intel/Makefile2
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.c30
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.h4
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_device.c (renamed from src/gallium/winsys/egl_drm/intel/intel_screen.c)52
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_device.h (renamed from src/gallium/winsys/egl_drm/intel/intel_screen.h)2
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.c174
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.h13
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c4
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c1
-rw-r--r--src/mesa/drivers/dri/common/utils.c2
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_tex.c2
-rw-r--r--src/mesa/glapi/glapi_getproc.c4
-rw-r--r--src/mesa/main/attrib.c1
-rw-r--r--src/mesa/main/colortab.c306
-rw-r--r--src/mesa/main/context.c14
-rw-r--r--src/mesa/main/dd.h2
-rw-r--r--src/mesa/main/execmem.c12
-rw-r--r--src/mesa/main/fbobject.c21
-rw-r--r--src/mesa/main/framebuffer.c13
-rw-r--r--src/mesa/main/mtypes.h5
-rw-r--r--src/mesa/main/shaders.c6
-rw-r--r--src/mesa/main/teximage.c58
-rw-r--r--src/mesa/main/texobj.c253
-rw-r--r--src/mesa/main/texobj.h4
-rw-r--r--src/mesa/main/texstate.c179
-rw-r--r--src/mesa/shader/arbprogparse.c9
-rw-r--r--src/mesa/shader/shader_api.c50
-rw-r--r--src/mesa/shader/slang/slang_codegen.c62
-rw-r--r--src/mesa/shader/slang/slang_compile.c21
-rw-r--r--src/mesa/shader/slang/slang_ir.c2
-rw-r--r--src/mesa/shader/slang/slang_print.c80
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c3
-rw-r--r--src/mesa/state_tracker/st_draw.c26
-rw-r--r--src/mesa/state_tracker/st_format.c5
-rw-r--r--src/mesa/vbo/vbo.h10
-rw-r--r--src/mesa/vbo/vbo_exec_api.c10
49 files changed, 990 insertions, 691 deletions
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile
index 477a75184a..252d00b6c2 100644
--- a/src/egl/drivers/xdri/Makefile
+++ b/src/egl/drivers/xdri/Makefile
@@ -27,6 +27,8 @@ OBJECTS = $(SOURCES:.c=.o)
DRM_LIB = `pkg-config --libs libdrm`
+MISC_LIBS = -ldl -lXext -lGL
+
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -47,7 +49,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS)
-noprefix \
-major 1 -minor 0 \
-install $(TOP)/$(LIB_DIR) \
- -ldl $(OBJECTS) $(DRM_LIB)
+ $(OBJECTS) $(DRM_LIB) $(MISC_LIBS)
clean:
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index 71d4f15371..5e50d6034a 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -118,6 +118,10 @@ struct xdri_egl_config
};
+/* XXX temp hack */
+static struct xdri_egl_driver *TheDriver = NULL;
+
+
/** cast wrapper */
static struct xdri_egl_driver *
xdri_egl_driver(_EGLDriver *drv)
@@ -154,6 +158,21 @@ lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+/** 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;
+}
+
+
/**
* Produce a set of EGL configs.
* Note that we get the list of GLcontextModes from the GLX library.
@@ -273,24 +292,25 @@ dri_context_modes_create(unsigned count, size_t minimum_size)
static __DRIscreen *
dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn)
{
- /* unused? */
- return NULL;
+ assert(TheDriver);
+
+ return &TheDriver->driScreen;
}
static GLboolean
-dri_window_exists(__DRInativeDisplay *dpy, __DRIid draw)
+dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw)
{
return EGL_TRUE;
}
static GLboolean
-dri_create_context(__DRInativeDisplay *dpy, int screenNum, int configID,
+dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID,
void * contextID, drm_context_t * hw_context)
{
assert(configID >= 0);
- return XF86DRICreateContextWithConfig(dpy, screenNum,
+ return XF86DRICreateContextWithConfig(ndpy, screenNum,
configID, contextID, hw_context);
}
@@ -325,7 +345,7 @@ dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable)
static GLboolean
-dri_get_drawable_info(__DRInativeDisplay *dpy, int scrn,
+dri_get_drawable_info(__DRInativeDisplay *ndpy, 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,
@@ -335,7 +355,7 @@ dri_get_drawable_info(__DRInativeDisplay *dpy, int scrn,
{
_eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
- if (!XF86DRIGetDrawableInfo(dpy, scrn, draw, index, stamp,
+ if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp,
x, y, width, height,
numClipRects, pClipRects,
backX, backY,
@@ -570,17 +590,29 @@ load_dri_driver(struct xdri_egl_driver *xdri_drv)
char filename[100];
int flags = RTLD_NOW;
- snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name);
+ /* try "egl_xxx_dri.so" first */
+ snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name);
_eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
-
xdri_drv->dri_driver_handle = dlopen(filename, flags);
- if (!xdri_drv->dri_driver_handle) {
- _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)",
- filename, dlerror());
+ if (xdri_drv->dri_driver_handle) {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
+ return EGL_TRUE;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror());
+ }
- return EGL_FALSE;
+ /* try regular "xxx_dri.so" next */
+ snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name);
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
+ xdri_drv->dri_driver_handle = dlopen(filename, flags);
+ if (xdri_drv->dri_driver_handle) {
+ _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
+ return EGL_TRUE;
}
- return EGL_TRUE;
+
+ _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror());
+ return EGL_FALSE;
}
@@ -646,6 +678,24 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
}
+static _EGLProc
+xdri_eglGetProcAddress(const char *procname)
+{
+#if 0
+ _EGLDriver *drv = NULL;
+
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/
+ _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname);
+ return proc;
+#elif 0
+ return (_EGLProc) st_get_proc_address(procname);
+#else
+ return NULL;
+#endif
+}
+
+
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
@@ -724,6 +774,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct xdri_egl_surface *xdri_surf;
int scrn = DefaultScreen(disp->Xdpy);
+ uint width, height;
xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
if (!xdri_surf)
@@ -744,6 +795,10 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
_eglSaveSurface(&xdri_surf->Base);
+ get_drawable_size(disp->Xdpy, window, &width, &height);
+ xdri_surf->Base.Width = width;
+ xdri_surf->Base.Height = height;
+
_eglLog(_EGL_DEBUG,
"XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d",
(int) window, _eglGetSurfaceHandle(&xdri_surf->Base),
@@ -790,9 +845,8 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
- __GLXdisplayPrivate *priv = __glXInitialize(disp->Xdpy);
- __GLXscreenConfigs *scrn = priv->screenConfigs;
- __DRIscreen *psc = &scrn->driScreen;
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ __DRIscreen *psc = &xdri_drv->driScreen;
__DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy,
xdri_surf->driDrawable,
psc->private);
@@ -818,10 +872,15 @@ _eglMain(_EGLDisplay *disp, const char *args)
if (!xdri_drv)
return NULL;
+ /* XXX temp hack */
+ TheDriver = xdri_drv;
+
_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.MakeCurrent = xdri_eglMakeCurrent;
xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index d12f66245c..db1c4c10e0 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -6,7 +6,7 @@
#include <GLES/gl.h>
-#define MAX_ATTRIBS 100
+#define MAX_ATTRIBS 128
#define FIRST_ATTRIB EGL_BUFFER_SIZE
@@ -17,7 +17,11 @@ struct _egl_config
};
-#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL)
+#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) \
+ assert((ATTR) - FIRST_ATTRIB < MAX_ATTRIBS); \
+ ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL)
+
+
#define GET_CONFIG_ATTRIB(CONF, ATTR) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB])
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 9140faeea9..85a75525c8 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -37,6 +37,8 @@
static unsigned trim( unsigned count, unsigned first, unsigned incr )
{
+ if (count < first)
+ return 0;
return count - (count - first) % incr;
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index 6b92811870..8e834501a4 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -184,7 +184,6 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear )
if (!load_input( cp, i, linear ))
return FALSE;
cp->insn_counter++;
- debug_printf("\n");
}
return TRUE;
@@ -316,7 +315,6 @@ boolean aos_emit_outputs( struct aos_compilation *cp )
aos_release_xmm_reg( cp, data.idx );
cp->insn_counter++;
- debug_printf("\n");
}
return TRUE;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
index 83ea0be74b..8505d333bd 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
@@ -221,7 +221,7 @@ pb_check_alignment(size_t requested, size_t provided)
static INLINE boolean
pb_check_usage(unsigned requested, unsigned provided)
{
- return (requested & provided) == provided ? TRUE : FALSE;
+ return (requested & provided) == requested ? TRUE : FALSE;
}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index 92aff88925..a395c630cc 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -573,7 +573,8 @@ tgsi_dump_declaration(
if (decl->Declaration.Semantic) {
TXT( ", " );
ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT );
- if (decl->Semantic.SemanticIndex != 0) {
+ if (decl->Semantic.SemanticIndex != 0 ||
+ decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) {
CHR( '[' );
UID( decl->Semantic.SemanticIndex );
CHR( ']' );
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index 2815e61345..cf4964b26b 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -581,6 +581,7 @@ i915_texture_create(struct pipe_screen *screen,
struct i915_screen *i915screen = i915_screen(screen);
struct pipe_winsys *ws = screen->winsys;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
+ size_t tex_size;
if (!tex)
return NULL;
@@ -600,14 +601,22 @@ i915_texture_create(struct pipe_screen *screen,
goto fail;
}
+ tex_size = tex->stride * tex->total_nblocksy;
+
tex->buffer = ws->buffer_create(ws, 64,
PIPE_BUFFER_USAGE_PIXEL,
- tex->stride *
- tex->total_nblocksy);
+ tex_size);
if (!tex->buffer)
goto fail;
+#if 0
+ void *ptr = ws->buffer_map(ws, tex->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memset(ptr, 0x80, tex_size);
+ ws->buffer_unmap(ws, tex->buffer);
+#endif
+
return &tex->base;
fail:
@@ -710,6 +719,8 @@ i915_texture_blanket(struct pipe_screen * screen,
return NULL;
tex->base = *base;
+ tex->base.refcount = 1;
+ tex->base.screen = screen;
tex->stride = stride[0];
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 24b91fbc79..901c8f83e7 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -154,8 +154,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
/* note: reference counting */
pipe_buffer_reference(ws,
&softpipe->constants[shader].buffer,
- buf->buffer);
- softpipe->constants[shader].size = buf->size;
+ buf ? buf->buffer : NULL);
+ softpipe->constants[shader].size = buf ? buf->size : 0;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 4db045cdc3..f775591352 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -122,8 +122,10 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Now extract the goodies:
*/
- spt->buffer = surf.buffer;
+ spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
+ spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
spt->stride[0] = surf.stride;
+ spt->buffer = surf.buffer;
return spt->buffer != NULL;
}
@@ -162,6 +164,39 @@ softpipe_texture_create(struct pipe_screen *screen,
}
+static struct pipe_texture *
+softpipe_texture_blanket(struct pipe_screen * screen,
+ const struct pipe_texture *base,
+ const unsigned *stride,
+ struct pipe_buffer *buffer)
+{
+ struct softpipe_texture *spt;
+ assert(screen);
+
+ /* Only supports one type */
+ if (base->target != PIPE_TEXTURE_2D ||
+ base->last_level != 0 ||
+ base->depth[0] != 1) {
+ return NULL;
+ }
+
+ spt = CALLOC_STRUCT(softpipe_texture);
+ if (!spt)
+ return NULL;
+
+ spt->base = *base;
+ spt->base.refcount = 1;
+ spt->base.screen = screen;
+ spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
+ spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
+ spt->stride[0] = stride[0];
+
+ pipe_buffer_reference(screen->winsys, &spt->buffer, buffer);
+
+ return &spt->base;
+}
+
+
static void
softpipe_texture_release(struct pipe_screen *screen,
struct pipe_texture **pt)
@@ -309,6 +344,7 @@ void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
+ screen->texture_blanket = softpipe_texture_blanket;
screen->texture_release = softpipe_texture_release;
screen->get_tex_surface = softpipe_get_tex_surface;
diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c
index efb57a394e..8db0329615 100644
--- a/src/gallium/winsys/common/intel_drm/intel_be_device.c
+++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c
@@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte
return &buffer->base;
}
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct intel_be_device *device,
+ const char* name, unsigned handle)
+{
+ struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
+ struct pipe_buffer *buffer;
+
+ if (!be_buf)
+ goto err;
+
+ memset(be_buf, 0, sizeof(*be_buf));
+
+ driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0);
+ driBOSetReferenced(be_buf->driBO, handle);
+
+ if (0) /** XXX TODO check error */
+ goto err_bo;
+
+ buffer = &be_buf->base;
+ buffer->refcount = 1;
+ buffer->alignment = 0;
+ buffer->usage = 0;
+ buffer->size = driBOSize(be_buf->driBO);
+
+ return buffer;
+err_bo:
+ free(be_buf);
+err:
+ return NULL;
+}
+
/*
* Surface functions.
@@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
assert((size_t)"intel_i915_surface_release is deprecated" & 0);
}
+
/*
* Fence functions
*/
@@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws,
return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
}
+
/*
* Misc functions
*/
diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h
index abf0253917..3f8b3f585c 100644
--- a/src/gallium/winsys/common/intel_drm/intel_be_device.h
+++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h
@@ -48,14 +48,23 @@ struct intel_be_buffer {
struct _DriBufferObject *driBO;
};
+/**
+ * Create a be buffer from a drm bo handle
+ *
+ * Takes a reference
+ */
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct intel_be_device *device,
+ const char* name, unsigned handle);
+
static INLINE struct intel_be_buffer *
-intel_be_buffer( struct pipe_buffer *buf )
+intel_be_buffer(struct pipe_buffer *buf)
{
return (struct intel_be_buffer *)buf;
}
static INLINE struct _DriBufferObject *
-dri_bo( struct pipe_buffer *buf )
+dri_bo(struct pipe_buffer *buf)
{
return intel_be_buffer(buf)->driBO;
}
diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c
index cfecebdb8c..f2412217f3 100644
--- a/src/gallium/winsys/dri/intel/intel_screen.c
+++ b/src/gallium/winsys/dri/intel/intel_screen.c
@@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys,
static void
intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle)
{
- struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
struct pipe_screen *screen = intelScreen->base.screen;
struct pipe_texture *texture;
struct pipe_texture templat;
struct pipe_surface *surface;
- struct pipe_buffer *buffer = &be_buf->base;
+ struct pipe_buffer *buffer;
unsigned pitch;
assert(intelScreen->front.cpp == 4);
- /* XXX create a intel_be function for this */
- {
- driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
- driBOSetReferenced(intelScreen->front.buffer, handle);
-
- memset(be_buf, 0, sizeof(*be_buf));
- buffer->refcount = 1;
- buffer->alignment = 0;
- buffer->usage = 0;
- buffer->size = driBOSize(intelScreen->front.buffer);
- be_buf->driBO = intelScreen->front.buffer;
- }
+ buffer = intel_be_buffer_from_handle(&intelScreen->base,
+ "front", handle);
+
+ if (!buffer)
+ return;
+
+ intelScreen->front.buffer = dri_bo(buffer);
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile
index 9c7ff065ff..e67b49f3ad 100644
--- a/src/gallium/winsys/egl_drm/intel/Makefile
+++ b/src/gallium/winsys/egl_drm/intel/Makefile
@@ -12,7 +12,7 @@ PIPE_DRIVERS = \
DRIVER_SOURCES = \
intel_swapbuffers.c \
intel_context.c \
- intel_screen.c \
+ intel_device.c \
intel_egl.c
C_SOURCES = \
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c
index 7205fa4483..927addb834 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_context.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.c
@@ -27,7 +27,7 @@
#include "i915simple/i915_screen.h"
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
@@ -147,13 +147,13 @@ int
intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate)
{
struct intel_context *intel = CALLOC_STRUCT(intel_context);
- struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv;
+ struct intel_device *device = (struct intel_device *)egl_context->device->priv;
struct pipe_context *pipe;
struct st_context *st_share = NULL;
egl_context->priv = intel;
- intel->intel_screen = screen;
+ intel->intel_device = device;
intel->egl_context = egl_context;
intel->egl_device = egl_context->device;
@@ -161,23 +161,37 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes
intel->base.hardware_unlock = intel_unlock_hardware;
intel->base.hardware_locked = intel_locked_hardware;
- intel_be_init_context(&intel->base, &screen->base);
+ intel_be_init_context(&intel->base, &device->base);
#if 0
pipe = intel_create_softpipe(intel, screen->winsys);
#else
- pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base);
+ pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base);
#endif
pipe->priv = intel;
intel->st = st_create_context(pipe, visual, st_share);
- screen->dummy = intel;
+ device->dummy = intel;
return TRUE;
}
+int
+intel_destroy_context(struct egl_drm_context *egl_context)
+{
+ struct intel_context *intel = egl_context->priv;
+
+ if (intel->intel_device->dummy == intel)
+ intel->intel_device->dummy = NULL;
+
+ st_destroy_context(intel->st);
+ intel_be_destroy_context(&intel->base);
+ free(intel);
+ return TRUE;
+}
+
void
intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read)
{
@@ -206,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra
void
intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
{
- struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv;
+ struct intel_device *device = (struct intel_device *)draw->device->priv;
struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
if (draw_fb->front_buffer)
@@ -221,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer
draw_fb->front = front;
- driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
+ driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
driBOSetReferenced(draw_fb->front_buffer, front->handle);
st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h
index f05a213ff0..dfa4720b08 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_context.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.h
@@ -47,7 +47,7 @@ struct intel_context
struct st_context *st;
- struct intel_screen *intel_screen;
+ struct intel_device *intel_device;
/* new egl stuff */
struct egl_drm_device *egl_device;
@@ -64,7 +64,7 @@ struct intel_framebuffer
{
struct st_framebuffer *stfb;
- struct intel_screen *screen;
+ struct intel_device *device;
struct _DriBufferObject *front_buffer;
struct egl_drm_frontbuffer *front;
};
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_device.c
index 2818b9676c..b9649cbec7 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_screen.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_device.c
@@ -32,7 +32,7 @@
#include "i915simple/i915_screen.h"
#include "intel_context.h"
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_batchbuffer.h"
#include "intel_egl.h"
@@ -41,24 +41,23 @@ extern const struct dri_extension card_extensions[];
int
-intel_init_driver(struct egl_drm_device *device)
+intel_create_device(struct egl_drm_device *device)
{
- struct intel_screen *intel_screen;
+ struct intel_device *intel_device;
/* Allocate the private area */
- intel_screen = CALLOC_STRUCT(intel_screen);
- if (!intel_screen)
+ intel_device = CALLOC_STRUCT(intel_device);
+ if (!intel_device)
return FALSE;
- device->priv = (void *)intel_screen;
- intel_screen->device = device;
+ device->priv = (void *)intel_device;
+ intel_device->device = device;
- /** TODO JB: ugly hack */
- intel_screen->deviceID = PCI_CHIP_I945_GM;
+ intel_device->deviceID = device->deviceID;
- intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM);
+ intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID);
- intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID);
+ intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID);
/* hack */
driInitExtensions(NULL, card_extensions, GL_FALSE);
@@ -67,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device)
}
int
+intel_destroy_device(struct egl_drm_device *device)
+{
+ struct intel_device *intel_device = (struct intel_device *)device->priv;
+
+ intel_be_destroy_device(&intel_device->base);
+
+ free(intel_device);
+ device->priv = NULL;
+
+ return TRUE;
+}
+
+int
intel_create_drawable(struct egl_drm_drawable *drawable,
const __GLcontextModes * visual)
{
@@ -76,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable,
if (!intelfb)
return GL_FALSE;
- intelfb->screen = drawable->device->priv;
+ intelfb->device = drawable->device->priv;
if (visual->redBits == 5)
colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
@@ -108,6 +120,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable,
return GL_FALSE;
}
- drawable->priv = (void *) intelfb;
- return GL_TRUE;
+ drawable->priv = (void *) intelfb;
+ return GL_TRUE;
+}
+
+int
+intel_destroy_drawable(struct egl_drm_drawable *drawable)
+{
+ struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv;
+ drawable->priv = NULL;
+
+ assert(intelfb->stfb);
+ st_unreference_framebuffer(&intelfb->stfb);
+ free(intelfb);
+ return TRUE;
}
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_device.h
index 9b990b48e7..2f9d4f887e 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_screen.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_device.h
@@ -36,7 +36,7 @@ struct pipe_screen;
struct egl_drm_device;
struct intel_context;
-struct intel_screen
+struct intel_device
{
struct intel_be_device base;
struct pipe_screen *pipe;
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c
index 6865bfa3d4..55f4d92afb 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_egl.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c
@@ -13,6 +13,7 @@
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
+#include "egllog.h"
#include "intel_egl.h"
@@ -23,18 +24,43 @@
#include "state_tracker/st_public.h"
-struct egl_drm_device* egl_drm_create_device(int drmFD);
+#define MAX_SCREENS 16
-struct egl_drm_device*
+static void
+drm_get_device_id(struct egl_drm_device *device)
+{
+ char path[512];
+ FILE *file;
+
+ /* TODO get the real minor */
+ int minor = 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;
+ }
+
+ fgets(path, sizeof( path ), file);
+ sscanf(path, "%x", &device->deviceID);
+ fclose(file);
+}
+
+static struct egl_drm_device*
egl_drm_create_device(int drmFD)
{
struct egl_drm_device *device = malloc(sizeof(*device));
memset(device, 0, sizeof(*device));
device->drmFD = drmFD;
- if (!intel_init_driver(device)) {
- printf("EGL: failed to initalize device\n");
+ device->version = drmGetVersion(device->drmFD);
+
+ drm_get_device_id(device);
+
+ if (!intel_create_device(device)) {
free(device);
+ return NULL;
}
return device;
@@ -42,11 +68,17 @@ egl_drm_create_device(int drmFD)
__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size );
+struct drm_screen;
+
struct drm_driver
{
_EGLDriver base; /* base class/object */
drmModeResPtr res;
+
+ struct drm_screen *screens[MAX_SCREENS];
+ size_t count_screens;
+
struct egl_drm_device *device;
};
@@ -68,17 +100,26 @@ struct drm_screen
{
_EGLScreen base;
- /* backing buffer and crtc */
+ /* currently only support one connector */
+ drmModeConnectorPtr connector;
+ uint32_t connectorID;
+
+ /* Has this screen been shown */
+ int shown;
+
+ /* Surface that is currently attached to this screen */
+ struct drm_surface *surf;
+
+ /* backing buffer */
drmBO buffer;
+
+ /* framebuffer */
drmModeFBPtr fb;
uint32_t fbID;
- drmModeCrtcPtr crtc;
- /* currently only support one connector */
- drmModeConnectorPtr connector;
- drmModeEncoderPtr encoder;
- uint32_t connectorID;
- uint32_t encoderID;
+ /* crtc and mode used */
+ drmModeCrtcPtr crtc;
+ uint32_t crtcID;
struct drm_mode_modeinfo *mode;
@@ -105,28 +146,17 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
}
}
-static void
-print_modes(drmModeConnectorPtr connector)
-{
- struct drm_mode_modeinfo *m;
- int i;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh);
- }
-}
static EGLBoolean
drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
- printf("%s enter\n", __FUNCTION__);
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_screen *screen = NULL;
drmModeConnectorPtr connector = NULL;
drmModeResPtr res = NULL;
unsigned count_connectors = 0;
+ int num_screens = 0;
EGLint i;
int fd;
@@ -147,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
if (res)
count_connectors = res->count_connectors;
- for(i = 0; i < count_connectors; i++) {
+ for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
connector = drmModeGetConnector(fd, res->connectors[i]);
if (!connector)
continue;
- if (connector->connection == DRM_MODE_DISCONNECTED) {
+ if (connector->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(connector);
continue;
}
@@ -165,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
_eglInitScreen(&screen->base);
_eglAddScreen(disp, &screen->base);
drm_add_modes_from_connector(&screen->base, connector);
+ drm_drv->screens[num_screens++] = screen;
}
+ drm_drv->count_screens = num_screens;
/* for now we only have one config */
_EGLConfig *config = calloc(1, sizeof(*config));
@@ -184,17 +216,64 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
drv->Initialized = EGL_TRUE;
*major = 1;
- *minor = 0;
+ *minor = 4;
return EGL_TRUE;
}
+static void
+drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+
+ intel_bind_frontbuffer(screen->surf->drawable, NULL);
+ screen->surf = NULL;
+
+ drmModeSetCrtc(
+ drm_drv->device->drmFD,
+ drm_drv->res->crtcs[1],
+ 0, // FD
+ 0, 0,
+ NULL, 0, // List of output ids
+ NULL);
+
+ drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
+ drmModeFreeFB(screen->fb);
+ screen->fb = NULL;
+
+ drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
+
+ screen->shown = 0;
+}
static EGLBoolean
drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
{
- /* TODO: clean up */
- free(drv);
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_screen *screen;
+ int i = 0;
+
+ intel_destroy_device(drm_drv->device);
+ drmFreeVersion(drm_drv->device->version);
+
+ for (i = 0; i < drm_drv->count_screens; i++) {
+ screen = drm_drv->screens[i];
+
+ if (screen->shown)
+ drm_takedown_shown_screen(drv, screen);
+
+ drmModeFreeConnector(screen->connector);
+ _eglDestroyScreen(&screen->base);
+ drm_drv->screens[i] = NULL;
+ }
+
+ drmClose(drm_drv->device->drmFD);
+
+ free(drm_drv->device);
+
+ _eglCleanupDisplay(_eglLookupDisplay(dpy));
+ free(drm_drv);
+
return EGL_TRUE;
}
@@ -237,7 +316,9 @@ visual_from_config(_EGLConfig *conf)
visual->doubleBufferMode = 1;
visual->depthBits = 24;
+ visual->haveDepthBuffer = visual->depthBits > 0;
visual->stencilBits = 8;
+ visual->haveStencilBuffer = visual->stencilBits > 0;
return visual;
}
@@ -314,6 +395,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
if (fc->base.IsBound) {
fc->base.DeletePending = EGL_TRUE;
} else {
+ intel_destroy_context(fc->context);
+ free(fc->context);
free(fc);
}
return EGL_TRUE;
@@ -333,6 +416,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat
return EGL_NO_SURFACE;
}
+
static EGLSurface
drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
@@ -480,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
size_t size = mode->Height * pitch;
int ret;
- /* TODO if allready shown take down */
+ if (scrn->shown)
+ drm_takedown_shown_screen(drv, scrn);
ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
DRM_BO_FLAG_READ |
@@ -490,10 +575,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
DRM_BO_FLAG_NO_EVICT,
DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
- if (ret) {
- printf("failed to create framebuffer (ret %d)\n", ret);
+ if (ret)
return EGL_FALSE;
- }
prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
@@ -510,10 +593,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
goto err_bo;
scrn->mode = drm_find_mode(scrn->connector, mode);
- if (!scrn->mode) {
- printf("oh noes, no matching mode found\n");
+ if (!scrn->mode)
goto err_fb;
- }
ret = drmModeSetCrtc(
drm_drv->device->drmFD,
@@ -529,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
scrn->front.width = mode->Width;
scrn->front.height = mode->Height;
+ scrn->surf = surf;
intel_bind_frontbuffer(surf->drawable, &scrn->front);
+ scrn->shown = 1;
+
return EGL_TRUE;
err_fb:
@@ -549,14 +633,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
if (fs->base.IsBound) {
fs->base.DeletePending = EGL_TRUE;
} else {
+ intel_bind_frontbuffer(fs->drawable, NULL);
+ intel_destroy_drawable(fs->drawable);
+ free(fs->drawable);
free(fs);
}
return EGL_TRUE;
}
-
-
static EGLBoolean
drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
@@ -569,12 +654,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re
if (!b)
return EGL_FALSE;
- /* XXX this is where we'd do the hardware context switch */
- (void) drawSurf;
- (void) readSurf;
- (void) ctx;
+ if (ctx) {
+ if (!drawSurf || !readSurf)
+ return EGL_FALSE;
+
+ intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
+ } else {
+ intel_make_current(NULL, NULL, NULL);
+ }
- intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
return EGL_TRUE;
}
@@ -602,7 +690,6 @@ _EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args)
{
struct drm_driver *drm;
- printf("%s enter\n", __FUNCTION__);
drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
if (!drm) {
@@ -626,6 +713,7 @@ _eglMain(_EGLDisplay *dpy, const char *args)
drm->base.API.SwapBuffers = drm_swap_buffers;
drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ drm->base.Name = "DRM/Gallium";
/* enable supported extensions */
drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h
index 18e84e8eea..1ee27e0847 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_egl.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h
@@ -2,10 +2,15 @@
#ifndef _INTEL_EGL_H_
#define _INTEL_EGL_H_
+#include <xf86drm.h>
+
struct egl_drm_device
{
void *priv;
int drmFD;
+
+ drmVersionPtr version;
+ int deviceID;
};
struct egl_drm_context
@@ -32,9 +37,15 @@ struct egl_drm_frontbuffer
#include "GL/internal/glcore.h"
-int intel_init_driver(struct egl_drm_device *device);
+int intel_create_device(struct egl_drm_device *device);
+int intel_destroy_device(struct egl_drm_device *device);
+
int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
+int intel_destroy_context(struct egl_drm_context *context);
+
int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
+int intel_destroy_drawable(struct egl_drm_drawable *drawable);
+
void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read);
void intel_swap_buffers(struct egl_drm_drawable *draw);
void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front);
diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
index bfff6f935f..2edcbc79ff 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
#include "intel_reg.h"
@@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw,
//const int srcWidth = surf->width;
//const int srcHeight = surf->height;
- intel = intel_fb->screen->dummy;
+ intel = intel_fb->device->dummy;
if (!intel) {
printf("No dummy context\n");
return;
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index 83b8bb95b1..708a58b781 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
surf->Base.DeletePending = EGL_TRUE;
}
else {
+ XFreeGC(surf->Dpy, surf->Gc);
st_unreference_framebuffer(&surf->Framebuffer);
free(surf);
}
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 3cf2146dce..67cffead00 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -310,8 +310,10 @@ void driInitSingleExtension( GLcontext * ctx,
*/
offset = _glapi_add_dispatch( functions, parameter_signature );
if (offset == -1) {
+#if 0 /* this causes noise with egl */
fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed "
"to add %s!\n", functions[0]);
+#endif
}
else if (ext->functions[i].remap_index != -1) {
driDispatchRemapTable[ ext->functions[i].remap_index ] =
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
index 65e665ee39..70ef726437 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
@@ -1821,7 +1821,7 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target,
tdfxTexInfo *ti;
int memNeeded;
- tObj = ctx->Texture.Proxy2D;
+ tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
if (!tObj->DriverData)
tObj->DriverData = fxAllocTexObjData(fxMesa);
ti = TDFX_TEXTURE_DATA(tObj);
diff --git a/src/mesa/glapi/glapi_getproc.c b/src/mesa/glapi/glapi_getproc.c
index 5e0af26a01..3634444c85 100644
--- a/src/mesa/glapi/glapi_getproc.c
+++ b/src/mesa/glapi/glapi_getproc.c
@@ -411,7 +411,7 @@ add_function_name( const char * funcName )
* \returns
* The offset in the dispatch table of the named function. A pointer to the
* driver's implementation of the named function should be stored at
- * \c dispatch_table[\c offset].
+ * \c dispatch_table[\c offset]. Return -1 if error/problem.
*
* \sa glXGetProcAddress
*
@@ -460,7 +460,7 @@ _glapi_add_dispatch( const char * const * function_names,
*/
if (!function_names[i] || function_names[i][0] != 'g' || function_names[i][1] != 'l')
- return GL_FALSE;
+ return -1;
/* Determine if the named function already exists. If the function does
* exist, it must have the same parameter signature as the function
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 2e6bb76586..b990369a9e 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -361,6 +361,7 @@ _mesa_PushAttrib(GLbitfield mask)
ctx->Texture.Unit[u].Current1DArray->RefCount++;
ctx->Texture.Unit[u].Current2DArray->RefCount++;
}
+
attr = MALLOC_STRUCT( gl_texture_attrib );
MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
/* copy state of the currently bound texture objects */
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index 610acba306..97120398f9 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -30,6 +30,7 @@
#include "image.h"
#include "macros.h"
#include "state.h"
+#include "teximage.h"
/**
@@ -305,49 +306,6 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat,
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
switch (target) {
- case GL_TEXTURE_1D:
- texObj = texUnit->Current1D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_2D:
- texObj = texUnit->Current2D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_3D:
- texObj = texUnit->Current3D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
- return;
- }
- texObj = texUnit->CurrentCubeMap;
- table = &texObj->Palette;
- break;
- case GL_PROXY_TEXTURE_1D:
- texObj = ctx->Texture.Proxy1D;
- table = &texObj->Palette;
- proxy = GL_TRUE;
- break;
- case GL_PROXY_TEXTURE_2D:
- texObj = ctx->Texture.Proxy2D;
- table = &texObj->Palette;
- proxy = GL_TRUE;
- break;
- case GL_PROXY_TEXTURE_3D:
- texObj = ctx->Texture.Proxy3D;
- table = &texObj->Palette;
- proxy = GL_TRUE;
- break;
- case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
- return;
- }
- texObj = ctx->Texture.ProxyCubeMap;
- table = &texObj->Palette;
- break;
case GL_SHARED_TEXTURE_PALETTE_EXT:
table = &ctx->Texture.Palette;
break;
@@ -396,8 +354,19 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat,
proxy = GL_TRUE;
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
- return;
+ /* try texture targets */
+ {
+ struct gl_texture_object *texobj
+ = _mesa_select_tex_object(ctx, texUnit, target);
+ if (texobj) {
+ table = &texobj->Palette;
+ proxy = _mesa_is_proxy_texture(target);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ return;
+ }
+ }
}
assert(table);
@@ -499,26 +468,6 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
switch (target) {
- case GL_TEXTURE_1D:
- texObj = texUnit->Current1D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_2D:
- texObj = texUnit->Current2D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_3D:
- texObj = texUnit->Current3D;
- table = &texObj->Palette;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
- return;
- }
- texObj = texUnit->CurrentCubeMap;
- table = &texObj->Palette;
- break;
case GL_SHARED_TEXTURE_PALETTE_EXT:
table = &ctx->Texture.Palette;
break;
@@ -547,8 +496,15 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX];
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
- return;
+ /* try texture targets */
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (texObj && !_mesa_is_proxy_texture(target)) {
+ table = &texObj->Palette;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+ return;
+ }
}
assert(table);
@@ -636,22 +592,6 @@ _mesa_GetColorTable( GLenum target, GLenum format,
}
switch (target) {
- case GL_TEXTURE_1D:
- table = &texUnit->Current1D->Palette;
- break;
- case GL_TEXTURE_2D:
- table = &texUnit->Current2D->Palette;
- break;
- case GL_TEXTURE_3D:
- table = &texUnit->Current3D->Palette;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
- return;
- }
- table = &texUnit->CurrentCubeMap->Palette;
- break;
case GL_SHARED_TEXTURE_PALETTE_EXT:
table = &ctx->Texture.Palette;
break;
@@ -672,8 +612,18 @@ _mesa_GetColorTable( GLenum target, GLenum format,
table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX];
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
- return;
+ /* try texture targets */
+ {
+ struct gl_texture_object *texobj
+ = _mesa_select_tex_object(ctx, texUnit, target);
+ if (texobj && !_mesa_is_proxy_texture(target)) {
+ table = &texobj->Palette;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
+ return;
+ }
+ }
}
ASSERT(table);
@@ -781,65 +731,41 @@ _mesa_GetColorTable( GLenum target, GLenum format,
void GLAPIENTRY
_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
+ GLfloat *scale, *bias;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
switch (target) {
- case GL_COLOR_TABLE_SGI:
- if (pname == GL_COLOR_TABLE_SCALE_SGI) {
- COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION], params);
- }
- else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
- COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION], params);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
- return;
- }
- break;
- case GL_TEXTURE_COLOR_TABLE_SGI:
- if (!ctx->Extensions.SGI_texture_color_table) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
- return;
- }
- if (pname == GL_COLOR_TABLE_SCALE_SGI) {
- COPY_4V(ctx->Pixel.TextureColorTableScale, params);
- }
- else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
- COPY_4V(ctx->Pixel.TextureColorTableBias, params);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
- return;
- }
- break;
- case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
- if (pname == GL_COLOR_TABLE_SCALE_SGI) {
- COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION], params);
- }
- else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
- COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION], params);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
- return;
- }
- break;
- case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
- if (pname == GL_COLOR_TABLE_SCALE_SGI) {
- COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX], params);
- }
- else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
- COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX], params);
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
- return;
- }
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
- return;
+ case GL_COLOR_TABLE_SGI:
+ scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION];
+ bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION];
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ scale = ctx->Pixel.TextureColorTableScale;
+ bias = ctx->Pixel.TextureColorTableBias;
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION];
+ bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION];
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX];
+ bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX];
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
+ return;
+ }
+
+ if (pname == GL_COLOR_TABLE_SCALE_SGI) {
+ COPY_4V(scale, params);
+ }
+ else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
+ COPY_4V(bias, params);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
+ return;
}
ctx->NewState |= _NEW_PIXEL;
@@ -879,40 +805,6 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
ASSERT_OUTSIDE_BEGIN_END(ctx);
switch (target) {
- case GL_TEXTURE_1D:
- table = &texUnit->Current1D->Palette;
- break;
- case GL_TEXTURE_2D:
- table = &texUnit->Current2D->Palette;
- break;
- case GL_TEXTURE_3D:
- table = &texUnit->Current3D->Palette;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameterfv(target)");
- return;
- }
- table = &texUnit->CurrentCubeMap->Palette;
- break;
- case GL_PROXY_TEXTURE_1D:
- table = &ctx->Texture.Proxy1D->Palette;
- break;
- case GL_PROXY_TEXTURE_2D:
- table = &ctx->Texture.Proxy2D->Palette;
- break;
- case GL_PROXY_TEXTURE_3D:
- table = &ctx->Texture.Proxy3D->Palette;
- break;
- case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameterfv(target)");
- return;
- }
- table = &ctx->Texture.ProxyCubeMap->Palette;
- break;
case GL_SHARED_TEXTURE_PALETTE_EXT:
table = &ctx->Texture.Palette;
break;
@@ -981,8 +873,19 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX];
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)");
- return;
+ /* try texture targets */
+ {
+ struct gl_texture_object *texobj
+ = _mesa_select_tex_object(ctx, texUnit, target);
+ if (texobj) {
+ table = &texobj->Palette;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameterfv(target)");
+ return;
+ }
+ }
}
assert(table);
@@ -1029,40 +932,6 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
ASSERT_OUTSIDE_BEGIN_END(ctx);
switch (target) {
- case GL_TEXTURE_1D:
- table = &texUnit->Current1D->Palette;
- break;
- case GL_TEXTURE_2D:
- table = &texUnit->Current2D->Palette;
- break;
- case GL_TEXTURE_3D:
- table = &texUnit->Current3D->Palette;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameteriv(target)");
- return;
- }
- table = &texUnit->CurrentCubeMap->Palette;
- break;
- case GL_PROXY_TEXTURE_1D:
- table = &ctx->Texture.Proxy1D->Palette;
- break;
- case GL_PROXY_TEXTURE_2D:
- table = &ctx->Texture.Proxy2D->Palette;
- break;
- case GL_PROXY_TEXTURE_3D:
- table = &ctx->Texture.Proxy3D->Palette;
- break;
- case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetColorTableParameteriv(target)");
- return;
- }
- table = &ctx->Texture.ProxyCubeMap->Palette;
- break;
case GL_SHARED_TEXTURE_PALETTE_EXT:
table = &ctx->Texture.Palette;
break;
@@ -1161,8 +1030,19 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX];
break;
default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
- return;
+ /* Try texture targets */
+ {
+ struct gl_texture_object *texobj
+ = _mesa_select_tex_object(ctx, texUnit, target);
+ if (texobj) {
+ table = &texobj->Palette;
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetColorTableParameteriv(target)");
+ return;
+ }
+ }
}
assert(table);
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 33f6d2c0d0..279880cf40 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -500,19 +500,12 @@ alloc_shared_state( GLcontext *ctx )
if (!ss->Default2DArray)
goto cleanup;
- /* Effectively bind the default textures to all texture units */
- ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->Default1DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ss->Default2DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ /* sanity check */
+ assert(ss->Default1D->RefCount == 1);
_glthread_INIT_MUTEX(ss->TexMutex);
ss->TextureStateStamp = 0;
-
#if FEATURE_EXT_framebuffer_object
ss->FrameBuffers = _mesa_NewHashTable();
if (!ss->FrameBuffers)
@@ -522,10 +515,9 @@ alloc_shared_state( GLcontext *ctx )
goto cleanup;
#endif
-
return GL_TRUE;
- cleanup:
+cleanup:
/* Ran out of memory at some point. Free everything and return NULL */
if (ss->DisplayList)
_mesa_DeleteHashTable(ss->DisplayList);
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index a24021c63f..7fb0a211d7 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -870,6 +870,8 @@ struct dd_function_table {
GLsizei *length, GLcharARB *sourceOut);
void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
GLfloat *params);
+ void (*GetUniformiv)(GLcontext *ctx, GLuint program, GLint location,
+ GLint *params);
GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
const GLcharARB *name);
GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
diff --git a/src/mesa/main/execmem.c b/src/mesa/main/execmem.c
index 40f66d7da2..aa40b02205 100644
--- a/src/mesa/main/execmem.c
+++ b/src/mesa/main/execmem.c
@@ -36,7 +36,7 @@
-#if defined(__linux__)
+#if defined(__linux__) || defined(__OpenBSD__)
/*
* Allocate a large block of memory which can hold code then dole it out
@@ -47,6 +47,16 @@
#include <sys/mman.h>
#include "mm.h"
+#ifdef MESA_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+
#define EXEC_HEAP_SIZE (10*1024*1024)
_glthread_DECLARE_STATIC_MUTEX(exec_mutex);
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index e4ff575e18..0ae69bdce7 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -172,22 +172,17 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
{
if (att->Type == GL_TEXTURE) {
ASSERT(att->Texture);
- att->Texture->RefCount--;
- if (att->Texture->RefCount == 0) {
- ctx->Driver.DeleteTexture(ctx, att->Texture);
- }
- else {
+ if (ctx->Driver.FinishRenderTexture) {
/* tell driver that we're done rendering to this texture. */
- if (ctx->Driver.FinishRenderTexture) {
- ctx->Driver.FinishRenderTexture(ctx, att);
- }
+ ctx->Driver.FinishRenderTexture(ctx, att);
}
- att->Texture = NULL;
+ _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
+ ASSERT(!att->Texture);
}
if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
- ASSERT(att->Renderbuffer);
ASSERT(!att->Texture);
- _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
+ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
+ ASSERT(!att->Renderbuffer);
}
att->Type = GL_NONE;
att->Complete = GL_TRUE;
@@ -213,8 +208,8 @@ _mesa_set_texture_attachment(GLcontext *ctx,
/* new attachment */
_mesa_remove_attachment(ctx, att);
att->Type = GL_TEXTURE;
- att->Texture = texObj;
- texObj->RefCount++;
+ assert(!att->Texture);
+ _mesa_reference_texobj(&att->Texture, texObj);
}
/* always update these fields */
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 96f1b30c9b..dab449fc09 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -38,6 +38,7 @@
#include "fbobject.h"
#include "framebuffer.h"
#include "renderbuffer.h"
+#include "texobj.h"
@@ -192,17 +193,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
}
if (att->Texture) {
- /* render to texture */
- att->Texture->RefCount--;
- if (att->Texture->RefCount == 0) {
- GET_CURRENT_CONTEXT(ctx);
- if (ctx) {
- ctx->Driver.DeleteTexture(ctx, att->Texture);
- }
- }
+ _mesa_reference_texobj(&att->Texture, NULL);
}
+ ASSERT(!att->Renderbuffer);
+ ASSERT(!att->Texture);
att->Type = GL_NONE;
- att->Texture = NULL;
}
/* unbind _Depth/_StencilBuffer to decr ref counts */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 00e7d5d395..2d6be1983c 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1404,6 +1404,7 @@ struct gl_texture_image
*/
struct gl_texture_object
{
+ _glthread_Mutex Mutex; /**< for thread safety */
GLint RefCount; /**< reference count */
GLuint Name; /**< the user-visible texture object ID */
GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */
@@ -1578,6 +1579,7 @@ struct gl_texture_attrib
struct gl_texture_unit Unit[MAX_TEXTURE_UNITS];
+#if 0
struct gl_texture_object *Proxy1D;
struct gl_texture_object *Proxy2D;
struct gl_texture_object *Proxy3D;
@@ -1585,6 +1587,9 @@ struct gl_texture_attrib
struct gl_texture_object *ProxyRect;
struct gl_texture_object *Proxy1DArray;
struct gl_texture_object *Proxy2DArray;
+#else
+ struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
+#endif
/** GL_EXT_shared_texture_palette */
GLboolean SharedPalette;
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
index b7b2f791a5..f0db0d2a81 100644
--- a/src/mesa/main/shaders.c
+++ b/src/mesa/main/shaders.c
@@ -309,11 +309,7 @@ void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
{
GET_CURRENT_CONTEXT(ctx);
- GLfloat fparams[16]; /* XXX is 16 enough? */
- GLuint i;
- ctx->Driver.GetUniformfv(ctx, program, location, fparams);
- for (i = 0; i < 16; i++)
- params[i] = (GLint) fparams[i]; /* XXX correct? */
+ ctx->Driver.GetUniformiv(ctx, program, location, params);
}
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index eed1937517..36557f19fd 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -767,15 +767,15 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
case GL_TEXTURE_1D:
return texUnit->Current1D;
case GL_PROXY_TEXTURE_1D:
- return ctx->Texture.Proxy1D;
+ return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
case GL_TEXTURE_2D:
return texUnit->Current2D;
case GL_PROXY_TEXTURE_2D:
- return ctx->Texture.Proxy2D;
+ return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
case GL_TEXTURE_3D:
return texUnit->Current3D;
case GL_PROXY_TEXTURE_3D:
- return ctx->Texture.Proxy3D;
+ return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
@@ -787,25 +787,25 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
? texUnit->CurrentCubeMap : NULL;
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Extensions.ARB_texture_cube_map
- ? ctx->Texture.ProxyCubeMap : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
case GL_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
? texUnit->CurrentRect : NULL;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle
- ? ctx->Texture.ProxyRect : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
case GL_TEXTURE_1D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
? texUnit->Current1DArray : NULL;
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
- ? ctx->Texture.Proxy1DArray : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
case GL_TEXTURE_2D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
? texUnit->Current2DArray : NULL;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
return ctx->Extensions.MESA_texture_array
- ? ctx->Texture.Proxy2DArray : NULL;
+ ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
default:
_mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
return NULL;
@@ -932,106 +932,106 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
case GL_PROXY_TEXTURE_1D:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy1D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy1D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy1D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_2D:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy2D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy2D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy2D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_3D:
if (level >= ctx->Const.Max3DTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy3D->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy3D->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy3D;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_CUBE_MAP:
if (level >= ctx->Const.MaxCubeTextureLevels)
return NULL;
- texImage = ctx->Texture.ProxyCubeMap->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.ProxyCubeMap->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.ProxyCubeMap;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_RECTANGLE_NV:
if (level > 0)
return NULL;
- texImage = ctx->Texture.ProxyRect->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.ProxyRect->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.ProxyRect;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy1DArray->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy1DArray->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy1DArray;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX];
}
return texImage;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
if (level >= ctx->Const.MaxTextureLevels)
return NULL;
- texImage = ctx->Texture.Proxy2DArray->Image[0][level];
+ texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level];
if (!texImage) {
texImage = ctx->Driver.NewTextureImage(ctx);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
return NULL;
}
- ctx->Texture.Proxy2DArray->Image[0][level] = texImage;
+ ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage;
/* Set the 'back' pointer */
- texImage->TexObject = ctx->Texture.Proxy2DArray;
+ texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX];
}
return texImage;
default:
@@ -2611,7 +2611,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
1, border)) {
/* when error, clear all proxy texture image parameters */
if (texImage)
- clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]);
+ clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]);
}
else {
/* no error, set the tex image parameters */
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 606e62d7a0..b77a00dd15 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -5,9 +5,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -108,6 +108,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
_mesa_bzero(obj, sizeof(*obj));
/* init the non-zero fields */
+ _glthread_INIT_MUTEX(obj->Mutex);
obj->RefCount = 1;
obj->Name = name;
obj->Target = target;
@@ -155,6 +156,11 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
(void) ctx;
+ /* Set Target to an invalid value. With some assertions elsewhere
+ * we can try to detect possible use of deleted textures.
+ */
+ texObj->Target = 0x99;
+
#if FEATURE_colortable
_mesa_free_colortable_data(&texObj->Palette);
#endif
@@ -168,6 +174,9 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
}
}
+ /* destroy the mutex -- it may have allocated memory (eg on bsd) */
+ _glthread_DESTROY_MUTEX(texObj->Mutex);
+
/* free this object */
_mesa_free(texObj);
}
@@ -186,6 +195,7 @@ void
_mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src )
{
+ dest->Target = src->Target;
dest->Name = src->Name;
dest->Priority = src->Priority;
dest->BorderColor[0] = src->BorderColor[0];
@@ -218,6 +228,94 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
/**
+ * Check if the given texture object is valid by examining its Target field.
+ * For debugging only.
+ */
+static GLboolean
+valid_texture_object(const struct gl_texture_object *tex)
+{
+ switch (tex->Target) {
+ case 0:
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ return GL_TRUE;
+ case 0x99:
+ _mesa_problem(NULL, "invalid reference to a deleted texture object");
+ return GL_FALSE;
+ default:
+ _mesa_problem(NULL, "invalid texture object Target value");
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Reference (or unreference) a texture object.
+ * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
+ * If 'tex' is non-null, increment its refcount.
+ */
+void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+ struct gl_texture_object *tex)
+{
+ assert(ptr);
+ if (*ptr == tex) {
+ /* no change */
+ return;
+ }
+
+ if (*ptr) {
+ /* Unreference the old texture */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_texture_object *oldTex = *ptr;
+
+ assert(valid_texture_object(oldTex));
+
+ _glthread_LOCK_MUTEX(oldTex->Mutex);
+ ASSERT(oldTex->RefCount > 0);
+ oldTex->RefCount--;
+
+ deleteFlag = (oldTex->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldTex->Mutex);
+
+ if (deleteFlag) {
+ GET_CURRENT_CONTEXT(ctx);
+ if (ctx)
+ ctx->Driver.DeleteTexture(ctx, oldTex);
+ else
+ _mesa_problem(NULL, "Unable to delete texture, no context");
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (tex) {
+ /* reference new texture */
+ assert(valid_texture_object(tex));
+ _glthread_LOCK_MUTEX(tex->Mutex);
+ if (tex->RefCount == 0) {
+ /* this texture's being deleted (look just above) */
+ /* Not sure this can every really happen. Warn if it does. */
+ _mesa_problem(NULL, "referencing deleted texture object");
+ *ptr = NULL;
+ }
+ else {
+ tex->RefCount++;
+ *ptr = tex;
+ }
+ _glthread_UNLOCK_MUTEX(tex->Mutex);
+ }
+}
+
+
+
+/**
* Report why a texture object is incomplete.
*
* \param t texture object.
@@ -613,8 +711,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
/**
* Check if the given texture object is bound to any texture image units and
- * unbind it if so.
- * XXX all RefCount accesses should be protected by a mutex.
+ * unbind it if so (revert to default textures).
*/
static void
unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
@@ -623,42 +720,26 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
- struct gl_texture_object **curr = NULL;
-
if (texObj == unit->Current1D) {
- curr = &unit->Current1D;
- unit->Current1D = ctx->Shared->Default1D;
+ _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D);
}
else if (texObj == unit->Current2D) {
- curr = &unit->Current2D;
- unit->Current2D = ctx->Shared->Default2D;
+ _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D);
}
else if (texObj == unit->Current3D) {
- curr = &unit->Current3D;
- unit->Current3D = ctx->Shared->Default3D;
+ _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D);
}
else if (texObj == unit->CurrentCubeMap) {
- curr = &unit->CurrentCubeMap;
- unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
}
else if (texObj == unit->CurrentRect) {
- curr = &unit->CurrentRect;
- unit->CurrentRect = ctx->Shared->DefaultRect;
+ _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect);
}
else if (texObj == unit->Current1DArray) {
- curr = &unit->Current1DArray;
- unit->CurrentRect = ctx->Shared->Default1DArray;
+ _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray);
}
else if (texObj == unit->Current2DArray) {
- curr = &unit->Current1DArray;
- unit->CurrentRect = ctx->Shared->Default2DArray;
- }
-
- if (curr) {
- (*curr)->RefCount++;
- texObj->RefCount--;
- if (texObj == unit->_Current)
- unit->_Current = *curr;
+ _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray);
}
}
}
@@ -694,8 +775,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
= _mesa_lookup_texture(ctx, textures[i]);
if (delObj) {
- GLboolean deleted;
-
_mesa_lock_texture(ctx, delObj);
/* Check if texture is bound to any framebuffer objects.
@@ -705,10 +784,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
unbind_texobj_from_fbo(ctx, delObj);
/* Check if this texture is currently bound to any texture units.
- * If so, unbind it and decrement the reference count.
+ * If so, unbind it.
*/
unbind_texobj_from_texunits(ctx, delObj);
+ _mesa_unlock_texture(ctx, delObj);
+
ctx->NewState |= _NEW_TEXTURE;
/* The texture _name_ is now free for re-use.
@@ -718,23 +799,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
_mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- /* The actual texture object will not be freed until it's no
- * longer bound in any context.
- * XXX all RefCount accesses should be protected by a mutex.
+ /* Unreference the texobj. If refcount hits zero, the texture
+ * will be deleted.
*/
- delObj->RefCount--;
- deleted = (delObj->RefCount == 0);
- _mesa_unlock_texture(ctx, delObj);
-
- /* We know that refcount went to zero above, so this is
- * the only pointer left to delObj, so we don't have to
- * worry about locking any more:
- */
- if (deleted) {
- ASSERT(delObj->Name != 0); /* Never delete default tex objs */
- ASSERT(ctx->Driver.DeleteTexture);
- (*ctx->Driver.DeleteTexture)(ctx, delObj);
- }
+ _mesa_reference_texobj(&delObj, NULL);
}
}
}
@@ -762,7 +830,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
GET_CURRENT_CONTEXT(ctx);
const GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *oldTexObj;
struct gl_texture_object *newTexObj = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -771,62 +838,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
_mesa_lookup_enum_by_nr(target), (GLint) texName);
/*
- * Get pointer to currently bound texture object (oldTexObj)
- */
- switch (target) {
- case GL_TEXTURE_1D:
- oldTexObj = texUnit->Current1D;
- break;
- case GL_TEXTURE_2D:
- oldTexObj = texUnit->Current2D;
- break;
- case GL_TEXTURE_3D:
- oldTexObj = texUnit->Current3D;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- if (!ctx->Extensions.ARB_texture_cube_map) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
- return;
- }
- oldTexObj = texUnit->CurrentCubeMap;
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- if (!ctx->Extensions.NV_texture_rectangle) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
- return;
- }
- oldTexObj = texUnit->CurrentRect;
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
- return;
- }
- oldTexObj = texUnit->Current1DArray;
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- if (!ctx->Extensions.MESA_texture_array) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
- return;
- }
- oldTexObj = texUnit->Current2DArray;
- break;
- default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
- return;
- }
-
- if (oldTexObj->Name == texName) {
- /* XXX this might be wrong. If the texobj is in use by another
- * context and a texobj parameter was changed, this might be our
- * only chance to update this context's hardware state.
- * Note that some applications re-bind the same texture a lot so we
- * want to handle that case quickly.
- */
- return; /* rebinding the same texture- no change */
- }
-
- /*
* Get pointer to new texture object (newTexObj)
*/
if (texName == 0) {
@@ -854,7 +865,8 @@ _mesa_BindTexture( GLenum target, GLuint texName )
newTexObj = ctx->Shared->Default2DArray;
break;
default:
- ; /* Bad targets are caught above */
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
+ return;
}
}
else {
@@ -900,28 +912,30 @@ _mesa_BindTexture( GLenum target, GLuint texName )
newTexObj->Target = target;
}
- /* XXX all RefCount accesses should be protected by a mutex. */
- newTexObj->RefCount++;
+ assert(valid_texture_object(newTexObj));
- /* do the actual binding, but first flush outstanding vertices:
- */
+ /* flush before changing binding */
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ /* Do the actual binding. The refcount on the previously bound
+ * texture object will be decremented. It'll be deleted if the
+ * count hits zero.
+ */
switch (target) {
case GL_TEXTURE_1D:
- texUnit->Current1D = newTexObj;
+ _mesa_reference_texobj(&texUnit->Current1D, newTexObj);
break;
case GL_TEXTURE_2D:
- texUnit->Current2D = newTexObj;
+ _mesa_reference_texobj(&texUnit->Current2D, newTexObj);
break;
case GL_TEXTURE_3D:
- texUnit->Current3D = newTexObj;
+ _mesa_reference_texobj(&texUnit->Current3D, newTexObj);
break;
case GL_TEXTURE_CUBE_MAP_ARB:
- texUnit->CurrentCubeMap = newTexObj;
+ _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj);
break;
case GL_TEXTURE_RECTANGLE_NV:
- texUnit->CurrentRect = newTexObj;
+ _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj);
break;
case GL_TEXTURE_1D_ARRAY_EXT:
texUnit->Current1DArray = newTexObj;
@@ -930,6 +944,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
texUnit->Current2DArray = newTexObj;
break;
default:
+ /* Bad target should be caught above */
_mesa_problem(ctx, "bad target in BindTexture");
return;
}
@@ -937,18 +952,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
/* Pass BindTexture call to device driver */
if (ctx->Driver.BindTexture)
(*ctx->Driver.BindTexture)( ctx, target, newTexObj );
-
- /* Decrement the reference count on the old texture and check if it's
- * time to delete it.
- */
- /* XXX all RefCount accesses should be protected by a mutex. */
- oldTexObj->RefCount--;
- ASSERT(oldTexObj->RefCount >= 0);
- if (oldTexObj->RefCount == 0) {
- ASSERT(oldTexObj->Name != 0);
- ASSERT(ctx->Driver.DeleteTexture);
- (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
- }
}
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 2a2bde3601..d5374c5d6c 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -58,6 +58,10 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
extern void
+_mesa_reference_texobj(struct gl_texture_object **ptr,
+ struct gl_texture_object *tex);
+
+extern void
_mesa_test_texobj_completeness( const GLcontext *ctx,
struct gl_texture_object *obj );
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 421f912849..20f9c4512c 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -62,31 +62,6 @@ static const struct gl_tex_env_combine_state default_combine_state = {
};
-/**
- * Copy a texture binding. Helper used by _mesa_copy_texture_state().
- */
-static void
-copy_texture_binding(const GLcontext *ctx,
- struct gl_texture_object **dst,
- struct gl_texture_object *src)
-{
- /* only copy if names differ (per OpenGL SI) */
- if ((*dst)->Name != src->Name) {
- /* unbind/delete dest binding which we're changing */
- (*dst)->RefCount--;
- if ((*dst)->RefCount == 0) {
- /* time to delete this texture object */
- ASSERT((*dst)->Name != 0);
- ASSERT(ctx->Driver.DeleteTexture);
- /* XXX cast-away const, unfortunately */
- (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst);
- }
- /* make new binding, incrementing ref count */
- *dst = src;
- src->RefCount++;
- }
-}
-
/**
* Used by glXCopyContext to copy texture state from one context to another.
@@ -143,20 +118,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
/* copy texture object bindings, not contents of texture objects */
_mesa_lock_context_textures(dst);
- copy_texture_binding(src, &dst->Texture.Unit[i].Current1D,
- src->Texture.Unit[i].Current1D);
- copy_texture_binding(src, &dst->Texture.Unit[i].Current2D,
- src->Texture.Unit[i].Current2D);
- copy_texture_binding(src, &dst->Texture.Unit[i].Current3D,
- src->Texture.Unit[i].Current3D);
- copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap,
- src->Texture.Unit[i].CurrentCubeMap);
- copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
- src->Texture.Unit[i].CurrentRect);
- copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray,
- src->Texture.Unit[i].Current1DArray);
- copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray,
- src->Texture.Unit[i].Current2DArray);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
+ src->Texture.Unit[i].Current1D);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
+ src->Texture.Unit[i].Current2D);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
+ src->Texture.Unit[i].Current3D);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
+ src->Texture.Unit[i].CurrentCubeMap);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
+ src->Texture.Unit[i].CurrentRect);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray,
+ src->Texture.Unit[i].Current1DArray);
+ _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray,
+ src->Texture.Unit[i].Current2DArray);
_mesa_unlock_context_textures(dst);
}
@@ -699,52 +674,32 @@ _mesa_update_texture( GLcontext *ctx, GLuint new_state )
static GLboolean
alloc_proxy_textures( GLcontext *ctx )
{
- ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
- if (!ctx->Texture.Proxy1D)
- goto cleanup;
-
- ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
- if (!ctx->Texture.Proxy2D)
- goto cleanup;
-
- ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
- if (!ctx->Texture.Proxy3D)
- goto cleanup;
-
- ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
- if (!ctx->Texture.ProxyCubeMap)
- goto cleanup;
-
- ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
- if (!ctx->Texture.ProxyRect)
- goto cleanup;
-
- ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
- if (!ctx->Texture.Proxy1DArray)
- goto cleanup;
-
- ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
- if (!ctx->Texture.Proxy2DArray)
- goto cleanup;
+ static const GLenum targets[] = {
+ GL_TEXTURE_1D,
+ GL_TEXTURE_2D,
+ GL_TEXTURE_3D,
+ GL_TEXTURE_CUBE_MAP_ARB,
+ GL_TEXTURE_RECTANGLE_NV,
+ GL_TEXTURE_1D_ARRAY_EXT,
+ GL_TEXTURE_2D_ARRAY_EXT
+ };
+ GLint tgt;
+
+ ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
+
+ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
+ if (!(ctx->Texture.ProxyTex[tgt]
+ = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
+ /* out of memory, free what we did allocate */
+ while (--tgt >= 0) {
+ ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
+ }
+ return GL_FALSE;
+ }
+ }
+ assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
return GL_TRUE;
-
- cleanup:
- if (ctx->Texture.Proxy1D)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
- if (ctx->Texture.Proxy2D)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
- if (ctx->Texture.Proxy3D)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
- if (ctx->Texture.ProxyCubeMap)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
- if (ctx->Texture.ProxyRect)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
- if (ctx->Texture.Proxy1DArray)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray);
- if (ctx->Texture.Proxy2DArray)
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray);
- return GL_FALSE;
}
@@ -786,13 +741,14 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
- texUnit->Current1D = ctx->Shared->Default1D;
- texUnit->Current2D = ctx->Shared->Default2D;
- texUnit->Current3D = ctx->Shared->Default3D;
- texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
- texUnit->CurrentRect = ctx->Shared->DefaultRect;
- texUnit->Current1DArray = ctx->Shared->Default1DArray;
- texUnit->Current2DArray = ctx->Shared->Default2DArray;
+ /* initialize current texture object ptrs to the shared default objects */
+ _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D);
+ _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D);
+ _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D);
+ _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
+ _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
+ _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray);
+ _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray);
}
@@ -807,25 +763,22 @@ _mesa_init_texture(GLcontext *ctx)
assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
- /* Effectively bind the default textures to all texture units */
- ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS;
- ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS;
-
/* Texture group */
ctx->Texture.CurrentUnit = 0; /* multitexture */
ctx->Texture._EnabledUnits = 0;
- for (i=0; i<MAX_TEXTURE_UNITS; i++)
- init_texture_unit( ctx, i );
ctx->Texture.SharedPalette = GL_FALSE;
#if FEATURE_colortable
_mesa_init_colortable(&ctx->Texture.Palette);
#endif
+ for (i = 0; i < MAX_TEXTURE_UNITS; i++)
+ init_texture_unit( ctx, i );
+
+ /* After we're done initializing the context's texture state the default
+ * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
+ */
+ assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1);
+
/* Allocate proxy textures */
if (!alloc_proxy_textures( ctx ))
return GL_FALSE;
@@ -840,14 +793,24 @@ _mesa_init_texture(GLcontext *ctx)
void
_mesa_free_texture_data(GLcontext *ctx)
{
+ GLuint u, tgt;
+
+ /* unreference current textures */
+ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+ struct gl_texture_unit *unit = ctx->Texture.Unit + u;
+ _mesa_reference_texobj(&unit->Current1D, NULL);
+ _mesa_reference_texobj(&unit->Current2D, NULL);
+ _mesa_reference_texobj(&unit->Current3D, NULL);
+ _mesa_reference_texobj(&unit->CurrentCubeMap, NULL);
+ _mesa_reference_texobj(&unit->CurrentRect, NULL);
+ _mesa_reference_texobj(&unit->Current1DArray, NULL);
+ _mesa_reference_texobj(&unit->Current2DArray, NULL);
+ }
+
/* Free proxy texture objects */
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray );
- (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray );
+ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
+ ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
+
#if FEATURE_colortable
{
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index a6bbdc64f1..ff583352ce 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -1133,7 +1133,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
struct arb_program *Program,
gl_state_index state_tokens[STATE_LENGTH])
{
- switch (*(*inst)++) {
+ GLubyte token = *(*inst)++;
+
+ switch (token) {
case STATE_MATERIAL_PARSER:
state_tokens[0] = STATE_MATERIAL;
state_tokens[1] = parse_face_type (inst);
@@ -1318,7 +1320,6 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
case STATE_CLIP_PLANE:
state_tokens[0] = STATE_CLIPPLANE;
- state_tokens[1] = parse_integer (inst, Program);
if (parse_clipplane_num (ctx, inst, Program,
(GLint *) &state_tokens[1]))
return 1;
@@ -1770,7 +1771,9 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
GLfloat const_values[4];
- switch (*(*inst)++) {
+ GLubyte token = *(*inst)++;
+
+ switch (token) {
case PARAM_STATE_ELEMENT:
if (parse_state_single_item (ctx, inst, Program, state_tokens))
return 1;
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 3e28d92fe1..c1fbcde61e 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -955,12 +955,15 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
}
+#define MAX_UNIFORM_ELEMENTS 16
+
/**
- * Called via ctx->Driver.GetUniformfv().
+ * Helper for GetUniformfv(), GetUniformiv()
+ * Returns number of elements written to 'params' output.
*/
-static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
- GLfloat *params)
+static GLuint
+get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+ GLfloat *params)
{
struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
@@ -984,9 +987,13 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
ASSERT(prog);
if (prog) {
+ /* See uniformiv() below */
+ assert(prog->Parameters->Parameters[progPos].Size <= MAX_UNIFORM_ELEMENTS);
+
for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) {
params[i] = prog->Parameters->ParameterValues[progPos][i];
}
+ return prog->Parameters->Parameters[progPos].Size;
}
}
else {
@@ -996,6 +1003,35 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
else {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
}
+ return 0;
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformfv().
+ */
+static void
+_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+ GLfloat *params)
+{
+ (void) get_uniformfv(ctx, program, location, params);
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformiv().
+ */
+static void
+_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+ GLint *params)
+{
+ GLfloat fparams[MAX_UNIFORM_ELEMENTS];
+ GLuint n = get_uniformfv(ctx, program, location, fparams);
+ GLuint i;
+ assert(n <= MAX_UNIFORM_ELEMENTS);
+ for (i = 0; i < n; i++) {
+ params[i] = (GLint) fparams[i];
+ }
}
@@ -1011,6 +1047,11 @@ _mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
if (!shProg)
return -1;
+ if (shProg->LinkStatus == GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
+ return -1;
+ }
+
/* XXX we should return -1 if the uniform was declared, but not
* actually used.
*/
@@ -1408,6 +1449,7 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
driver->GetShaderInfoLog = _mesa_get_shader_info_log;
driver->GetShaderSource = _mesa_get_shader_source;
driver->GetUniformfv = _mesa_get_uniformfv;
+ driver->GetUniformiv = _mesa_get_uniformiv;
driver->GetUniformLocation = _mesa_get_uniform_location;
driver->IsProgram = _mesa_is_program;
driver->IsShader = _mesa_is_shader;
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 14fa38c3cd..af45dfb2e8 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -924,6 +924,30 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
}
+/**
+ * Recursively traverse 'oper', replacing occurances of 'oldScope' with
+ * 'newScope' in the oper->locals->outer_scope filed.
+ *
+ * This is used after function inlining to update the scoping of
+ * the newly copied/inlined code so that vars are found in the new,
+ * inlined scope and not in the original function code.
+ */
+static void
+slang_replace_scope(slang_operation *oper,
+ slang_variable_scope *oldScope,
+ slang_variable_scope *newScope)
+{
+ GLuint i;
+ if (oper->locals != newScope &&
+ oper->locals->outer_scope == oldScope) {
+ oper->locals->outer_scope = newScope;
+ }
+ for (i = 0; i < oper->num_children; i++) {
+ slang_replace_scope(&oper->children[i], oldScope, newScope);
+ }
+}
+
+
/**
* Produce inline code for a call to an assembly instruction.
@@ -985,6 +1009,13 @@ slang_inline_asm_function(slang_assemble_ctx *A,
_slang_free(substOld);
_slang_free(substNew);
+#if 0
+ printf("+++++++++++++ inlined asm function %s +++++++++++++\n",
+ (char *) fun->header.a_name);
+ slang_print_tree(inlined, 3);
+ printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+#endif
+
return inlined;
}
@@ -1012,6 +1043,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
slang_operation **substNew;
GLuint substCount, numCopyIn, i;
slang_function *prevFunction;
+ slang_variable_scope *newScope = NULL;
/* save / push */
prevFunction = A->CurFunction;
@@ -1029,7 +1061,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
_slang_alloc(totalArgs * sizeof(slang_operation *));
#if 0
- printf("Inline call to %s (total vars=%d nparams=%d)\n",
+ printf("\nInline call to %s (total vars=%d nparams=%d)\n",
(char *) fun->header.a_name,
fun->parameters->num_variables, numArgs);
#endif
@@ -1179,9 +1211,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
slang_operation *decl = slang_operation_insert(&inlined->num_children,
&inlined->children,
numCopyIn);
- /*
- printf("COPY_IN %s from expr\n", (char*)p->a_name);
- */
+
decl->type = SLANG_OPER_VARIABLE_DECL;
assert(decl->locals);
decl->locals->outer_scope = inlined->locals;
@@ -1192,6 +1222,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
/* child[0] is the var's initializer */
slang_operation_copy(&decl->children[0], args + i);
+ /* add parameter 'p' to the local variable scope here */
+ {
+ slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
+ pCopy->type = p->type;
+ pCopy->a_name = p->a_name;
+ pCopy->array_len = p->array_len;
+ }
+
+ newScope = inlined->locals;
numCopyIn++;
}
}
@@ -1231,8 +1270,15 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
_slang_free(substOld);
_slang_free(substNew);
+ /* Update scoping to use the new local vars instead of the
+ * original function's vars. This is especially important
+ * for nested inlining.
+ */
+ if (newScope)
+ slang_replace_scope(inlined, fun->parameters, newScope);
+
#if 0
- printf("Done Inline call to %s (total vars=%d nparams=%d)\n",
+ printf("Done Inline call to %s (total vars=%d nparams=%d)\n\n",
(char *) fun->header.a_name,
fun->parameters->num_variables, numArgs);
slang_print_tree(top, 0);
@@ -2063,7 +2109,11 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
n = new_node0(IR_VAR_DECL);
if (n) {
_slang_attach_storage(n, var);
-
+#if 0
+ printf("%s var %p %s store=%p\n",
+ __FUNCTION__, (void *) var, (char *) var->a_name,
+ (void *) n->Store);
+#endif
assert(var->aux);
assert(n->Store == var->aux);
assert(n->Store);
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index e2117c03e6..ccb04494bf 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1634,6 +1634,15 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
return 0;
}
+ /* allocate global address space for a variable with a known size */
+ if (C->global_scope
+ && !(var->type.specifier.type == SLANG_SPEC_ARRAY
+ && var->array_len == 0)) {
+ if (!calculate_var_size(C, O, var))
+ return GL_FALSE;
+ var->address = slang_var_pool_alloc(O->global_pool, var->size);
+ }
+
/* emit code for global var decl */
if (C->global_scope) {
slang_assemble_ctx A;
@@ -1648,15 +1657,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
return 0;
}
- /* allocate global address space for a variable with a known size */
- if (C->global_scope
- && !(var->type.specifier.type == SLANG_SPEC_ARRAY
- && var->array_len == 0)) {
- if (!calculate_var_size(C, O, var))
- return GL_FALSE;
- var->address = slang_var_pool_alloc(O->global_pool, var->size);
- }
-
/* initialize global variable */
if (C->global_scope) {
if (var->initializer != NULL) {
@@ -2167,6 +2167,9 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader)
type = SLANG_UNIT_FRAGMENT_SHADER;
}
+ if (!shader->Source)
+ return GL_FALSE;
+
ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
/* XXX temporary hack */
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
index 31ad94183c..16c36aad0c 100644
--- a/src/mesa/shader/slang/slang_ir.c
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -218,12 +218,14 @@ storage_string(const slang_ir_storage *st)
"NAMED_PARAM",
"CONSTANT",
"UNIFORM",
+ "VARYING",
"WRITE_ONLY",
"ADDRESS",
"SAMPLER",
"UNDEFINED"
};
static char s[100];
+ assert(Elements(files) == PROGRAM_FILE_MAX);
#if 0
if (st->Size == 1)
sprintf(s, "%s[%d]", files[st->File], st->Index);
diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c
index 4a7d4bbbc7..ff9c62c929 100644
--- a/src/mesa/shader/slang/slang_print.c
+++ b/src/mesa/shader/slang/slang_print.c
@@ -171,9 +171,15 @@ static void
print_binary(const slang_operation *op, const char *oper, int indent)
{
assert(op->num_children == 2);
+ printf("binary at %p locals=%p outer=%p\n",
+ (void *) op,
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
slang_print_tree(&op->children[0], indent + 3);
spaces(indent);
- printf("%s\n", oper);
+ printf("%s at %p locals=%p outer=%p\n",
+ oper, (void *) op, (void *) op->locals,
+ (void *) op->locals->outer_scope);
slang_print_tree(&op->children[1], indent + 3);
}
@@ -185,11 +191,13 @@ print_generic2(const slang_operation *op, const char *oper,
GLuint i;
if (oper) {
spaces(indent);
- printf("[%p locals %p] %s %s\n", (void*) op, (void*) op->locals, oper, s);
+ printf("%s %s at %p locals=%p outer=%p\n",
+ oper, s, (void *) op, (void *) op->locals,
+ (void *) op->locals->outer_scope);
}
for (i = 0; i < op->num_children; i++) {
spaces(indent);
- printf("//child %u:\n", i);
+ printf("//child %u of %u:\n", i, op->num_children);
slang_print_tree(&op->children[i], indent);
}
}
@@ -244,7 +252,7 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
spaces(indent);
- printf("{ locals %p outer %p\n", (void*)op->locals, (void*)op->locals->outer_scope);
+ printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
print_generic(op, NULL, indent+3);
spaces(indent);
printf("}\n");
@@ -252,7 +260,14 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_BLOCK_NEW_SCOPE:
spaces(indent);
- printf("{{ // new scope locals %p\n", (void*)op->locals);
+ printf("{{ // new scope locals=%p: ", (void*)op->locals);
+ {
+ int i;
+ for (i = 0; i < op->locals->num_variables; i++) {
+ printf("%s ", (char *) op->locals->variables[i]->a_name);
+ }
+ printf("\n");
+ }
print_generic(op, NULL, indent+3);
spaces(indent);
printf("}}\n");
@@ -264,14 +279,16 @@ slang_print_tree(const slang_operation *op, int indent)
slang_variable *v;
v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
if (v) {
+ const slang_variable_scope *scope;
spaces(indent);
printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
print_type(&v->type);
printf(" %s (%p)", (char *) op->a_id,
(void *) find_var(op->locals, op->a_id));
- printf(" (in scope %p) ",
- (void *) find_scope(op->locals, op->a_id));
+ scope = find_scope(op->locals, op->a_id);
+ printf(" (in scope %p) ", (void *) scope);
+ assert(scope);
if (op->num_children == 1) {
printf(" :=\n");
slang_print_tree(&op->children[0], indent + 3);
@@ -300,8 +317,12 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_ASM:
spaces(indent);
- printf("ASM: %s\n", (char*) op->a_id);
- print_generic(op, NULL, indent+3);
+ printf("ASM: %s at %p locals=%p outer=%p\n",
+ (char *) op->a_id,
+ (void *) op,
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
+ print_generic(op, "ASM", indent+3);
break;
case SLANG_OPER_BREAK:
@@ -333,7 +354,9 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_EXPRESSION:
spaces(indent);
- printf("EXPR: locals %p\n", (void*) op->locals);
+ printf("EXPR: locals=%p outer=%p\n",
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
/*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
slang_print_tree(&op->children[0], indent + 3);
break;
@@ -422,13 +445,25 @@ slang_print_tree(const slang_operation *op, int indent)
break;
case SLANG_OPER_IDENTIFIER:
- spaces(indent);
- if (op->var && op->var->a_name)
- printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
- (void *) find_scope(op->locals, op->a_id));
- else
- printf("VAR' %s (in scope %p)\n", (char *) op->a_id,
- (void *) find_scope(op->locals, op->a_id));
+ {
+ const slang_variable_scope *scope;
+ spaces(indent);
+ if (op->var && op->var->a_name) {
+ scope = find_scope(op->locals, op->var->a_name);
+ printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
+ (void *) scope);
+ assert(scope);
+ }
+ else {
+ scope = find_scope(op->locals, op->a_id);
+ printf("VAR' %s (in scope %p) locals=%p outer=%p\n",
+ (char *) op->a_id,
+ (void *) scope,
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
+ assert(scope);
+ }
+ }
break;
case SLANG_OPER_SEQUENCE:
@@ -437,7 +472,9 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_ASSIGN:
spaces(indent);
- printf("ASSIGNMENT locals %p\n", (void*)op->locals);
+ printf("ASSIGNMENT locals=%p outer=%p\n",
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
print_binary(op, ":=", indent);
break;
@@ -573,7 +610,9 @@ slang_print_tree(const slang_operation *op, int indent)
case SLANG_OPER_SUBSCRIPT:
spaces(indent);
- printf("SLANG_OPER_SUBSCRIPT\n");
+ printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
+ (void *) op->locals,
+ (void *) op->locals->outer_scope);
print_generic(op, NULL, indent+3);
break;
@@ -640,7 +679,8 @@ slang_print_function(const slang_function *f, GLboolean body)
print_variable(f->parameters->variables[i], 3);
}
- printf(")\n");
+ printf(") param scope = %p\n", (void *) f->parameters);
+
if (body && f->body)
slang_print_tree(f->body, 0);
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 7245798d0d..8406bf247f 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -422,7 +422,8 @@ st_finish_render_texture(GLcontext *ctx,
struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(att->Renderbuffer);
- assert(strb);
+ if (!strb)
+ return;
ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 21911774d7..a57d7b6a7a 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -300,9 +300,8 @@ st_draw_vbo(GLcontext *ctx,
vbuffer[attr].buffer = NULL;
pipe_reference_buffer(pipe, &vbuffer[attr].buffer, stobj->buffer);
- vbuffer[attr].buffer_offset = (unsigned) arrays[0]->Ptr;/* in bytes */
- velements[attr].src_offset = arrays[mesaAttr]->Ptr - arrays[0]->Ptr;
- assert(velements[attr].src_offset <= 2048); /* 11-bit field */
+ vbuffer[attr].buffer_offset = (unsigned) arrays[mesaAttr]->Ptr;
+ velements[attr].src_offset = 0;
}
else {
/* attribute data is in user-space memory, not a VBO */
@@ -323,6 +322,8 @@ st_draw_vbo(GLcontext *ctx,
velements[attr].src_offset = 0;
}
+ assert(velements[attr].src_offset <= 2048); /* 11-bit field */
+
/* common-case setup */
vbuffer[attr].pitch = arrays[mesaAttr]->StrideB; /* in bytes */
vbuffer[attr].max_index = max_index;
@@ -335,6 +336,25 @@ st_draw_vbo(GLcontext *ctx,
assert(velements[attr].src_format);
}
+#if 0
+ {
+ GLuint i;
+ char buf[100];
+ for (i = 0; i < vp->num_inputs; i++) {
+ printf("buffers[%d].pitch = %u\n", i, vbuffer[i].pitch);
+ printf("buffers[%d].max_index = %u\n", i, vbuffer[i].max_index);
+ printf("buffers[%d].buffer_offset = %u\n", i, vbuffer[i].buffer_offset);
+ printf("buffers[%d].buffer = %p\n", i, (void*) vbuffer[i].buffer);
+ }
+ for (i = 0; i < vp->num_inputs; i++) {
+ printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset);
+ printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index);
+ printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components);
+ printf("vlements[%d].format = %s\n", i, pf_sprint_name(buf, velements[i].src_format));
+ }
+ }
+#endif
+
pipe->set_vertex_buffers(pipe, vp->num_inputs, vbuffer);
pipe->set_vertex_elements(pipe, vp->num_inputs, velements);
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 03ec558a36..50a06868df 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -362,7 +362,10 @@ st_choose_format(struct pipe_context *pipe, GLint internalFormat,
case GL_RGBA12:
return default_rgba_format( screen, surfType );
case GL_RGBA16:
- return default_deep_rgba_format( screen, surfType );
+ if (surfType == PIPE_SURFACE)
+ return default_deep_rgba_format( screen, surfType );
+ else
+ return default_rgba_format( screen, surfType );
case GL_RGBA4:
case GL_RGBA2:
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h
index 59cd7f6984..5362226c2f 100644
--- a/src/mesa/vbo/vbo.h
+++ b/src/mesa/vbo/vbo.h
@@ -120,19 +120,19 @@ void vbo_use_buffer_objects(GLcontext *ctx);
void vbo_set_draw_func(GLcontext *ctx, vbo_draw_func func);
-void
+void GLAPIENTRY
_vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
-void
+void GLAPIENTRY
_vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z);
-void
+void GLAPIENTRY
_vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
-void
+void GLAPIENTRY
_vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params);
-void
+void GLAPIENTRY
_vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
#endif
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 2c2e66dd0b..579bbeb4f3 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -770,34 +770,34 @@ static void reset_attrfv( struct vbo_exec_context *exec )
}
-void
+void GLAPIENTRY
_vbo_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
vbo_Color4f(r, g, b, a);
}
-void
+void GLAPIENTRY
_vbo_Normal3f(GLfloat x, GLfloat y, GLfloat z)
{
vbo_Normal3f(x, y, z);
}
-void
+void GLAPIENTRY
_vbo_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
vbo_MultiTexCoord4f(target, s, t, r, q);
}
-void
+void GLAPIENTRY
_vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
{
vbo_Materialfv(face, pname, params);
}
-void
+void GLAPIENTRY
_vbo_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
vbo_VertexAttrib4fARB(index, x, y, z, w);