X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=e0630c33d0b0c95439f41688b333df75a6a15743;hb=6340d6bf22ad0bfedf8565500336237a8da887f5;hp=89154eb72a6b5d562e0e7f41c93ac840f5e5083e;hpb=4d859f73fce9918381c65da55f046a7c605c9e65;p=mesa.git
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 89154eb72a6..e0630c33d0b 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -6,9 +6,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.5
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -30,18 +30,23 @@
/**
- * \mainpage Mesa Core Module
+ * \mainpage Mesa Main Module
*
- * \section CoreIntroduction Introduction
+ * \section MainIntroduction Introduction
*
- * The Mesa core module consists of all the top-level files in the src
- * directory. The core module basically takes care of API dispatch,
- * and OpenGL state management.
+ * The Mesa Main module consists of all the files in the main/ directory.
+ * Among the features of this module are:
+ *
+ * - Structures to represent most GL state
+ * - State set/get functions
+ * - Display lists
+ * - Texture unit, object and image handling
+ * - Matrix and attribute stacks
+ *
*
- * For example, calls to glPolygonMode() are routed to _mesa_PolygonMode()
- * which updates the state related to polygonmode. Furthermore, dirty
- * state flags related to polygon mode are set and if the device driver
- * implements a special routine for PolygonMode, it will be called.
+ * Other modules are responsible for API dispatch, vertex transformation,
+ * point/line/triangle setup, rasterization, vertex array caching,
+ * vertex/fragment programs/shaders, etc.
*
*
* \section AboutDoxygen About Doxygen
@@ -74,6 +79,7 @@
#include "glheader.h"
#include "imports.h"
#include "accum.h"
+#include "arrayobj.h"
#include "attrib.h"
#include "blend.h"
#include "buffers.h"
@@ -86,6 +92,7 @@
#include "eval.h"
#include "enums.h"
#include "extensions.h"
+#include "fbobject.h"
#include "feedback.h"
#include "fog.h"
#include "get.h"
@@ -94,6 +101,7 @@
#include "histogram.h"
#include "hint.h"
#include "hash.h"
+#include "atifragshader.h"
#include "light.h"
#include "lines.h"
#include "macros.h"
@@ -109,11 +117,13 @@
#include "simple_list.h"
#include "state.h"
#include "stencil.h"
+#include "texcompress.h"
#include "teximage.h"
#include "texobj.h"
#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
+#include "version.h"
#include "vtxfmt.h"
#if _HAVE_FULL_GL
#include "math/m_translate.h"
@@ -121,9 +131,10 @@
#include "math/m_xform.h"
#include "math/mathmod.h"
#endif
+#include "shaderobjects.h"
#ifdef USE_SPARC_ASM
-#include "SPARC/sparc.h"
+#include "sparc/sparc.h"
#endif
#ifndef MESA_VERBOSE
@@ -191,6 +202,7 @@ GLboolean
_mesa_loseCurrent(__GLcontext *gc)
{
/* XXX unbind context from thread */
+ (void) gc;
return GL_TRUE;
}
@@ -211,6 +223,7 @@ GLboolean
_mesa_makeCurrent(__GLcontext *gc)
{
/* XXX bind context to thread */
+ (void) gc;
return GL_TRUE;
}
@@ -266,6 +279,7 @@ _mesa_copyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
GLboolean
_mesa_forceCurrent(__GLcontext *gc)
{
+ (void) gc;
return GL_TRUE;
}
@@ -301,6 +315,7 @@ void
_mesa_notifyDestroy(__GLcontext *gc)
{
/* Unbind from it. */
+ (void) gc;
}
/**
@@ -321,6 +336,7 @@ _mesa_notifySwapBuffers(__GLcontext *gc)
struct __GLdispatchStateRec *
_mesa_dispatchExec(__GLcontext *gc)
{
+ (void) gc;
return NULL;
}
@@ -328,12 +344,14 @@ _mesa_dispatchExec(__GLcontext *gc)
void
_mesa_beginDispatchOverride(__GLcontext *gc)
{
+ (void) gc;
}
/** No-op */
void
_mesa_endDispatchOverride(__GLcontext *gc)
{
+ (void) gc;
}
/**
@@ -371,6 +389,8 @@ _mesa_init_default_exports(__GLexports *exports)
exports->dispatchExec = _mesa_dispatchExec;
exports->beginDispatchOverride = _mesa_beginDispatchOverride;
exports->endDispatchOverride = _mesa_endDispatchOverride;
+#else
+ (void) exports;
#endif
}
@@ -418,7 +438,8 @@ __glCoreNopDispatch(void)
/*@{*/
/**
- * Allocate a new GLvisual object.
+ * Allocates a GLvisual structure and initializes it via
+ * _mesa_initialize_visual().
*
* \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode.
* \param dbFlag double buffering
@@ -439,8 +460,7 @@ __glCoreNopDispatch(void)
* \return pointer to new GLvisual or NULL if requested parameters can't be
* met.
*
- * Allocates a GLvisual structure and initializes it via
- * _mesa_initialize_visual().
+ * \note Need to add params for level and numAuxBuffers (at least)
*/
GLvisual *
_mesa_create_visual( GLboolean rgbFlag,
@@ -459,7 +479,7 @@ _mesa_create_visual( GLboolean rgbFlag,
GLint accumAlphaBits,
GLint numSamples )
{
- GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
+ GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual));
if (vis) {
if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag,
redBits, greenBits, blueBits, alphaBits,
@@ -467,7 +487,7 @@ _mesa_create_visual( GLboolean rgbFlag,
accumRedBits, accumGreenBits,
accumBlueBits, accumAlphaBits,
numSamples)) {
- FREE(vis);
+ _mesa_free(vis);
return NULL;
}
}
@@ -475,14 +495,13 @@ _mesa_create_visual( GLboolean rgbFlag,
}
/**
- * Initialize the fields of the given GLvisual.
- *
+ * Makes some sanity checks and fills in the fields of the
+ * GLvisual object with the given parameters. If the caller needs
+ * to set additional fields, he should just probably init the whole GLvisual
+ * object himself.
* \return GL_TRUE on success, or GL_FALSE on failure.
*
* \sa _mesa_create_visual() above for the parameter description.
- *
- * Makes some sanity checks and fills in the fields of the
- * GLvisual structure with the given parameters.
*/
GLboolean
_mesa_initialize_visual( GLvisual *vis,
@@ -502,34 +521,18 @@ _mesa_initialize_visual( GLvisual *vis,
GLint accumAlphaBits,
GLint numSamples )
{
- (void) numSamples;
-
assert(vis);
- /* This is to catch bad values from device drivers not updated for
- * Mesa 3.3. Some device drivers just passed 1. That's a REALLY
- * bad value now (a 1-bit depth buffer!?!).
- */
- assert(depthBits == 0 || depthBits > 1);
-
if (depthBits < 0 || depthBits > 32) {
return GL_FALSE;
}
- if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) {
- return GL_FALSE;
- }
- if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) {
- return GL_FALSE;
- }
- if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) {
- return GL_FALSE;
- }
- if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) {
- return GL_FALSE;
- }
- if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) {
+ if (stencilBits < 0 || stencilBits > STENCIL_BITS) {
return GL_FALSE;
}
+ assert(accumRedBits >= 0);
+ assert(accumGreenBits >= 0);
+ assert(accumBlueBits >= 0);
+ assert(accumAlphaBits >= 0);
vis->rgbMode = rgbFlag;
vis->doubleBufferMode = dbFlag;
@@ -539,14 +542,16 @@ _mesa_initialize_visual( GLvisual *vis,
vis->greenBits = greenBits;
vis->blueBits = blueBits;
vis->alphaBits = alphaBits;
+ vis->rgbBits = redBits + greenBits + blueBits;
vis->indexBits = indexBits;
vis->depthBits = depthBits;
- vis->accumRedBits = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0;
- vis->accumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0;
- vis->accumBlueBits = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0;
- vis->accumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0;
- vis->stencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0;
+ vis->stencilBits = stencilBits;
+
+ vis->accumRedBits = accumRedBits;
+ vis->accumGreenBits = accumGreenBits;
+ vis->accumBlueBits = accumBlueBits;
+ vis->accumAlphaBits = accumAlphaBits;
vis->haveAccumBuffer = accumRedBits > 0;
vis->haveDepthBuffer = depthBits > 0;
@@ -555,12 +560,15 @@ _mesa_initialize_visual( GLvisual *vis,
vis->numAuxBuffers = 0;
vis->level = 0;
vis->pixmapMode = 0;
+ vis->sampleBuffers = numSamples > 0 ? 1 : 0;
+ vis->samples = numSamples;
return GL_TRUE;
}
+
/**
- * Destroy a visual.
+ * Destroy a visual and free its memory.
*
* \param vis visual.
*
@@ -569,154 +577,7 @@ _mesa_initialize_visual( GLvisual *vis,
void
_mesa_destroy_visual( GLvisual *vis )
{
- FREE(vis);
-}
-
-/*@}*/
-
-
-/**********************************************************************/
-/** \name GL Framebuffer allocation/destruction */
-/**********************************************************************/
-/*@{*/
-
-/**
- * Create a new framebuffer.
- *
- * A GLframebuffer is a structure which encapsulates the depth, stencil and
- * accum buffers and related parameters.
- *
- * \param visual a GLvisual pointer (we copy the struct contents)
- * \param softwareDepth create/use a software depth buffer?
- * \param softwareStencil create/use a software stencil buffer?
- * \param softwareAccum create/use a software accum buffer?
- * \param softwareAlpha create/use a software alpha buffer?
- *
- * \return pointer to new GLframebuffer struct or NULL if error.
- *
- * Allocate a GLframebuffer structure and initializes it via
- * _mesa_initialize_framebuffer().
- */
-GLframebuffer *
-_mesa_create_framebuffer( const GLvisual *visual,
- GLboolean softwareDepth,
- GLboolean softwareStencil,
- GLboolean softwareAccum,
- GLboolean softwareAlpha )
-{
- GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer);
- assert(visual);
- if (buffer) {
- _mesa_initialize_framebuffer(buffer, visual,
- softwareDepth, softwareStencil,
- softwareAccum, softwareAlpha );
- }
- return buffer;
-}
-
-/**
- * Initialize a GLframebuffer object.
- *
- * \sa _mesa_create_framebuffer() above for the parameter description.
- *
- * Makes some sanity checks and fills in the fields of the
- * GLframebuffer structure with the given parameters.
- */
-void
-_mesa_initialize_framebuffer( GLframebuffer *buffer,
- const GLvisual *visual,
- GLboolean softwareDepth,
- GLboolean softwareStencil,
- GLboolean softwareAccum,
- GLboolean softwareAlpha )
-{
- assert(buffer);
- assert(visual);
-
- _mesa_bzero(buffer, sizeof(GLframebuffer));
-
- /* sanity checks */
- if (softwareDepth ) {
- assert(visual->depthBits > 0);
- }
- if (softwareStencil) {
- assert(visual->stencilBits > 0);
- }
- if (softwareAccum) {
- assert(visual->rgbMode);
- assert(visual->accumRedBits > 0);
- assert(visual->accumGreenBits > 0);
- assert(visual->accumBlueBits > 0);
- }
- if (softwareAlpha) {
- assert(visual->rgbMode);
- assert(visual->alphaBits > 0);
- }
-
- buffer->Visual = *visual;
- buffer->UseSoftwareDepthBuffer = softwareDepth;
- buffer->UseSoftwareStencilBuffer = softwareStencil;
- buffer->UseSoftwareAccumBuffer = softwareAccum;
- buffer->UseSoftwareAlphaBuffers = softwareAlpha;
-}
-
-/**
- * Free a framebuffer struct and its buffers.
- *
- * Calls _mesa_free_framebuffer_data() and frees the structure.
- */
-void
-_mesa_destroy_framebuffer( GLframebuffer *buffer )
-{
- if (buffer) {
- _mesa_free_framebuffer_data(buffer);
- FREE(buffer);
- }
-}
-
-/**
- * Free the data hanging off of \p buffer, but not \p buffer itself.
- *
- * \param buffer framebuffer.
- *
- * Frees all the buffers associated with the structure.
- */
-void
-_mesa_free_framebuffer_data( GLframebuffer *buffer )
-{
- if (!buffer)
- return;
-
- if (buffer->UseSoftwareDepthBuffer && buffer->DepthBuffer) {
- MESA_PBUFFER_FREE( buffer->DepthBuffer );
- buffer->DepthBuffer = NULL;
- }
- if (buffer->UseSoftwareAccumBuffer && buffer->Accum) {
- MESA_PBUFFER_FREE( buffer->Accum );
- buffer->Accum = NULL;
- }
- if (buffer->UseSoftwareStencilBuffer && buffer->Stencil) {
- MESA_PBUFFER_FREE( buffer->Stencil );
- buffer->Stencil = NULL;
- }
- if (buffer->UseSoftwareAlphaBuffers){
- if (buffer->FrontLeftAlpha) {
- MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
- buffer->FrontLeftAlpha = NULL;
- }
- if (buffer->BackLeftAlpha) {
- MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
- buffer->BackLeftAlpha = NULL;
- }
- if (buffer->FrontRightAlpha) {
- MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
- buffer->FrontRightAlpha = NULL;
- }
- if (buffer->BackRightAlpha) {
- MESA_PBUFFER_FREE( buffer->BackRightAlpha );
- buffer->BackRightAlpha = NULL;
- }
- }
+ _mesa_free(vis);
}
/*@}*/
@@ -745,25 +606,24 @@ _glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
* and sets the glapi callbacks if the \c MESA_DEBUG environment variable is
* defined.
*
- * \sa _mesa_init_lists(), _math_init().
+ * \sa _math_init().
*/
static void
one_time_init( GLcontext *ctx )
{
static GLboolean alreadyCalled = GL_FALSE;
+ (void) ctx;
_glthread_LOCK_MUTEX(OneTimeLock);
if (!alreadyCalled) {
GLuint i;
/* do some implementation tests */
assert( sizeof(GLbyte) == 1 );
- assert( sizeof(GLshort) >= 2 );
- assert( sizeof(GLint) >= 4 );
assert( sizeof(GLubyte) == 1 );
- assert( sizeof(GLushort) >= 2 );
- assert( sizeof(GLuint) >= 4 );
-
- _mesa_init_lists();
+ assert( sizeof(GLshort) == 2 );
+ assert( sizeof(GLushort) == 2 );
+ assert( sizeof(GLint) == 4 );
+ assert( sizeof(GLuint) == 4 );
#if _HAVE_FULL_GL
_math_init();
@@ -778,20 +638,15 @@ one_time_init( GLcontext *ctx )
#endif
if (_mesa_getenv("MESA_DEBUG")) {
_glapi_noop_enable_warnings(GL_TRUE);
-#ifndef GLX_DIRECT_RENDERING
- /* libGL from before 2002/06/28 don't have this function. Someday,
- * when newer libGL libs are common, remove the #ifdef test. This
- * only serves to print warnings when calling undefined GL functions.
- */
_glapi_set_warning_func( (_glapi_warning_func) _mesa_warning );
-#endif
}
else {
_glapi_noop_enable_warnings(GL_FALSE);
}
#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
- _mesa_debug(ctx, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
+ _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n",
+ MESA_VERSION_STRING, __DATE__, __TIME__);
#endif
alreadyCalled = GL_TRUE;
@@ -799,15 +654,15 @@ one_time_init( GLcontext *ctx )
_glthread_UNLOCK_MUTEX(OneTimeLock);
}
+
/**
* Allocate and initialize a shared context state structure.
- *
- * \return pointer to a gl_shared_state structure on success, or NULL on
- * failure.
- *
* Initializes the display list, texture objects and vertex programs hash
* tables, allocates the texture objects. If it runs out of memory, frees
* everything already allocated before returning NULL.
+ *
+ * \return pointer to a gl_shared_state structure on success, or NULL on
+ * failure.
*/
static GLboolean
alloc_shared_state( GLcontext *ctx )
@@ -836,8 +691,22 @@ alloc_shared_state( GLcontext *ctx )
if (!ss->DefaultFragmentProgram)
goto cleanup;
#endif
+#if FEATURE_ATI_fragment_shader
+ ss->ATIShaders = _mesa_NewHashTable();
+ ss->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0);
+ if (!ss->DefaultFragmentShader)
+ goto cleanup;
+#endif
+#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
ss->BufferObjects = _mesa_NewHashTable();
+#endif
+
+ ss->ArrayObjects = _mesa_NewHashTable();
+
+#if FEATURE_ARB_shader_objects
+ ss->GL2Objects = _mesa_NewHashTable ();
+#endif
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
if (!ss->Default1D)
@@ -866,6 +735,16 @@ alloc_shared_state( GLcontext *ctx )
ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+#if FEATURE_EXT_framebuffer_object
+ ss->FrameBuffers = _mesa_NewHashTable();
+ if (!ss->FrameBuffers)
+ goto cleanup;
+ ss->RenderBuffers = _mesa_NewHashTable();
+ if (!ss->RenderBuffers)
+ goto cleanup;
+#endif
+
+
return GL_TRUE;
cleanup:
@@ -886,8 +765,29 @@ alloc_shared_state( GLcontext *ctx )
if (ss->DefaultFragmentProgram)
ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
+#if FEATURE_ATI_fragment_shader
+ if (ss->DefaultFragmentShader)
+ _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
+#endif
+#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
if (ss->BufferObjects)
_mesa_DeleteHashTable(ss->BufferObjects);
+#endif
+
+ if (ss->ArrayObjects)
+ _mesa_DeleteHashTable (ss->ArrayObjects);
+
+#if FEATURE_ARB_shader_objects
+ if (ss->GL2Objects)
+ _mesa_DeleteHashTable (ss->GL2Objects);
+#endif
+
+#if FEATURE_EXT_framebuffer_object
+ if (ss->FrameBuffers)
+ _mesa_DeleteHashTable(ss->FrameBuffers);
+ if (ss->RenderBuffers)
+ _mesa_DeleteHashTable(ss->RenderBuffers);
+#endif
if (ss->Default1D)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
@@ -904,8 +804,77 @@ alloc_shared_state( GLcontext *ctx )
return GL_FALSE;
}
+
+/**
+ * Callback for deleting a display list. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_displaylist_cb(GLuint id, void *data, void *userData)
+{
+ struct mesa_display_list *list = (struct mesa_display_list *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ _mesa_delete_list(ctx, list);
+}
+
+/**
+ * Callback for deleting a texture object. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_texture_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_texture_object *texObj = (struct gl_texture_object *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ ctx->Driver.DeleteTexture(ctx, texObj);
+}
+
+/**
+ * Callback for deleting a program object. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_program_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_program *prog = (struct gl_program *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ ctx->Driver.DeleteProgram(ctx, prog);
+}
+
+/**
+ * Callback for deleting an ATI fragment shader object.
+ * Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_fragshader_cb(GLuint id, void *data, void *userData)
+{
+ struct ati_fragment_shader *shader = (struct ati_fragment_shader *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ _mesa_delete_ati_fragment_shader(ctx, shader);
+}
+
+/**
+ * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_bufferobj_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ ctx->Driver.DeleteBuffer(ctx, bufObj);
+}
+
+/**
+ * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_arrayobj_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_array_object *arrayObj = (struct gl_array_object *) data;
+ GLcontext *ctx = (GLcontext *) userData;
+ _mesa_delete_array_object(ctx, arrayObj);
+}
+
+
/**
- * Deallocate a shared state context and all children structures.
+ * Deallocate a shared state object and all children structures.
*
* \param ctx GL context.
* \param ss shared state pointer.
@@ -919,58 +888,63 @@ alloc_shared_state( GLcontext *ctx )
static void
free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
{
- /* Free display lists */
- while (1) {
- GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
- if (list) {
- _mesa_destroy_list(ctx, list);
- }
- else {
- break;
- }
- }
+ /*
+ * Free display lists
+ */
+ _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx);
_mesa_DeleteHashTable(ss->DisplayList);
- /* Free texture objects */
+ /*
+ * Free texture objects
+ */
ASSERT(ctx->Driver.DeleteTexture);
- while (1) {
- GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
- if (texName) {
- struct gl_texture_object *texObj = (struct gl_texture_object *)
- _mesa_HashLookup(ss->TexObjects, texName);
- ASSERT(texObj);
- (*ctx->Driver.DeleteTexture)(ctx, texObj);
- _mesa_HashRemove(ss->TexObjects, texName);
- }
- else {
- break;
- }
- }
+ /* the default textures */
+ ctx->Driver.DeleteTexture(ctx, ss->Default1D);
+ ctx->Driver.DeleteTexture(ctx, ss->Default2D);
+ ctx->Driver.DeleteTexture(ctx, ss->Default3D);
+ ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
+ ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
+ /* all other textures */
+ _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
_mesa_DeleteHashTable(ss->TexObjects);
-#if FEATURE_NV_vertex_program
- /* Free vertex programs */
- while (1) {
- GLuint prog = _mesa_HashFirstEntry(ss->Programs);
- if (prog) {
- struct program *p = (struct program *) _mesa_HashLookup(ss->Programs,
- prog);
- ASSERT(p);
- ctx->Driver.DeleteProgram(ctx, p);
- _mesa_HashRemove(ss->Programs, prog);
- }
- else {
- break;
- }
- }
+#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program)
+ _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx);
_mesa_DeleteHashTable(ss->Programs);
#endif
+#if FEATURE_ARB_vertex_program
+ _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+#endif
+#if FEATURE_ARB_fragment_program
+ _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+#endif
+
+#if FEATURE_ATI_fragment_shader
+ _mesa_HashDeleteAll(ss->ATIShaders, delete_fragshader_cb, ctx);
+ _mesa_DeleteHashTable(ss->ATIShaders);
+ _mesa_delete_ati_fragment_shader(ctx, ss->DefaultFragmentShader);
+#endif
+#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
+ _mesa_HashDeleteAll(ss->BufferObjects, delete_bufferobj_cb, ctx);
_mesa_DeleteHashTable(ss->BufferObjects);
+#endif
+
+ _mesa_HashDeleteAll(ss->ArrayObjects, delete_arrayobj_cb, ctx);
+ _mesa_DeleteHashTable(ss->ArrayObjects);
+
+#if FEATURE_ARB_shader_objects
+ _mesa_DeleteHashTable(ss->GL2Objects);
+#endif
+
+#if FEATURE_EXT_framebuffer_object
+ _mesa_DeleteHashTable(ss->FrameBuffers);
+ _mesa_DeleteHashTable(ss->RenderBuffers);
+#endif
_glthread_DESTROY_MUTEX(ss->Mutex);
- FREE(ss);
+ _mesa_free(ss);
}
@@ -980,25 +954,41 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
static void
_mesa_init_current( GLcontext *ctx )
{
- int i;
+ GLuint i;
- /* Current group */
+ /* Init all to (0,0,0,1) */
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
ASSIGN_4V( ctx->Current.Attrib[i], 0.0, 0.0, 0.0, 1.0 );
}
- /* special cases: */
+
+ /* redo special cases: */
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 );
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 );
ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_FOG], 0.0, 0.0, 0.0, 0.0 );
- for (i = 0; i < MAX_TEXTURE_UNITS; i++)
- ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], 0.0, 0.0, 0.0, 1.0);
- ctx->Current.Index = 1;
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0] = 1.0;
ctx->Current.EdgeFlag = GL_TRUE;
}
+/**
+ * Init vertex/fragment program native limits from logical limits.
+ */
+static void
+init_natives(struct gl_program_constants *prog)
+{
+ prog->MaxNativeInstructions = prog->MaxInstructions;
+ prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
+ prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
+ prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
+ prog->MaxNativeAttribs = prog->MaxAttribs;
+ prog->MaxNativeTemps = prog->MaxTemps;
+ prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
+ prog->MaxNativeParameters = prog->MaxParameters;
+}
+
+
/**
* Initialize fields of gl_constants (aka ctx->Const.*).
* Use defaults from config.h. The device drivers will often override
@@ -1012,14 +1002,18 @@ _mesa_init_constants( GLcontext *ctx )
assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
- /* Constants, may be overriden by device drivers */
+ assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_COORD_UNITS);
+ assert(MAX_TEXTURE_UNITS >= MAX_TEXTURE_IMAGE_UNITS);
+
+ /* Constants, may be overriden (usually only reduced) by device drivers */
ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS;
ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS;
ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE;
- ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS;
ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits,
+ ctx->Const.MaxTextureImageUnits);
ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS;
ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
@@ -1034,32 +1028,40 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY;
- ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE;
ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH;
ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT;
ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES;
ctx->Const.MaxLights = MAX_LIGHTS;
- ctx->Const.MaxSpotExponent = 128.0;
ctx->Const.MaxShininess = 128.0;
+ ctx->Const.MaxSpotExponent = 128.0;
+ ctx->Const.MaxViewportWidth = MAX_WIDTH;
+ ctx->Const.MaxViewportHeight = MAX_HEIGHT;
#if FEATURE_ARB_vertex_program
- ctx->Const.MaxVertexProgramInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
- ctx->Const.MaxVertexProgramAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
- ctx->Const.MaxVertexProgramTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
- ctx->Const.MaxVertexProgramLocalParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
- ctx->Const.MaxVertexProgramEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;/*XXX*/
- ctx->Const.MaxVertexProgramAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+ ctx->Const.VertexProgram.MaxInstructions = MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS;
+ ctx->Const.VertexProgram.MaxAluInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexIndirections = 0;
+ ctx->Const.VertexProgram.MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
+ ctx->Const.VertexProgram.MaxTemps = MAX_NV_VERTEX_PROGRAM_TEMPS;
+ ctx->Const.VertexProgram.MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+ ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+ ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
+ ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+ init_natives(&ctx->Const.VertexProgram);
#endif
#if FEATURE_ARB_fragment_program
- ctx->Const.MaxFragmentProgramInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
- ctx->Const.MaxFragmentProgramAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
- ctx->Const.MaxFragmentProgramTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
- ctx->Const.MaxFragmentProgramLocalParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
- ctx->Const.MaxFragmentProgramEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;/*XXX*/
- ctx->Const.MaxFragmentProgramAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
- ctx->Const.MaxFragmentProgramAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
- ctx->Const.MaxFragmentProgramTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
- ctx->Const.MaxFragmentProgramTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
+ ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxTexInstructions = MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
+ ctx->Const.FragmentProgram.MaxTexIndirections = MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
+ ctx->Const.FragmentProgram.MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
+ ctx->Const.FragmentProgram.MaxTemps = MAX_NV_FRAGMENT_PROGRAM_TEMPS;
+ ctx->Const.FragmentProgram.MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
+ ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+ init_natives(&ctx->Const.FragmentProgram);
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
@@ -1073,7 +1075,52 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.CheckArrayBounds = GL_FALSE;
#endif
- ASSERT(ctx->Const.MaxTextureUnits == MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits));
+ /* GL_ARB_draw_buffers */
+ ctx->Const.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+
+ /* GL_OES_read_format */
+ ctx->Const.ColorReadFormat = GL_RGBA;
+ ctx->Const.ColorReadType = GL_UNSIGNED_BYTE;
+
+#if FEATURE_EXT_framebuffer_object
+ ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS;
+ ctx->Const.MaxRenderbufferSize = MAX_WIDTH;
+#endif
+
+ /* sanity checks */
+ ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits,
+ ctx->Const.MaxTextureCoordUnits));
+ ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+ ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+}
+
+
+/**
+ * Do some sanity checks on the limits/constants for the given context.
+ * Only called the first time a context is bound.
+ */
+static void
+check_context_limits(GLcontext *ctx)
+{
+ /* Many context limits/constants are limited by the size of
+ * internal arrays.
+ */
+ assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS);
+ assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS);
+
+ assert(ctx->Const.MaxViewportWidth <= MAX_WIDTH);
+ assert(ctx->Const.MaxViewportHeight <= MAX_WIDTH);
+
+ /* make sure largest texture image is <= MAX_WIDTH in size */
+ assert((1 << (ctx->Const.MaxTextureLevels -1 )) <= MAX_WIDTH);
+ assert((1 << (ctx->Const.MaxCubeTextureLevels -1 )) <= MAX_WIDTH);
+ assert((1 << (ctx->Const.Max3DTextureLevels -1 )) <= MAX_WIDTH);
+
+ assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS);
+
+ /* XXX probably add more tests */
}
@@ -1099,7 +1146,6 @@ init_attrib_groups( GLcontext *ctx )
/* Attribute Groups */
_mesa_init_accum( ctx );
_mesa_init_attrib( ctx );
- _mesa_init_buffers( ctx );
_mesa_init_buffer_objects( ctx );
_mesa_init_color( ctx );
_mesa_init_colortables( ctx );
@@ -1115,12 +1161,15 @@ init_attrib_groups( GLcontext *ctx )
_mesa_init_line( ctx );
_mesa_init_lighting( ctx );
_mesa_init_matrix( ctx );
- _mesa_init_occlude( ctx );
+ _mesa_init_multisample( ctx );
_mesa_init_pixel( ctx );
_mesa_init_point( ctx );
_mesa_init_polygon( ctx );
_mesa_init_program( ctx );
+ _mesa_init_query( ctx );
_mesa_init_rastpos( ctx );
+ _mesa_init_scissor( ctx );
+ _mesa_init_shaderobjects (ctx);
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
@@ -1129,10 +1178,12 @@ init_attrib_groups( GLcontext *ctx )
if (!_mesa_init_texture( ctx ))
return GL_FALSE;
+ _mesa_init_texture_s3tc( ctx );
+ _mesa_init_texture_fxt1( ctx );
+
/* Miscellaneous */
ctx->NewState = _NEW_ALL;
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
- ctx->CatchSignals = GL_TRUE;
ctx->_Facing = 0;
return GL_TRUE;
@@ -1140,200 +1191,41 @@ init_attrib_groups( GLcontext *ctx )
/**
- * If the DRI libGL.so library is old, it may not have the entrypoints for
- * some recent OpenGL extensions. Dynamically add them now.
- * If we're building stand-alone Mesa where libGL.so has both the dispatcher
- * and driver code, this won't be an issue (and calling this function won't
- * do any harm).
+ * This is the default function we plug into all dispatch table slots
+ * This helps prevents a segfault when someone calls a GL function without
+ * first checking if the extension's supported.
*/
-static void
-add_newer_entrypoints(void)
+static int
+generic_nop(void)
{
- unsigned i;
- static const struct {
- const char * const name;
- unsigned offset;
- }
- newer_entrypoints[] = {
- /* GL_ARB_window_pos aliases with GL_MESA_window_pos */
- { "glWindowPos2dARB", 513 },
- { "glWindowPos2dvARB", 514 },
- { "glWindowPos2fARB", 515 },
- { "glWindowPos2fvARB", 516 },
- { "glWindowPos2iARB", 517 },
- { "glWindowPos2ivARB", 518 },
- { "glWindowPos2sARB", 519 },
- { "glWindowPos2svARB", 520 },
- { "glWindowPos3dARB", 521 },
- { "glWindowPos3dvARB", 522 },
- { "glWindowPos3fARB", 523 },
- { "glWindowPos3fvARB", 524 },
- { "glWindowPos3iARB", 525 },
- { "glWindowPos3ivARB", 526 },
- { "glWindowPos3sARB", 527 },
- { "glWindowPos3svARB", 528 },
-#if FEATURE_NV_vertex_program
- { "glAreProgramsResidentNV", 578 },
- { "glBindProgramNV", 579 },
- { "glDeleteProgramsNV", 580 },
- { "glExecuteProgramNV", 581 },
- { "glGenProgramsNV", 582 },
- { "glGetProgramParameterdvNV", 583 },
- { "glGetProgramParameterfvNV", 584 },
- { "glGetProgramivNV", 585 },
- { "glGetProgramStringNV", 586 },
- { "glGetTrackMatrixivNV", 587 },
- { "glGetVertexAttribdvNV", 588 },
- { "glGetVertexAttribfvNV", 589 },
- { "glGetVertexAttribivNV", 590 },
- { "glGetVertexAttribPointervNV", 591 },
- { "glIsProgramNV", 592 },
- { "glLoadProgramNV", 593 },
- { "glProgramParameter4dNV", 594 },
- { "glProgramParameter4dvNV", 595 },
- { "glProgramParameter4fNV", 596 },
- { "glProgramParameter4fvNV", 597 },
- { "glProgramParameters4dvNV", 598 },
- { "glProgramParameters4fvNV", 599 },
- { "glRequestResidentProgramsNV", 600 },
- { "glTrackMatrixNV", 601 },
- { "glVertexAttribPointerNV", 602 },
- { "glVertexAttrib1dNV", 603 },
- { "glVertexAttrib1dvNV", 604 },
- { "glVertexAttrib1fNV", 605 },
- { "glVertexAttrib1fvNV", 606 },
- { "glVertexAttrib1sNV", 607 },
- { "glVertexAttrib1svNV", 608 },
- { "glVertexAttrib2dNV", 609 },
- { "glVertexAttrib2dvNV", 610 },
- { "glVertexAttrib2fNV", 611 },
- { "glVertexAttrib2fvNV", 612 },
- { "glVertexAttrib2sNV", 613 },
- { "glVertexAttrib2svNV", 614 },
- { "glVertexAttrib3dNV", 615 },
- { "glVertexAttrib3dvNV", 616 },
- { "glVertexAttrib3fNV", 617 },
- { "glVertexAttrib3fvNV", 618 },
- { "glVertexAttrib3sNV", 619 },
- { "glVertexAttrib3svNV", 620 },
- { "glVertexAttrib4dNV", 621 },
- { "glVertexAttrib4dvNV", 622 },
- { "glVertexAttrib4fNV", 623 },
- { "glVertexAttrib4fvNV", 624 },
- { "glVertexAttrib4sNV", 625 },
- { "glVertexAttrib4svNV", 626 },
- { "glVertexAttrib4ubNV", 627 },
- { "glVertexAttrib4ubvNV", 628 },
- { "glVertexAttribs1dvNV", 629 },
- { "glVertexAttribs1fvNV", 630 },
- { "glVertexAttribs1svNV", 631 },
- { "glVertexAttribs2dvNV", 632 },
- { "glVertexAttribs2fvNV", 633 },
- { "glVertexAttribs2svNV", 634 },
- { "glVertexAttribs3dvNV", 635 },
- { "glVertexAttribs3fvNV", 636 },
- { "glVertexAttribs3svNV", 637 },
- { "glVertexAttribs4dvNV", 638 },
- { "glVertexAttribs4fvNV", 639 },
- { "glVertexAttribs4svNV", 640 },
- { "glVertexAttribs4ubvNV", 641 },
-#endif
- { "glPointParameteriNV", 642 },
- { "glPointParameterivNV", 643 },
- { "glMultiDrawArraysEXT", 644 },
- { "glMultiDrawElementsEXT", 645 },
- { "glMultiDrawArraysSUN", _gloffset_MultiDrawArraysEXT },
- { "glMultiDrawElementsSUN", _gloffset_MultiDrawElementsEXT },
- { "glActiveStencilFaceEXT", 646 },
-#if FEATURE_NV_fence
- { "glDeleteFencesNV", 647 },
- { "glGenFencesNV", 648 },
- { "glIsFenceNV", 649 },
- { "glTestFenceNV", 650 },
- { "glGetFenceivNV", 651 },
- { "glFinishFenceNV", 652 },
- { "glSetFenceNV", 653 },
-#endif
-#if FEATURE_NV_fragment_program
- { "glProgramNamedParameter4fNV", 682 },
- { "glProgramNamedParameter4dNV", 683 },
- { "glProgramNamedParameter4fvNV", 683 },
- { "glProgramNamedParameter4dvNV", 684 },
- { "glGetProgramNamedParameterfvNV", 685 },
- { "glGetProgramNamedParameterdvNV", 686 },
-#endif
-#if FEATURE_ARB_vertex_program
- { "glVertexAttrib1sARB", _gloffset_VertexAttrib1sNV },
- { "glVertexAttrib1fARB", _gloffset_VertexAttrib1fNV },
- { "glVertexAttrib1dARB", _gloffset_VertexAttrib1dNV },
- { "glVertexAttrib2sARB", _gloffset_VertexAttrib2sNV },
- { "glVertexAttrib2fARB", _gloffset_VertexAttrib2fNV },
- { "glVertexAttrib2dARB", _gloffset_VertexAttrib2dNV },
- { "glVertexAttrib3sARB", _gloffset_VertexAttrib3sNV },
- { "glVertexAttrib3fARB", _gloffset_VertexAttrib3fNV },
- { "glVertexAttrib3dARB", _gloffset_VertexAttrib3dNV },
- { "glVertexAttrib4sARB", _gloffset_VertexAttrib4sNV },
- { "glVertexAttrib4fARB", _gloffset_VertexAttrib4fNV },
- { "glVertexAttrib4dARB", _gloffset_VertexAttrib4dNV },
- { "glVertexAttrib4NubARB", _gloffset_VertexAttrib4ubNV },
- { "glVertexAttrib1svARB", _gloffset_VertexAttrib1svNV },
- { "glVertexAttrib1fvARB", _gloffset_VertexAttrib1fvNV },
- { "glVertexAttrib1dvARB", _gloffset_VertexAttrib1dvNV },
- { "glVertexAttrib2svARB", _gloffset_VertexAttrib2svNV },
- { "glVertexAttrib2fvARB", _gloffset_VertexAttrib2fvNV },
- { "glVertexAttrib2dvARB", _gloffset_VertexAttrib2dvNV },
- { "glVertexAttrib3svARB", _gloffset_VertexAttrib3svNV },
- { "glVertexAttrib3fvARB", _gloffset_VertexAttrib3fvNV },
- { "glVertexAttrib3dvARB", _gloffset_VertexAttrib3dvNV },
- { "glVertexAttrib4bvARB", _gloffset_VertexAttrib4bvARB },
- { "glVertexAttrib4svARB", _gloffset_VertexAttrib4svNV },
- { "glVertexAttrib4ivARB", _gloffset_VertexAttrib4ivARB },
- { "glVertexAttrib4ubvARB", _gloffset_VertexAttrib4ubvARB },
- { "glVertexAttrib4usvARB", _gloffset_VertexAttrib4usvARB },
- { "glVertexAttrib4uivARB", _gloffset_VertexAttrib4uivARB },
- { "glVertexAttrib4fvARB", _gloffset_VertexAttrib4fvNV },
- { "glVertexAttrib4dvARB", _gloffset_VertexAttrib4dvNV },
- { "glVertexAttrib4NbvARB", _gloffset_VertexAttrib4NbvARB },
- { "glVertexAttrib4NsvARB", _gloffset_VertexAttrib4NsvARB },
- { "glVertexAttrib4NivARB", _gloffset_VertexAttrib4NivARB },
- { "glVertexAttrib4NubvARB", _gloffset_VertexAttrib4ubvNV },
- { "glVertexAttrib4NusvARB", _gloffset_VertexAttrib4NusvARB },
- { "glVertexAttrib4NuivARB", _gloffset_VertexAttrib4NuivARB },
- { "glVertexAttribPointerARB", _gloffset_VertexAttribPointerARB },
- { "glEnableVertexAttribArrayARB", _gloffset_EnableVertexAttribArrayARB },
- { "glDisableVertexAttribArrayARB", _gloffset_DisableVertexAttribArrayARB },
- { "glProgramStringARB", _gloffset_ProgramStringARB },
- { "glBindProgramARB", _gloffset_BindProgramNV },
- { "glDeleteProgramsARB", _gloffset_DeleteProgramsNV },
- { "glGenProgramsARB", _gloffset_GenProgramsNV },
- { "glIsProgramARB", _gloffset_IsProgramNV },
- { "glProgramEnvParameter4dARB", _gloffset_ProgramEnvParameter4dARB },
- { "glProgramEnvParameter4dvARB", _gloffset_ProgramEnvParameter4dvARB },
- { "glProgramEnvParameter4fARB", _gloffset_ProgramEnvParameter4fARB },
- { "glProgramEnvParameter4fvARB", _gloffset_ProgramEnvParameter4fvARB },
- { "glProgramLocalParameter4dARB", _gloffset_ProgramLocalParameter4dARB },
- { "glProgramLocalParameter4dvARB", _gloffset_ProgramLocalParameter4dvARB },
- { "glProgramLocalParameter4fARB", _gloffset_ProgramLocalParameter4fARB },
- { "glProgramLocalParameter4fvARB", _gloffset_ProgramLocalParameter4fvARB },
- { "glGetProgramEnvParameterdvARB", _gloffset_GetProgramEnvParameterdvARB },
- { "glGetProgramEnvParameterfvARB", _gloffset_GetProgramEnvParameterfvARB },
- { "glGetProgramLocalParameterdvARB", _gloffset_GetProgramLocalParameterdvARB },
- { "glGetProgramLocalParameterfvARB", _gloffset_GetProgramLocalParameterfvARB },
- { "glGetProgramivARB", _gloffset_GetProgramivARB },
- { "glGetProgramStringARB", _gloffset_GetProgramStringARB },
- { "glGetVertexAttribdvARB", _gloffset_GetVertexAttribdvNV },
- { "glGetVertexAttribfvARB", _gloffset_GetVertexAttribfvNV },
- { "glGetVertexAttribivARB", _gloffset_GetVertexAttribivNV },
- { "glGetVertexAttribPointervARB", _gloffset_GetVertexAttribPointervNV },
-#endif
- { "glMultiModeDrawArraysIBM", _gloffset_MultiModeDrawArraysIBM },
- { "glMultiModeDrawElementsIBM", _gloffset_MultiModeDrawElementsIBM },
- };
-
- for ( i = 0 ; i < Elements(newer_entrypoints) ; i++ ) {
- _glapi_add_entrypoint( newer_entrypoints[i].name,
- newer_entrypoints[i].offset );
+ _mesa_problem(NULL, "User called no-op dispatch function (an unsupported extension function?)");
+ return 0;
+}
+
+
+/**
+ * Allocate and initialize a new dispatch table.
+ */
+static struct _glapi_table *
+alloc_dispatch_table(void)
+{
+ /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
+ * In practice, this'll be the same for stand-alone Mesa. But for DRI
+ * Mesa we do this to accomodate different versions of libGL and various
+ * DRI drivers.
+ */
+ GLint numEntries = MAX2(_glapi_get_dispatch_table_size(),
+ sizeof(struct _glapi_table) / sizeof(_glapi_proc));
+ struct _glapi_table *table =
+ (struct _glapi_table *) _mesa_malloc(numEntries * sizeof(_glapi_proc));
+ if (table) {
+ _glapi_proc *entry = (_glapi_proc *) table;
+ GLint i;
+ for (i = 0; i < numEntries; i++) {
+ entry[i] = (_glapi_proc) generic_nop;
+ }
}
+ return table;
}
@@ -1370,10 +1262,9 @@ _mesa_initialize_context( GLcontext *ctx,
const struct dd_function_table *driverFunctions,
void *driverContext )
{
- GLuint dispatchSize;
-
ASSERT(driverContext);
assert(driverFunctions->NewTextureObject);
+ assert(driverFunctions->FreeTexImageData);
/* If the driver wants core Mesa to use special imports, it'll have to
* override these defaults.
@@ -1389,6 +1280,8 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->Visual = *visual;
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
+ ctx->WinSysDrawBuffer = NULL;
+ ctx->WinSysReadBuffer = NULL;
/* Plug in driver functions and context pointer here.
* This is important because when we call alloc_shared_state() below
@@ -1417,39 +1310,34 @@ _mesa_initialize_context( GLcontext *ctx,
return GL_FALSE;
}
- /* libGL ABI coordination */
- add_newer_entrypoints();
-
- /* Find the larger of Mesa's dispatch table and libGL's dispatch table.
- * In practice, this'll be the same for stand-alone Mesa. But for DRI
- * Mesa we do this to accomodate different versions of libGL and various
- * DRI drivers.
- */
- dispatchSize = MAX2(_glapi_get_dispatch_table_size(),
- sizeof(struct _glapi_table) / sizeof(void *));
-
- /* setup API dispatch tables */
- ctx->Exec = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
- ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*));
+ /* setup the API dispatch tables */
+ ctx->Exec = alloc_dispatch_table();
+ ctx->Save = alloc_dispatch_table();
if (!ctx->Exec || !ctx->Save) {
free_shared_state(ctx, ctx->Shared);
if (ctx->Exec)
- FREE( ctx->Exec );
+ _mesa_free(ctx->Exec);
}
- _mesa_init_exec_table(ctx->Exec, dispatchSize);
+ _mesa_init_exec_table(ctx->Exec);
ctx->CurrentDispatch = ctx->Exec;
-
#if _HAVE_FULL_GL
- _mesa_init_dlist_table(ctx->Save, dispatchSize);
+ _mesa_init_dlist_table(ctx->Save);
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
-
-
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
#endif
+ ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
+ ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram;
+
+ ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+ if (ctx->_MaintainTnlProgram)
+ ctx->_MaintainTexEnvProgram = 1; /* this is required... */
+
+ ctx->FirstTimeCurrent = GL_TRUE;
+
return GL_TRUE;
}
@@ -1507,7 +1395,7 @@ _mesa_free_context_data( GLcontext *ctx )
{
/* if we're destroying the current context, unbind it first */
if (ctx == _mesa_get_current_context()) {
- _mesa_make_current(NULL, NULL);
+ _mesa_make_current(NULL, NULL, NULL);
}
_mesa_free_lighting_data( ctx );
@@ -1516,20 +1404,17 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
_mesa_free_colortables_data( ctx );
-#if FEATURE_NV_vertex_program
- if (ctx->VertexProgram.Current) {
- ctx->VertexProgram.Current->Base.RefCount--;
- if (ctx->VertexProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
- }
-#endif
-#if FEATURE_NV_fragment_program
- if (ctx->FragmentProgram.Current) {
- ctx->FragmentProgram.Current->Base.RefCount--;
- if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
- ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
- }
+ _mesa_free_program_data(ctx);
+ _mesa_free_query_data(ctx);
+
+#if FEATURE_ARB_vertex_buffer_object
+ _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj);
#endif
+ _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
+
+ /* free dispatch tables */
+ _mesa_free(ctx->Exec);
+ _mesa_free(ctx->Save);
/* Shared context state (display lists, textures, etc) */
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
@@ -1542,10 +1427,7 @@ _mesa_free_context_data( GLcontext *ctx )
}
if (ctx->Extensions.String)
- FREE((void *) ctx->Extensions.String);
-
- FREE(ctx->Exec);
- FREE(ctx->Save);
+ _mesa_free((void *) ctx->Extensions.String);
}
@@ -1561,7 +1443,7 @@ _mesa_destroy_context( GLcontext *ctx )
{
if (ctx) {
_mesa_free_context_data(ctx);
- FREE( (void *) ctx );
+ _mesa_free( (void *) ctx );
}
}
@@ -1575,7 +1457,7 @@ _mesa_destroy_context( GLcontext *ctx )
* \param mask bitwise OR of GL_*_BIT flags
*
* According to the bits specified in \p mask, copies the corresponding
- * attributes from \p src into \dst. For many of the attributes a simple \c
+ * attributes from \p src into \p dst. For many of the attributes a simple \c
* memcpy is not enough due to the existence of internal pointers in their data
* structures.
*/
@@ -1616,7 +1498,7 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
if (mask & GL_LIGHTING_BIT) {
GLuint i;
/* begin with memcpy */
- MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light) );
+ dst->Light = src->Light;
/* fixup linked lists to prevent pointer insanity */
make_empty_list( &(dst->Light.EnabledList) );
for (i = 0; i < MAX_LIGHTS; i++) {
@@ -1691,6 +1573,11 @@ _mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
/**
* Check if the given context can render into the given framebuffer
* by checking visual attributes.
+ *
+ * XXX this may go away someday because we're moving toward more freedom
+ * in binding contexts to drawables with different visual attributes.
+ * The GL_EXT_f_b_o extension is prompting some of that.
+ *
* \return GL_TRUE if compatible, GL_FALSE otherwise.
*/
static GLboolean
@@ -1704,8 +1591,11 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
if (ctxvis->rgbMode != bufvis->rgbMode)
return GL_FALSE;
+#if 0
+ /* disabling this fixes the fgl_glxgears pbuffer demo */
if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)
return GL_FALSE;
+#endif
if (ctxvis->stereoMode && !bufvis->stereoMode)
return GL_FALSE;
if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)
@@ -1730,65 +1620,66 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer)
/**
- * Set the current context, binding the given frame buffer to the context.
- *
- * \param newCtx new GL context.
- * \param buffer framebuffer.
- *
- * Calls _mesa_make_current2() with \p buffer as read and write framebuffer.
+ * Do one-time initialization for the given framebuffer. Specifically,
+ * ask the driver for the window's current size and update the framebuffer
+ * object to match.
+ * Really, the device driver should totally take care of this.
*/
-void
-_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer )
+static void
+initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
{
- _mesa_make_current2( newCtx, buffer, buffer );
+ GLuint width, height;
+ if (ctx->Driver.GetBufferSize) {
+ ctx->Driver.GetBufferSize(fb, &width, &height);
+ if (ctx->Driver.ResizeBuffers)
+ ctx->Driver.ResizeBuffers(ctx, fb, width, height);
+ fb->Initialized = GL_TRUE;
+ }
}
+
/**
- * Bind the given context to the given draw-buffer and read-buffer and
- * make it the current context for this thread.
- *
- * \param newCtx new GL context. If NULL then there will be no current GL
- * context.
- * \param drawBuffer draw framebuffer.
- * \param readBuffer read framebuffer.
- *
- * Check that the context's and framebuffer's visuals are compatible, returning
- * immediately otherwise. Sets the glapi current context via
- * _glapi_set_context(). If \p newCtx is not NULL, associates \p drawBuffer and
- * \p readBuffer with it and calls dd_function_table::ResizeBuffers if the buffers size has changed.
- * Calls dd_function_table::MakeCurrent callback if defined.
- *
- * When a context is bound by the first time and the \c MESA_INFO environment
- * variable is set it calls print_info() as an aid for remote user
- * troubleshooting.
+ * Bind the given context to the given drawBuffer and readBuffer and
+ * make it the current context for the calling thread.
+ * We'll render into the drawBuffer and read pixels from the
+ * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc).
+ *
+ * We check that the context's and framebuffer's visuals are compatible
+ * and return immediately if they're not.
+ *
+ * \param newCtx the new GL context. If NULL then there will be no current GL
+ * context.
+ * \param drawBuffer the drawing framebuffer
+ * \param readBuffer the reading framebuffer
*/
void
-_mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
- GLframebuffer *readBuffer )
+_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
+ GLframebuffer *readBuffer )
{
- if (MESA_VERBOSE)
- _mesa_debug(newCtx, "_mesa_make_current2()\n");
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(newCtx, "_mesa_make_current()\n");
/* Check that the context's and framebuffer's visuals are compatible.
*/
- if (newCtx && drawBuffer && newCtx->DrawBuffer != drawBuffer) {
- if (!check_compatible(newCtx, drawBuffer))
+ if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {
+ if (!check_compatible(newCtx, drawBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and drawbuffer");
return;
+ }
}
- if (newCtx && readBuffer && newCtx->ReadBuffer != readBuffer) {
- if (!check_compatible(newCtx, readBuffer))
+ if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {
+ if (!check_compatible(newCtx, readBuffer)) {
+ _mesa_warning(newCtx,
+ "MakeCurrent: incompatible visuals for context and readbuffer");
return;
+ }
}
- /* We call this function periodically (just here for now) in
- * order to detect when multithreading has begun.
- */
- _glapi_check_multithread();
-
+ /* We used to call _glapi_check_multithread() here. Now do it in drivers */
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
-
if (!newCtx) {
_glapi_set_dispatch(NULL); /* none current */
}
@@ -1797,55 +1688,65 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
if (drawBuffer && readBuffer) {
/* TODO: check if newCtx and buffer's visual match??? */
- newCtx->DrawBuffer = drawBuffer;
- newCtx->ReadBuffer = readBuffer;
- newCtx->NewState |= _NEW_BUFFERS;
-#if _HAVE_FULL_GL
- if (drawBuffer->Width == 0 && drawBuffer->Height == 0) {
- /* get initial window size */
- GLuint bufWidth, bufHeight;
+ ASSERT(drawBuffer->Name == 0);
+ ASSERT(readBuffer->Name == 0);
+ newCtx->WinSysDrawBuffer = drawBuffer;
+ newCtx->WinSysReadBuffer = readBuffer;
- /* ask device driver for size of output buffer */
- (*newCtx->Driver.GetBufferSize)( drawBuffer, &bufWidth, &bufHeight );
+ /*
+ * Only set the context's Draw/ReadBuffer fields if they're NULL
+ * or not bound to a user-created FBO.
+ */
+ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
+ newCtx->DrawBuffer = drawBuffer;
+ }
+ if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
+ newCtx->ReadBuffer = readBuffer;
+ }
- if (drawBuffer->Width != bufWidth ||
- drawBuffer->Height != bufHeight) {
+ newCtx->NewState |= _NEW_BUFFERS;
- drawBuffer->Width = bufWidth;
- drawBuffer->Height = bufHeight;
+#if 1
+ /* We want to get rid of these lines: */
- newCtx->Driver.ResizeBuffers( drawBuffer );
- }
+#if _HAVE_FULL_GL
+ if (!drawBuffer->Initialized) {
+ initialize_framebuffer_size(newCtx, drawBuffer);
+ }
+ if (readBuffer != drawBuffer && !readBuffer->Initialized) {
+ initialize_framebuffer_size(newCtx, readBuffer);
}
- if (readBuffer != drawBuffer &&
- readBuffer->Width == 0 && readBuffer->Height == 0) {
- /* get initial window size */
- GLuint bufWidth, bufHeight;
-
- /* ask device driver for size of output buffer */
- (*newCtx->Driver.GetBufferSize)( readBuffer, &bufWidth, &bufHeight );
-
- if (readBuffer->Width != bufWidth ||
- readBuffer->Height != bufHeight) {
+ _mesa_resizebuffers(newCtx);
+#endif
- readBuffer->Width = bufWidth;
- readBuffer->Height = bufHeight;
+#else
+ /* We want the drawBuffer and readBuffer to be initialized by
+ * the driver.
+ * This generally means the Width and Height match the actual
+ * window size and the renderbuffers (both hardware and software
+ * based) are allocated to match. The later can generally be
+ * done with a call to _mesa_resize_framebuffer().
+ *
+ * It's theoretically possible for a buffer to have zero width
+ * or height, but for now, assert check that the driver did what's
+ * expected of it.
+ */
+ ASSERT(drawBuffer->Width > 0);
+ ASSERT(drawBuffer->Height > 0);
+#endif
- newCtx->Driver.ResizeBuffers( readBuffer );
- }
+ if (newCtx->FirstTimeCurrent) {
+ /* set initial viewport and scissor size now */
+ _mesa_set_viewport(newCtx, 0, 0,
+ drawBuffer->Width, drawBuffer->Height);
+ _mesa_set_scissor(newCtx, 0, 0,
+ drawBuffer->Width, drawBuffer->Height );
+ check_context_limits(newCtx);
}
-#endif
}
- /* Alert the driver - usually passed on to the sw t&l module,
- * but also used to detect threaded cases in the radeon codegen
- * hw t&l module.
- */
- if (newCtx->Driver.MakeCurrent)
- newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer );
-
/* We can use this to help debug user's problems. Tell them to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
@@ -1860,6 +1761,32 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
}
}
+
+/**
+ * Make context 'ctx' share the display lists, textures and programs
+ * that are associated with 'ctxToShare'.
+ * Any display lists, textures or programs associated with 'ctx' will
+ * be deleted if nobody else is sharing them.
+ */
+GLboolean
+_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
+{
+ if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
+ ctx->Shared->RefCount--;
+ if (ctx->Shared->RefCount == 0) {
+ free_shared_state(ctx, ctx->Shared);
+ }
+ ctx->Shared = ctxToShare->Shared;
+ ctx->Shared->RefCount++;
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+
+
/**
* Get current context for the calling thread.
*