summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_arrayelt.c3
-rw-r--r--src/mesa/main/api_exec.c1
-rw-r--r--src/mesa/main/api_validate.c21
-rw-r--r--src/mesa/main/attrib.c146
-rw-r--r--src/mesa/main/bufferobj.c64
-rw-r--r--src/mesa/main/bufferobj.h20
-rw-r--r--src/mesa/main/colortab.c8
-rw-r--r--src/mesa/main/config.h9
-rw-r--r--src/mesa/main/context.c69
-rw-r--r--src/mesa/main/context.h6
-rw-r--r--src/mesa/main/convolve.c20
-rw-r--r--src/mesa/main/debug.c97
-rw-r--r--src/mesa/main/dlist.c304
-rw-r--r--src/mesa/main/drawpix.c142
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/fbobject.c20
-rw-r--r--src/mesa/main/fog.c2
-rw-r--r--src/mesa/main/framebuffer.c26
-rw-r--r--src/mesa/main/getstring.c1
-rw-r--r--src/mesa/main/histogram.c8
-rw-r--r--src/mesa/main/image.c382
-rw-r--r--src/mesa/main/image.h24
-rw-r--r--src/mesa/main/imports.c85
-rw-r--r--src/mesa/main/imports.h3
-rw-r--r--src/mesa/main/light.c8
-rw-r--r--src/mesa/main/mtypes.h14
-rw-r--r--src/mesa/main/pixel.c24
-rw-r--r--src/mesa/main/polygon.c4
-rw-r--r--src/mesa/main/readpix.c55
-rw-r--r--src/mesa/main/shared.c2
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/texenv.c69
-rw-r--r--src/mesa/main/texenvprogram.c15
-rw-r--r--src/mesa/main/texgetimage.c233
-rw-r--r--src/mesa/main/texgetimage.h9
-rw-r--r--src/mesa/main/teximage.c525
-rw-r--r--src/mesa/main/teximage.h16
-rw-r--r--src/mesa/main/texobj.c56
-rw-r--r--src/mesa/main/texobj.h8
-rw-r--r--src/mesa/main/texparam.c58
-rw-r--r--src/mesa/main/texstate.h18
-rw-r--r--src/mesa/main/texstore.c6
-rw-r--r--src/mesa/main/varray.c41
-rw-r--r--src/mesa/main/varray.h6
-rw-r--r--src/mesa/main/viewport.c4
45 files changed, 1520 insertions, 1119 deletions
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
index f5b7d1e138..2462a1b003 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -28,6 +28,7 @@
#include "glheader.h"
#include "api_arrayelt.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
@@ -1071,7 +1072,7 @@ void _ae_destroy_context( GLcontext *ctx )
static void check_vbo( AEcontext *actx,
struct gl_buffer_object *vbo )
{
- if (vbo->Name && !vbo->Pointer) {
+ if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
GLuint i;
for (i = 0; i < actx->nr_vbos; i++)
if (actx->vbo[i] == vbo)
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index e49cd041a6..199550b35d 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -107,6 +107,7 @@
#include "state.h"
#include "stencil.h"
#include "texenv.h"
+#include "texgetimage.h"
#include "teximage.h"
#if FEATURE_texgen
#include "texgen.h"
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index b2f11ffbfe..2df4f17389 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "api_validate.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "mtypes.h"
@@ -62,7 +63,7 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
GLuint max = 0;
GLuint i;
- if (elementBuf->Name) {
+ if (_mesa_is_bufferobj(elementBuf)) {
/* elements are in a user-defined buffer object. need to map it */
map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER,
GL_READ_ONLY, elementBuf);
@@ -96,14 +97,12 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
/**
- * Check if OK to render by examining framebuffer status and vertex arrays.
+ * Check if OK to draw arrays/elements.
*/
static GLboolean
-check_valid_to_render(GLcontext *ctx, char *function)
+check_valid_to_render(GLcontext *ctx, const char *function)
{
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDraw%s(incomplete framebuffer)", function);
+ if (!_mesa_valid_to_render(ctx, function)) {
return GL_FALSE;
}
@@ -160,11 +159,11 @@ _mesa_validate_DrawElements(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Elements"))
+ if (!check_valid_to_render(ctx, "glDrawElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -233,11 +232,11 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "RangeElements"))
+ if (!check_valid_to_render(ctx, "glDrawRangeElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -289,7 +288,7 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Arrays"))
+ if (!check_valid_to_render(ctx, "glDrawArrays"))
return GL_FALSE;
if (ctx->Const.CheckArrayBounds) {
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index cb49c4cb07..ab99ca1c64 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -174,24 +174,30 @@ struct texture_state
/**
- * Allocate a new attribute state node. These nodes have a
- * "kind" value and a pointer to a struct of state data.
+ * Allocate new attribute node of given type/kind. Attach payload data.
+ * Insert it into the linked list named by 'head'.
*/
-static struct gl_attrib_node *
-new_attrib_node( GLbitfield kind )
+static void
+save_attrib_data(struct gl_attrib_node **head,
+ GLbitfield kind, void *payload)
{
- struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
- if (an) {
- an->kind = kind;
+ struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node);
+ if (n) {
+ n->kind = kind;
+ n->data = payload;
+ /* insert at head */
+ n->next = *head;
+ *head = n;
+ }
+ else {
+ /* out of memory! */
}
- return an;
}
void GLAPIENTRY
_mesa_PushAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -213,10 +219,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_accum_attrib *attr;
attr = MALLOC_STRUCT( gl_accum_attrib );
MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
- newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ACCUM_BUFFER_BIT, attr);
}
if (mask & GL_COLOR_BUFFER_BIT) {
@@ -227,10 +230,7 @@ _mesa_PushAttrib(GLbitfield mask)
/* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
- newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr);
}
if (mask & GL_CURRENT_BIT) {
@@ -238,20 +238,14 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT( ctx, 0 );
attr = MALLOC_STRUCT( gl_current_attrib );
MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
- newnode = new_attrib_node( GL_CURRENT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CURRENT_BIT, attr);
}
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_depthbuffer_attrib *attr;
attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
- newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_DEPTH_BUFFER_BIT, attr);
}
if (mask & GL_ENABLE_BIT) {
@@ -331,40 +325,28 @@ _mesa_PushAttrib(GLbitfield mask)
attr->VertexProgram = ctx->VertexProgram.Enabled;
attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
- newnode = new_attrib_node( GL_ENABLE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ENABLE_BIT, attr);
}
if (mask & GL_EVAL_BIT) {
struct gl_eval_attrib *attr;
attr = MALLOC_STRUCT( gl_eval_attrib );
MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
- newnode = new_attrib_node( GL_EVAL_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_EVAL_BIT, attr);
}
if (mask & GL_FOG_BIT) {
struct gl_fog_attrib *attr;
attr = MALLOC_STRUCT( gl_fog_attrib );
MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
- newnode = new_attrib_node( GL_FOG_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_FOG_BIT, attr);
}
if (mask & GL_HINT_BIT) {
struct gl_hint_attrib *attr;
attr = MALLOC_STRUCT( gl_hint_attrib );
MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
- newnode = new_attrib_node( GL_HINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_HINT_BIT, attr);
}
if (mask & GL_LIGHTING_BIT) {
@@ -372,30 +354,21 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT(ctx, 0); /* flush material changes */
attr = MALLOC_STRUCT( gl_light_attrib );
MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
- newnode = new_attrib_node( GL_LIGHTING_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIGHTING_BIT, attr);
}
if (mask & GL_LINE_BIT) {
struct gl_line_attrib *attr;
attr = MALLOC_STRUCT( gl_line_attrib );
MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
- newnode = new_attrib_node( GL_LINE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LINE_BIT, attr);
}
if (mask & GL_LIST_BIT) {
struct gl_list_attrib *attr;
attr = MALLOC_STRUCT( gl_list_attrib );
MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
- newnode = new_attrib_node( GL_LIST_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIST_BIT, attr);
}
if (mask & GL_PIXEL_MODE_BIT) {
@@ -404,60 +377,42 @@ _mesa_PushAttrib(GLbitfield mask)
MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
/* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
- newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr);
}
if (mask & GL_POINT_BIT) {
struct gl_point_attrib *attr;
attr = MALLOC_STRUCT( gl_point_attrib );
MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
- newnode = new_attrib_node( GL_POINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POINT_BIT, attr);
}
if (mask & GL_POLYGON_BIT) {
struct gl_polygon_attrib *attr;
attr = MALLOC_STRUCT( gl_polygon_attrib );
MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
- newnode = new_attrib_node( GL_POLYGON_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_BIT, attr);
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
GLuint *stipple;
stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
- newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
- newnode->data = stipple;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_STIPPLE_BIT, stipple);
}
if (mask & GL_SCISSOR_BIT) {
struct gl_scissor_attrib *attr;
attr = MALLOC_STRUCT( gl_scissor_attrib );
MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
- newnode = new_attrib_node( GL_SCISSOR_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_SCISSOR_BIT, attr);
}
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_stencil_attrib *attr;
attr = MALLOC_STRUCT( gl_stencil_attrib );
MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
- newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_STENCIL_BUFFER_BIT, attr);
}
if (mask & GL_TEXTURE_BIT) {
@@ -494,30 +449,21 @@ _mesa_PushAttrib(GLbitfield mask)
_mesa_unlock_context_textures(ctx);
- newnode = new_attrib_node( GL_TEXTURE_BIT );
- newnode->data = texstate;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TEXTURE_BIT, texstate);
}
if (mask & GL_TRANSFORM_BIT) {
struct gl_transform_attrib *attr;
attr = MALLOC_STRUCT( gl_transform_attrib );
MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
- newnode = new_attrib_node( GL_TRANSFORM_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TRANSFORM_BIT, attr);
}
if (mask & GL_VIEWPORT_BIT) {
struct gl_viewport_attrib *attr;
attr = MALLOC_STRUCT( gl_viewport_attrib );
MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
- newnode = new_attrib_node( GL_VIEWPORT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_VIEWPORT_BIT, attr);
}
/* GL_ARB_multisample */
@@ -525,10 +471,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_multisample_attrib *attr;
attr = MALLOC_STRUCT( gl_multisample_attrib );
MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
- newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_MULTISAMPLE_BIT_ARB, attr);
}
end:
@@ -1373,7 +1316,6 @@ copy_pixelstore(GLcontext *ctx,
void GLAPIENTRY
_mesa_PushClientAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -1394,17 +1336,11 @@ _mesa_PushClientAttrib(GLbitfield mask)
/* packing attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Pack);
- newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr);
/* unpacking attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Unpack);
- newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr);
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
@@ -1425,10 +1361,8 @@ _mesa_PushClientAttrib(GLbitfield mask)
attr->ArrayObj = obj;
- newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
+
/* bump reference counts on buffer objects */
adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
}
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index d640f5358e..f96185a4b5 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -156,7 +156,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
_mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller);
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
}
@@ -165,7 +165,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
"%s(size + offset > buffer size)", caller);
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Buffer is currently mapped */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
@@ -423,7 +423,7 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
(void) target;
(void) access;
/* Just return a direct pointer to the data */
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* already mapped! */
return NULL;
}
@@ -445,7 +445,7 @@ _mesa_buffer_map_range( GLcontext *ctx, GLenum target, GLintptr offset,
(void) target;
(void) access;
(void) length;
- assert(!bufObj->Pointer);
+ assert(!_mesa_bufferobj_mapped(bufObj));
/* Just return a direct pointer to the data */
return bufObj->Data + offset;
}
@@ -502,8 +502,8 @@ _mesa_copy_buffer_subdata(GLcontext *ctx,
GLubyte *srcPtr, *dstPtr;
/* buffer should not already be mapped */
- assert(!src->Pointer);
- assert(!dst->Pointer);
+ assert(!_mesa_bufferobj_mapped(src));
+ assert(!_mesa_bufferobj_mapped(dst));
srcPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_READ_BUFFER,
GL_READ_ONLY, src);
@@ -663,7 +663,7 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLvoid *start, *end;
const GLubyte *sizeAddr; /* buffer size, cast to a pointer */
- ASSERT(pack->BufferObj->Name != 0);
+ ASSERT(_mesa_is_bufferobj(pack->BufferObj));
if (pack->BufferObj->Size == 0)
/* no buffer! */
@@ -709,7 +709,7 @@ _mesa_map_bitmap_pbo(GLcontext *ctx,
{
const GLubyte *buf;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* unpack from PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
@@ -736,7 +736,7 @@ void
_mesa_unmap_bitmap_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -753,7 +753,7 @@ _mesa_map_drawpix_pbo(GLcontext *ctx,
{
const GLvoid *buf;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* unpack from PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
@@ -779,7 +779,7 @@ void
_mesa_unmap_drawpix_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -798,7 +798,7 @@ _mesa_map_readpix_pbo(GLcontext *ctx,
{
void *buf;
- if (pack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
/* pack into PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
GL_WRITE_ONLY_ARB,
@@ -824,7 +824,7 @@ void
_mesa_unmap_readpix_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *pack)
{
- if (pack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
}
}
@@ -932,7 +932,7 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
ASSERT(bufObj->Name == ids[i]);
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* if mapped, unmap it now */
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
@@ -1086,12 +1086,12 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
_mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB(buffer 0)" );
return;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, target, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
@@ -1187,18 +1187,18 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
_mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" );
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(buffer 0)" );
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
return NULL;
}
ASSERT(ctx->Driver.MapBuffer);
bufObj->Pointer = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
}
@@ -1248,11 +1248,11 @@ _mesa_UnmapBufferARB(GLenum target)
_mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" );
return GL_FALSE;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" );
return GL_FALSE;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
return GL_FALSE;
}
@@ -1315,7 +1315,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
_mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameterivARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" );
return;
}
@@ -1331,7 +1331,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
*params = simplified_access_mode(bufObj->AccessFlags);
break;
case GL_BUFFER_MAPPED_ARB:
- *params = (bufObj->Pointer != NULL);
+ *params = _mesa_bufferobj_mapped(bufObj);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)");
@@ -1357,7 +1357,7 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" );
return;
}
@@ -1376,26 +1376,26 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
ASSERT_OUTSIDE_BEGIN_END(ctx);
src = get_buffer(ctx, readTarget);
- if (!src || src->Name == 0) {
+ if (!src || !_mesa_is_bufferobj(src)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(readTarget = 0x%x)", readTarget);
return;
}
dst = get_buffer(ctx, writeTarget);
- if (!dst || dst->Name == 0) {
+ if (!dst || !_mesa_is_bufferobj(dst)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(writeTarget = 0x%x)", writeTarget);
return;
}
- if (src->Pointer) {
+ if (_mesa_bufferobj_mapped(src)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(readBuffer is mapped)");
return;
}
- if (dst->Pointer) {
+ if (_mesa_bufferobj_mapped(dst)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(writeBuffer is mapped)");
return;
@@ -1499,7 +1499,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
}
bufObj = get_buffer(ctx, target);
- if (!bufObj || bufObj->Name == 0) {
+ if (!bufObj || !_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glMapBufferRange(target = 0x%x)", target);
return NULL;
@@ -1511,7 +1511,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer already mapped)");
return NULL;
@@ -1564,13 +1564,13 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(current buffer is 0)");
return;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
/* buffer is not mapped */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer is not mapped)");
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index ef59ff83c8..decb44a65e 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -36,6 +36,26 @@
* Internal functions
*/
+
+/** Is the given buffer object currently mapped? */
+static INLINE GLboolean
+_mesa_bufferobj_mapped(const struct gl_buffer_object *obj)
+{
+ return obj->Pointer != NULL;
+}
+
+/**
+ * Is the given buffer object a user-created buffer object?
+ * Mesa uses default buffer objects in several places. Default buffers
+ * always have Name==0. User created buffers have Name!=0.
+ */
+static INLINE GLboolean
+_mesa_is_bufferobj(const struct gl_buffer_object *obj)
+{
+ return obj->Name != 0;
+}
+
+
extern void
_mesa_init_buffer_objects( GLcontext *ctx );
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index bd9cf438b4..36304065eb 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -179,7 +179,7 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
GLfloat bScale, GLfloat bBias,
GLfloat aScale, GLfloat aBias)
{
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* Get/unpack the color table data from a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, count, 1, 1,
@@ -279,7 +279,7 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -696,7 +696,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack color table into PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, table->Size, 1, 1,
@@ -720,7 +720,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
format, type, data, &ctx->Pack, 0x0);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index f77a29a43e..e4995c35c4 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -138,9 +138,14 @@
/**
* Maximum viewport/image width. Must accomodate all texture sizes too.
*/
-#define MAX_WIDTH 4096
+
+#ifndef MAX_WIDTH
+# define MAX_WIDTH 4096
+#endif
/** Maximum viewport/image height */
-#define MAX_HEIGHT 4096
+#ifndef MAX_HEIGHT
+# define MAX_HEIGHT 4096
+#endif
/** Maxmimum size for CVA. May be overridden by the drivers. */
#define MAX_ARRAY_LOCK_SIZE 3000
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 415e339cb8..38ec418809 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -150,6 +150,7 @@
#include "glapi/glapioffsets.h"
#include "glapi/glapitable.h"
#include "shader/program.h"
+#include "shader/prog_print.h"
#include "shader/shader_api.h"
#if FEATURE_ATI_fragment_shader
#include "shader/atifragshader.h"
@@ -1576,4 +1577,72 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
}
+
+/**
+ * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
+ * is called to see if it's valid to render. This involves checking that
+ * the current shader is valid and the framebuffer is complete.
+ * If an error is detected it'll be recorded here.
+ * \return GL_TRUE if OK to render, GL_FALSE if not
+ */
+GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where)
+{
+ if (ctx->Shader.CurrentProgram) {
+ /* using shaders */
+ if (!ctx->Shader.CurrentProgram->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(shader not linked), where");
+ return GL_FALSE;
+ }
+ }
+ else {
+ if (ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(vertex program not valid)", where);
+ return GL_FALSE;
+ }
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(fragment program not valid)", where);
+ return GL_FALSE;
+ }
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "%s(incomplete framebuffer)", where);
+ return GL_FALSE;
+ }
+
+#ifdef DEBUG
+ if (ctx->Shader.Flags & GLSL_LOG) {
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ if (shProg) {
+ if (!shProg->_Used) {
+ /* This is the first time this shader is being used.
+ * Append shader's constants/uniforms to log file.
+ */
+ GLuint i;
+ for (i = 0; i < shProg->NumShaders; i++) {
+ struct gl_shader *sh = shProg->Shaders[i];
+ if (sh->Type == GL_VERTEX_SHADER) {
+ _mesa_append_uniforms_to_file(sh,
+ &shProg->VertexProgram->Base);
+ }
+ else if (sh->Type == GL_FRAGMENT_SHADER) {
+ _mesa_append_uniforms_to_file(sh,
+ &shProg->FragmentProgram->Base);
+ }
+ }
+ shProg->_Used = GL_TRUE;
+ }
+ }
+ }
+#endif
+
+ return GL_TRUE;
+}
+
+
/*@}*/
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 0531ae8ee8..5587695fa0 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -159,6 +159,11 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
GLboolean flag );
+extern GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where);
+
+
+
/** \name Miscellaneous */
/*@{*/
@@ -174,7 +179,6 @@ _mesa_Flush( void );
/*@}*/
-
/**
* \name Macros for flushing buffered rendering commands before state changes,
* checking if inside glBegin/glEnd, etc.
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 814c6a0a5a..69dba72ed3 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -144,7 +144,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution1D.Width = width;
ctx->Convolution1D.Height = 1;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
@@ -173,7 +173,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
format, type, image, &ctx->Unpack,
0); /* transferOps */
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -242,7 +242,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution2D.Width = width;
ctx->Convolution2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
@@ -276,7 +276,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
0); /* transferOps */
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -598,7 +598,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack the filter into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Pack,
@@ -629,7 +629,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
format, type, dst, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -802,7 +802,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
filter = &ctx->Separable2D;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack filter into PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Width, 1, 1,
@@ -850,7 +850,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
(void) span; /* unused at this time */
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Pack filter into PBO */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
@@ -905,7 +905,7 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Separable2D.Width = width;
ctx->Separable2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack filter from PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
@@ -971,7 +971,7 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Pixel.ConvolutionFilterBias[2][3]);
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
index 1c8c44fcb9..8492c8561d 100644
--- a/src/mesa/main/debug.c
+++ b/src/mesa/main/debug.c
@@ -33,6 +33,7 @@
#include "get.h"
#include "pixelstore.h"
#include "readpix.h"
+#include "texgetimage.h"
#include "texobj.h"
#include "texformat.h"
@@ -234,11 +235,11 @@ _mesa_init_debug( GLcontext *ctx )
*/
static void
write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
- int comps, int rcomp, int gcomp, int bcomp)
+ int comps, int rcomp, int gcomp, int bcomp, GLboolean invert)
{
FILE *f = fopen( filename, "w" );
if (f) {
- int i, x, y;
+ int x, y;
const GLubyte *ptr = buffer;
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
@@ -246,10 +247,11 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
- for (y=height-1; y>=0; y--) {
- for (x=0; x<width; x++) {
- i = (y*width + x) * comps;
- fputc(ptr[i+rcomp], f); /* write red */
+ for (y=0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int yy = invert ? (height - 1 - y) : y;
+ int i = (yy * width + x) * comps;
+ fputc(ptr[i+rcomp], f); /* write red */
fputc(ptr[i+gcomp], f); /* write green */
fputc(ptr[i+bcomp], f); /* write blue */
}
@@ -263,47 +265,34 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
* Write level[0] image to a ppm file.
*/
static void
-write_texture_image(struct gl_texture_object *texObj)
+write_texture_image(struct gl_texture_object *texObj, GLuint face, GLuint level)
{
- const struct gl_texture_image *img = texObj->Image[0][0];
- if (img && img->Data) {
+ struct gl_texture_image *img = texObj->Image[face][level];
+ if (img) {
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pixelstore_attrib store;
+ GLubyte *buffer;
char s[100];
+ buffer = (GLubyte *) _mesa_malloc(img->Width * img->Height
+ * img->Depth * 4);
+
+ store = ctx->Pack; /* save */
+ ctx->Pack = ctx->DefaultPacking;
+
+ ctx->Driver.GetTexImage(ctx, texObj->Target, level,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer, texObj, img);
+
/* make filename */
- sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
-
- switch (img->TexFormat->MesaFormat) {
- case MESA_FORMAT_RGBA8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 3, 2, 1);
- break;
- case MESA_FORMAT_ARGB8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB888:
- write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB565:
- {
- GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3);
- GLuint i;
- for (i = 0; i < img->Width * img->Height; i++) {
- GLint r, g, b;
- GLushort s = ((GLushort *) img->Data)[i];
- r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
- g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
- b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
- buf2[i*3+1] = r;
- buf2[i*3+2] = g;
- buf2[i*3+3] = b;
- }
- write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0);
- _mesa_free(buf2);
- }
- break;
- default:
- printf("XXXX unsupported mesa tex format %d in %s\n",
- img->TexFormat->MesaFormat, __FUNCTION__);
- }
+ _mesa_sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
+
+ _mesa_printf(" Writing image level %u to %s\n", level, s);
+ write_ppm(s, buffer, img->Width, img->Height, 4, 0, 1, 2, GL_FALSE);
+
+ ctx->Pack = store; /* restore */
+
+ _mesa_free(buffer);
}
}
@@ -316,17 +305,21 @@ dump_texture_cb(GLuint id, void *data, void *userData)
{
struct gl_texture_object *texObj = (struct gl_texture_object *) data;
int i;
+ GLboolean written = GL_FALSE;
(void) userData;
- printf("Texture %u\n", texObj->Name);
- printf(" Target 0x%x\n", texObj->Target);
+ _mesa_printf("Texture %u\n", texObj->Name);
+ _mesa_printf(" Target 0x%x\n", texObj->Target);
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
struct gl_texture_image *texImg = texObj->Image[0][i];
if (texImg) {
- printf(" Image %u: %d x %d x %d at %p\n", i,
- texImg->Width, texImg->Height, texImg->Depth, texImg->Data);
- if (DumpImages && i == 0) {
- write_texture_image(texObj);
+ _mesa_printf(" Image %u: %d x %d x %d, format %u at %p\n", i,
+ texImg->Width, texImg->Height, texImg->Depth,
+ texImg->TexFormat->MesaFormat, texImg->Data);
+ if (DumpImages && !written) {
+ GLuint face = 0;
+ write_texture_image(texObj, face, i);
+ written = GL_TRUE;
}
}
}
@@ -368,7 +361,7 @@ _mesa_dump_color_buffer(const char *filename)
ctx->DrawBuffer->_ColorDrawBuffers[0],
ctx->DrawBuffer->ColorDrawBuffer[0]);
_mesa_printf("Writing %d x %d color buffer to %s\n", w, h, filename);
- write_ppm(filename, buf, w, h, 4, 0, 1, 2);
+ write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -403,7 +396,7 @@ _mesa_dump_depth_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d depth buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -438,7 +431,7 @@ _mesa_dump_stencil_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d stencil buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 49f202daa1..9b68b3e116 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -683,24 +683,48 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
/**
* Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
- * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
+ * If we run out of memory, GL_OUT_OF_MEMORY will be recorded.
*/
static GLvoid *
-unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth,
+unpack_image(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid * pixels,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, pixels, unpack);
+ GLvoid *image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, pixels, unpack);
+ if (pixels && !image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
- else
- if (_mesa_validate_pbo_access
- (dimensions, unpack, width, height, depth, format, type, pixels)) {
- const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels);
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, src, unpack);
+ else if (_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
+ format, type, pixels)) {
+ const GLubyte *map, *src;
+ GLvoid *image;
+
+ map = (GLubyte *)
+ ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, unpack->BufferObj);
+ if (!map) {
+ /* unable to map src buffer! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
+ return NULL;
+ }
+
+ src = ADD_POINTERS(map, pixels);
+ image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, src, unpack);
+
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
/* bad access! */
return NULL;
@@ -858,7 +882,6 @@ save_Bitmap(GLsizei width, GLsizei height,
GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_BITMAP, 7);
@@ -869,10 +892,7 @@ save_Bitmap(GLsizei width, GLsizei height,
n[4].f = yorig;
n[5].f = xmove;
n[6].f = ymove;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_Bitmap(ctx->Exec, (width, height,
@@ -999,7 +1019,7 @@ _mesa_save_CallList(GLuint list)
void GLAPIENTRY
-_mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+_mesa_save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
{
GET_CURRENT_CONTEXT(ctx);
GLint i;
@@ -1024,7 +1044,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
typeErrorFlag = GL_TRUE;
}
- for (i = 0; i < n; i++) {
+ for (i = 0; i < num; i++) {
GLint list = translate_id(i, type, lists);
Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
if (n) {
@@ -1039,7 +1059,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
invalidate_saved_current_state( ctx );
if (ctx->ExecuteFlag) {
- CALL_CallLists(ctx->Exec, (n, type, lists));
+ CALL_CallLists(ctx->Exec, (num, type, lists));
}
}
@@ -1217,8 +1237,6 @@ save_ColorTable(GLenum target, GLenum internalFormat,
format, type, table));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE, 6);
@@ -1228,10 +1246,8 @@ save_ColorTable(GLenum target, GLenum internalFormat,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
@@ -1307,8 +1323,6 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
GLenum format, GLenum type, const GLvoid * table)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, count, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_SUB_TABLE, 6);
@@ -1318,10 +1332,8 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
n[3].i = count;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorSubTable(ctx->Exec,
@@ -1379,10 +1391,10 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
GLenum format, GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
if (n) {
n[1].e = target;
@@ -1390,10 +1402,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
@@ -1408,10 +1418,10 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
if (n) {
n[1].e = target;
@@ -1420,10 +1430,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
n[4].i = height;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter2D(ctx->Exec,
@@ -1778,20 +1786,18 @@ save_DrawPixels(GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_PIXELS, 5);
if (n) {
n[1].i = width;
n[2].i = height;
n[3].e = format;
n[4].e = type;
- n[5].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
@@ -1880,7 +1886,10 @@ save_Fogfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_Fogf(GLenum pname, GLfloat param)
{
- save_Fogfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Fogfv(pname, parray);
}
@@ -1904,7 +1913,7 @@ save_Fogiv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_Fogfv(pname, p);
}
@@ -1913,7 +1922,10 @@ save_Fogiv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Fogi(GLenum pname, GLint param)
{
- save_Fogiv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Fogiv(pname, parray);
}
@@ -2077,9 +2089,12 @@ save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
-save_Lightf(GLenum light, GLenum pname, GLfloat params)
+save_Lightf(GLenum light, GLenum pname, GLfloat param)
{
- save_Lightfv(light, pname, &params);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Lightfv(light, pname, parray);
}
@@ -2125,7 +2140,10 @@ save_Lightiv(GLenum light, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Lighti(GLenum light, GLenum pname, GLint param)
{
- save_Lightiv(light, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Lightiv(light, pname, parray);
}
@@ -2152,7 +2170,10 @@ save_LightModelfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_LightModelf(GLenum pname, GLfloat param)
{
- save_LightModelfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_LightModelfv(pname, parray);
}
@@ -2174,7 +2195,7 @@ save_LightModeliv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_LightModelfv(pname, fparam);
}
@@ -2183,7 +2204,10 @@ save_LightModeliv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_LightModeli(GLenum pname, GLint param)
{
- save_LightModeliv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_LightModeliv(pname, parray);
}
@@ -2698,21 +2722,28 @@ save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_PointParameterfEXT(GLenum pname, GLfloat param)
{
- save_PointParameterfvEXT(pname, &param);
+ GLfloat parray[3];
+ parray[0] = param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameteriNV(GLenum pname, GLint param)
{
- GLfloat p = (GLfloat) param;
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameterivNV(GLenum pname, const GLint * param)
{
- GLfloat p = (GLfloat) param[0];
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param[0];
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
@@ -2753,16 +2784,14 @@ static void GLAPIENTRY
save_PolygonStipple(const GLubyte * pattern)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
- pattern, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1);
if (n) {
- n[1].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
+ pattern, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
@@ -3386,7 +3415,10 @@ save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexEnvfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexEnvfv(target, pname, parray);
}
@@ -3454,8 +3486,10 @@ save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_TexGend(GLenum coord, GLenum pname, GLdouble param)
{
- GLfloat p = (GLfloat) param;
- save_TexGenfv(coord, pname, &p);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
@@ -3474,14 +3508,20 @@ save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
static void GLAPIENTRY
save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
{
- save_TexGenfv(coord, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
static void GLAPIENTRY
save_TexGeni(GLenum coord, GLenum pname, GLint param)
{
- save_TexGeniv(coord, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_TexGeniv(coord, pname, parray);
}
@@ -3509,7 +3549,10 @@ save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexParameterfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexParameterfv(target, pname, parray);
}
@@ -3546,8 +3589,6 @@ save_TexImage1D(GLenum target,
border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE1D, 8);
@@ -3559,10 +3600,8 @@ save_TexImage1D(GLenum target,
n[5].i = border;
n[6].e = format;
n[7].e = type;
- n[8].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage1D(ctx->Exec, (target, level, components, width,
@@ -3585,8 +3624,6 @@ save_TexImage2D(GLenum target,
height, border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE2D, 9);
@@ -3599,10 +3636,8 @@ save_TexImage2D(GLenum target,
n[6].i = border;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage2D(ctx->Exec, (target, level, components, width,
@@ -3628,8 +3663,6 @@ save_TexImage3D(GLenum target,
}
else {
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE3D, 10);
if (n) {
@@ -3642,10 +3675,8 @@ save_TexImage3D(GLenum target,
n[7].i = border;
n[8].e = format;
n[9].e = type;
- n[10].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[10].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
@@ -3663,9 +3694,9 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
if (n) {
n[1].e = target;
@@ -3674,10 +3705,8 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
n[4].i = (GLint) width;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
@@ -3694,9 +3723,9 @@ save_TexSubImage2D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
if (n) {
n[1].e = target;
@@ -3707,10 +3736,8 @@ save_TexSubImage2D(GLenum target, GLint level,
n[6].i = (GLint) height;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
@@ -3727,9 +3754,9 @@ save_TexSubImage3D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE3D, 11);
if (n) {
n[1].e = target;
@@ -3742,10 +3769,8 @@ save_TexSubImage3D(GLenum target, GLint level,
n[8].i = (GLint) depth;
n[9].e = format;
n[10].e = type;
- n[11].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[11].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage3D(ctx->Exec, (target, level,
@@ -4458,18 +4483,17 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- return;
- }
- _mesa_memcpy(programCopy, program, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ return;
+ }
+ _mesa_memcpy(programCopy, program, len);
n[1].e = target;
n[2].ui = id;
n[3].i = len;
@@ -4486,15 +4510,17 @@ save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
- if (!idCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
- return;
- }
- _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 2);
if (n) {
+ GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
+ if (!idCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
+ return;
+ }
+ _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
n[1].i = num;
n[2].data = idCopy;
}
@@ -4655,16 +4681,17 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
- if (!nameCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
- return;
- }
- _mesa_memcpy(nameCopy, name, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
if (n) {
+ GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
+ if (!nameCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
+ return;
+ }
+ _mesa_memcpy(nameCopy, name, len);
n[1].ui = id;
n[2].i = len;
n[3].data = nameCopy;
@@ -4753,18 +4780,17 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
- return;
- }
- _mesa_memcpy(programCopy, string, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(programCopy, string, len);
n[1].e = target;
n[2].e = format;
n[3].i = len;
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index 6682b5e725..6d31f32443 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -27,6 +27,7 @@
#include "bufferobj.h"
#include "context.h"
#include "drawpix.h"
+#include "enums.h"
#include "feedback.h"
#include "framebuffer.h"
#include "image.h"
@@ -34,6 +35,18 @@
#include "state.h"
+
+/**
+ * If a fragment program is enabled, check that it's valid.
+ * \return GL_TRUE if valid, GL_FALSE otherwise
+ */
+static GLboolean
+valid_fragment_program(GLcontext *ctx)
+{
+ return !(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled);
+}
+
+
#if _HAVE_FULL_GL
/*
@@ -51,29 +64,34 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
return;
}
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels (invalid fragment program)");
- return;
+ goto end;
}
if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) {
- /* found an error */
- return;
+ /* the error was already recorded */
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glDrawPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -88,13 +106,13 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(invalid PBO access)");
- return;
+ goto end;
}
- if (ctx->Unpack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(PBO is mapped)");
- return;
+ goto end;
}
}
@@ -116,6 +134,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
@@ -126,37 +147,48 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (width < 0 || height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
+ return;
+ }
+
+ if (type != GL_COLOR && type != GL_DEPTH && type != GL_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
+ return;
+ }
+
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels (invalid fragment program)");
- return;
- }
-
- if (width < 0 || height < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
- return;
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glCopyPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!_mesa_source_buffer_exists(ctx, type) ||
!_mesa_dest_buffer_exists(ctx, type)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels(missing source or dest buffer)");
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid || width ==0 || height == 0) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -181,6 +213,9 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
#endif /* _HAVE_FULL_GL */
@@ -208,7 +243,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBitmap (invalid fragment program)");
return;
@@ -235,7 +270,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
"glBitmap(invalid PBO access)");
return;
}
- if (ctx->Unpack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
return;
@@ -264,68 +299,3 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
}
-
-
-
-#if 0 /* experimental */
-/*
- * Execute glDrawDepthPixelsMESA(). This function accepts both a color
- * image and depth (Z) image. Rasterization produces fragments with
- * color and Z taken from these images. This function is intended for
- * Z-compositing. Normally, this operation requires two glDrawPixels
- * calls with stencil testing.
- */
-void GLAPIENTRY
-_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
- GLenum colorFormat, GLenum colorType,
- const GLvoid *colors,
- GLenum depthType, const GLvoid *depths )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (width < 0 || height < 0) {
- _mesa_error( ctx, GL_INVALID_VALUE,
- "glDrawDepthPixelsMESA(width or height < 0" );
- return;
- }
-
- if (!ctx->Current.RasterPosValid) {
- return;
- }
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDrawDepthPixelsMESA(incomplete framebuffer)");
- return;
- }
-
- if (ctx->RenderMode == GL_RENDER) {
- /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
- GLint x = IROUND(ctx->Current.RasterPos[0]);
- GLint y = IROUND(ctx->Current.RasterPos[1]);
- ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
- colorFormat, colorType, colors,
- depthType, depths, &ctx->Unpack);
- }
- else if (ctx->RenderMode == GL_FEEDBACK) {
- /* Feedback the current raster pos info */
- FLUSH_CURRENT( ctx, 0 );
- _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
- _mesa_feedback_vertex( ctx,
- ctx->Current.RasterPos,
- ctx->Current.RasterColor,
- ctx->Current.RasterIndex,
- ctx->Current.RasterTexCoords[0] );
- }
- else {
- ASSERT(ctx->RenderMode == GL_SELECT);
- /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
- }
-}
-
-#endif
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index c60b58a492..8870a20d0e 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -78,6 +78,7 @@ static const struct {
{ OFF, "GL_ARB_texture_non_power_of_two", F(ARB_texture_non_power_of_two)},
{ OFF, "GL_ARB_texture_rectangle", F(NV_texture_rectangle) },
{ ON, "GL_ARB_transpose_matrix", F(ARB_transpose_matrix) },
+ { OFF, "GL_ARB_vertex_array_bgra", F(EXT_vertex_array_bgra) },
{ OFF, "GL_ARB_vertex_array_object", F(ARB_vertex_array_object) },
{ ON, "GL_ARB_vertex_buffer_object", F(ARB_vertex_buffer_object) },
{ OFF, "GL_ARB_vertex_program", F(ARB_vertex_program) },
@@ -413,6 +414,7 @@ _mesa_enable_2_0_extensions(GLcontext *ctx)
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
#endif
ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
#if FEATURE_ARB_shader_objects
ctx->Extensions.ARB_shader_objects = GL_TRUE;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 83301f1e62..825a23090b 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -417,21 +417,22 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
if (format == GL_COLOR) {
if (att->Renderbuffer->_BaseFormat != GL_RGB &&
att->Renderbuffer->_BaseFormat != GL_RGBA) {
- ASSERT(att->Renderbuffer->RedBits);
- ASSERT(att->Renderbuffer->GreenBits);
- ASSERT(att->Renderbuffer->BlueBits);
att_incomplete("bad renderbuffer color format");
att->Complete = GL_FALSE;
return;
}
+ ASSERT(att->Renderbuffer->RedBits);
+ ASSERT(att->Renderbuffer->GreenBits);
+ ASSERT(att->Renderbuffer->BlueBits);
}
else if (format == GL_DEPTH) {
- ASSERT(att->Renderbuffer->DepthBits);
if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else {
@@ -442,12 +443,13 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
}
else {
assert(format == GL_STENCIL);
- ASSERT(att->Renderbuffer->StencilBits);
if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else {
@@ -2038,7 +2040,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
- if (readRb->StencilBits != drawRb->StencilBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->StencilBits != drawRb->StencilBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(stencil buffer size mismatch");
return;
@@ -2048,7 +2052,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
- if (readRb->DepthBits != drawRb->DepthBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->DepthBits != drawRb->DepthBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(depth buffer size mismatch");
return;
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 50a61bd84b..4323d3db82 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -67,7 +67,7 @@ _mesa_Fogiv(GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in _mesa_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_Fogfv(pname, p);
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 5a13c88a7a..dc79b8ca61 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -817,7 +817,7 @@ _mesa_update_framebuffer(GLcontext *ctx)
/**
* Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
- * glCopyTex[Sub]Image, etc. exists.
+ * glCopyTex[Sub]Image, etc) exists.
* \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
* GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
* \return GL_TRUE if buffer exists, GL_FALSE otherwise
@@ -825,8 +825,12 @@ _mesa_update_framebuffer(GLcontext *ctx)
GLboolean
_mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->ReadBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->ReadBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ }
if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -850,10 +854,8 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
return GL_FALSE;
}
- /* XXX enable this post 6.5 release:
ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||
ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);
- */
break;
case GL_DEPTH:
case GL_DEPTH_COMPONENT:
@@ -891,13 +893,17 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
/**
* As above, but for drawing operations.
- * XXX code do some code merging w/ above function.
+ * XXX could do some code merging w/ above function.
*/
GLboolean
_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->DrawBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
+ }
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -918,7 +924,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
case GL_BGRA:
case GL_ABGR_EXT:
case GL_COLOR_INDEX:
- /* nothing special */
+ /* Nothing special since GL_DRAW_BUFFER could be GL_NONE. */
/* Could assert that colorbuffer has RedBits > 0 */
break;
case GL_DEPTH:
@@ -945,7 +951,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
break;
default:
_mesa_problem(ctx,
- "Unexpected format 0x%x in _mesa_source_buffer_exists",
+ "Unexpected format 0x%x in _mesa_dest_buffer_exists",
format);
return GL_FALSE;
}
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 41fd786d7d..6599ed9698 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -266,5 +266,6 @@ _mesa_GetError( void )
_mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+ ctx->ErrorDebugCount = 0;
return e;
}
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index 5fee4fd0e3..726a50d3b1 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -649,7 +649,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack min/max values into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, 2, 1, 1,
@@ -687,7 +687,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
format, type, values, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -733,7 +733,7 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
return;
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack min/max values into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(1, &ctx->Pack, ctx->Histogram.Width, 1, 1,
@@ -761,7 +761,7 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
(CONST GLuint (*)[4]) ctx->Histogram.Count,
format, type, values, &ctx->Pack);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 090e5eb330..d77c593ac7 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -531,6 +531,210 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
/**
+ * Test if the given image format is a color/RGBA format (i.e., not color
+ * index, depth, stencil, etc).
+ * \param format the image format value (may by an internal texture format)
+ * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ */
+GLboolean
+_mesa_is_color_format(GLenum format)
+{
+ switch (format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case 3:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ case 4:
+ case GL_ABGR_EXT:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ /* float texture formats */
+ case GL_ALPHA16F_ARB:
+ case GL_ALPHA32F_ARB:
+ case GL_LUMINANCE16F_ARB:
+ case GL_LUMINANCE32F_ARB:
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ case GL_INTENSITY16F_ARB:
+ case GL_INTENSITY32F_ARB:
+ case GL_RGB16F_ARB:
+ case GL_RGB32F_ARB:
+ case GL_RGBA16F_ARB:
+ case GL_RGBA32F_ARB:
+ /* compressed formats */
+ case GL_COMPRESSED_ALPHA:
+ case GL_COMPRESSED_LUMINANCE:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_COMPRESSED_INTENSITY:
+ case GL_COMPRESSED_RGB:
+ case GL_COMPRESSED_RGBA:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+#if FEATURE_EXT_texture_sRGB
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif /* FEATURE_EXT_texture_sRGB */
+ return GL_TRUE;
+ /* signed texture formats */
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_TRUE;
+ case GL_YCBCR_MESA: /* not considered to be RGB */
+ /* fall-through */
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a color index format.
+ */
+GLboolean
+_mesa_is_index_format(GLenum format)
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth component format.
+ */
+GLboolean
+_mesa_is_depth_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a YCbCr format.
+ */
+GLboolean
+_mesa_is_ycbcr_format(GLenum format)
+{
+ switch (format) {
+ case GL_YCBCR_MESA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth+stencil format.
+ */
+GLboolean
+_mesa_is_depthstencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+/**
+ * Test if the given image format is a dudv format.
+ */
+GLboolean
+_mesa_is_dudv_format(GLenum format)
+{
+ switch (format) {
+ case GL_DUDV_ATI:
+ case GL_DU8DV8_ATI:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
* Return the address of a specific pixel in an image (1D, 2D or 3D).
*
* Pixel unpacking/packing parameters are observed according to \p packing.
@@ -5335,3 +5539,181 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
return GL_TRUE;
}
+
+
+/**
+ * Clip dst coords against Xmax (or Ymax).
+ */
+static INLINE void
+clip_right_or_top(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint maxValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX1 > maxValue) {
+ /* X1 outside right edge */
+ ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = maxValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX0 > maxValue) {
+ /* X0 outside right edge */
+ ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = maxValue;
+ bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
+ *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Clip dst coords against Xmin (or Ymin).
+ */
+static INLINE void
+clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint minValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX0 < minValue) {
+ /* X0 outside left edge */
+ ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
+ *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX1 < minValue) {
+ /* X1 outside left edge */
+ ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Do clipping of blit src/dest rectangles.
+ * The dest rect is clipped against both the buffer bounds and scissor bounds.
+ * The src rect is just clipped against the buffer bounds.
+ *
+ * When either the src or dest rect is clipped, the other is also clipped
+ * proportionately!
+ *
+ * Note that X0 need not be less than X1 (same for Y) for either the source
+ * and dest rects. That makes the clipping a little trickier.
+ *
+ * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
+ */
+GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
+{
+ const GLint srcXmin = 0;
+ const GLint srcXmax = ctx->ReadBuffer->Width;
+ const GLint srcYmin = 0;
+ const GLint srcYmax = ctx->ReadBuffer->Height;
+
+ /* these include scissor bounds */
+ const GLint dstXmin = ctx->DrawBuffer->_Xmin;
+ const GLint dstXmax = ctx->DrawBuffer->_Xmax;
+ const GLint dstYmin = ctx->DrawBuffer->_Ymin;
+ const GLint dstYmax = ctx->DrawBuffer->_Ymax;
+
+ /*
+ printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ /* trivial rejection tests */
+ if (*dstX0 == *dstX1)
+ return GL_FALSE; /* no width */
+ if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
+ return GL_FALSE; /* totally out (left) of bounds */
+ if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
+ return GL_FALSE; /* totally out (right) of bounds */
+
+ if (*dstY0 == *dstY1)
+ return GL_FALSE;
+ if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
+ return GL_FALSE;
+ if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
+ return GL_FALSE;
+
+ if (*srcX0 == *srcX1)
+ return GL_FALSE;
+ if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
+ return GL_FALSE;
+ if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
+ return GL_FALSE;
+
+ if (*srcY0 == *srcY1)
+ return GL_FALSE;
+ if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
+ return GL_FALSE;
+ if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
+ return GL_FALSE;
+
+ /*
+ * dest clip
+ */
+ clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
+ clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
+ clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
+ clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
+
+ /*
+ * src clip (just swap src/dst values from above)
+ */
+ clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
+ clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
+ clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
+ clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
+
+ /*
+ printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ ASSERT(*dstX0 >= dstXmin);
+ ASSERT(*dstX0 <= dstXmax);
+ ASSERT(*dstX1 >= dstXmin);
+ ASSERT(*dstX1 <= dstXmax);
+
+ ASSERT(*dstY0 >= dstYmin);
+ ASSERT(*dstY0 <= dstYmax);
+ ASSERT(*dstY1 >= dstYmin);
+ ASSERT(*dstY1 <= dstYmax);
+
+ ASSERT(*srcX0 >= srcXmin);
+ ASSERT(*srcX0 <= srcXmax);
+ ASSERT(*srcX1 >= srcXmin);
+ ASSERT(*srcX1 <= srcXmax);
+
+ ASSERT(*srcY0 >= srcYmin);
+ ASSERT(*srcY0 <= srcYmax);
+ ASSERT(*srcY1 >= srcYmin);
+ ASSERT(*srcY1 <= srcYmax);
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
index b26c27e5a8..20459a5f1e 100644
--- a/src/mesa/main/image.h
+++ b/src/mesa/main/image.h
@@ -54,6 +54,24 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type );
extern GLboolean
_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type );
+extern GLboolean
+_mesa_is_color_format(GLenum format);
+
+extern GLboolean
+_mesa_is_index_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depth_format(GLenum format);
+
+extern GLboolean
+_mesa_is_ycbcr_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depthstencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_dudv_format(GLenum format);
+
extern GLvoid *
_mesa_image_address( GLuint dimensions,
@@ -291,4 +309,10 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
+extern GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
+
+
#endif
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 1722579e82..6ffaddcde9 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -911,6 +911,20 @@ _mesa_strtod( const char *s, char **end )
return strtod(s, end);
}
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++)
+ sum += *c * (i % 100);
+ return sum;
+}
+
+
/*@}*/
@@ -1021,23 +1035,59 @@ output_if_debug(const char *prefixString, const char *outputString,
}
}
-static const char *error_string( GLenum error );
-static void flush_delayed_errors( GLcontext *ctx )
+/**
+ * Return string version of GL error code.
+ */
+static const char *
+error_string( GLenum error )
+{
+ switch (error) {
+ case GL_NO_ERROR:
+ return "GL_NO_ERROR";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "unknown";
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( GLcontext *ctx )
{
- char s2[MAXSTRING];
+ char s[MAXSTRING];
if (ctx->ErrorDebugCount) {
- _mesa_snprintf(s2, MAXSTRING, "%d similar %s errors",
+ _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
ctx->ErrorDebugCount,
error_string(ctx->ErrorValue));
- output_if_debug("Mesa: ", s2, GL_TRUE);
+ output_if_debug("Mesa", s, GL_TRUE);
ctx->ErrorDebugCount = 0;
}
}
+
/**
* Report a warning (a recoverable error condition) to stderr if
* either DEBUG is defined or the MESA_DEBUG env var is set.
@@ -1083,31 +1133,6 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
}
-static const char *error_string( GLenum error )
-{
- switch (error) {
- case GL_NO_ERROR:
- return "GL_NO_ERROR";
- case GL_INVALID_VALUE:
- return "GL_INVALID_VALUE";
- case GL_INVALID_ENUM:
- return "GL_INVALID_ENUM";
- case GL_INVALID_OPERATION:
- return "GL_INVALID_OPERATION";
- case GL_STACK_OVERFLOW:
- return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW:
- return "GL_STACK_UNDERFLOW";
- case GL_OUT_OF_MEMORY:
- return "GL_OUT_OF_MEMORY";
- case GL_TABLE_TOO_LARGE:
- return "GL_TABLE_TOO_LARGE";
- case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
- return "GL_INVALID_FRAMEBUFFER_OPERATION";
- default:
- return "unknown";
- }
-}
/**
* Record an OpenGL state error. These usually occur when the user
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 7b61e22e93..fb85f0862c 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -586,6 +586,9 @@ _mesa_atoi( const char *s );
extern double
_mesa_strtod( const char *s, char **end );
+extern unsigned int
+_mesa_str_checksum(const char *str);
+
extern int
_mesa_sprintf( char *str, const char *fmt, ... );
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 0f0d831fee..10c89f4368 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -528,7 +528,7 @@ _mesa_LightModeliv( GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_LightModelfv( pname, fparam );
}
@@ -1256,15 +1256,15 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state )
ctx->Driver.LightingSpaceChange( ctx );
}
else {
- GLuint new_state = ctx->NewState;
+ GLuint new_state2 = ctx->NewState;
/* Recalculate that same state only if it has been invalidated
* by other statechanges.
*/
- if (new_state & _NEW_MODELVIEW)
+ if (new_state2 & _NEW_MODELVIEW)
update_modelview_scale(ctx);
- if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
compute_light_positions( ctx );
}
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d0309f5e90..41172788ef 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -83,6 +83,7 @@
/*@{*/
struct _mesa_HashTable;
struct gl_attrib_node;
+struct gl_meta_state;
struct gl_pixelstore_attrib;
struct gl_program_cache;
struct gl_texture_format;
@@ -227,7 +228,9 @@ typedef enum
FRAG_ATTRIB_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
+ FRAG_ATTRIB_FACE = 12, /**< front/back face */
+ FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
+ FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
} gl_frag_attrib;
@@ -239,6 +242,8 @@ typedef enum
#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
+#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
+#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
@@ -1834,9 +1839,6 @@ struct gl_fragment_program
struct gl_program Base; /**< base class */
GLenum FogOption;
GLboolean UsesKill; /**< shader uses KIL instruction */
- GLboolean UsesPointCoord; /**< shader uses gl_PointCoord */
- GLboolean UsesFrontFacing; /**< shader used gl_FrontFacing */
- GLboolean UsesFogFragCoord; /**< shader used gl_FogFragCoord */
};
@@ -2004,6 +2006,7 @@ struct gl_shader
GLboolean Main; /**< shader defines main() */
GLboolean UnresolvedRefs;
const GLchar *Source; /**< Source code string */
+ GLuint SourceChecksum; /**< for debug/logging purposes */
struct gl_program *Program; /**< Post-compile assembly code */
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
@@ -2034,6 +2037,7 @@ struct gl_shader_program
struct gl_program_parameter_list *Varying;
GLboolean LinkStatus; /**< GL_LINK_STATUS */
GLboolean Validated;
+ GLboolean _Used; /**< Ever used for drawing? */
GLchar *InfoLog;
};
@@ -2981,6 +2985,8 @@ struct __GLcontextRec
struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
/*@}*/
+ struct gl_meta_state *Meta; /**< for "meta" operations */
+
#if FEATURE_EXT_framebuffer_object
struct gl_renderbuffer *CurrentRenderbuffer;
#endif
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index d9f3e476e8..25f55a422f 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -158,7 +158,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -188,7 +188,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
store_pixelmap(ctx, map, mapsize, values);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -217,7 +217,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -259,7 +259,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -290,7 +290,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* unpack pixelmap from PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Unpack's buffer object */
@@ -333,7 +333,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
@@ -359,7 +359,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -397,7 +397,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat));
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -420,7 +420,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -458,7 +458,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -481,7 +481,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
mapsize = pm ? pm->Size : 0;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack pixelmap into PBO */
GLubyte *buf;
/* Note, need to use DefaultPacking and Pack's buffer object */
@@ -528,7 +528,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index 564250b881..d11c9424d5 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -193,7 +193,7 @@ _mesa_PolygonMode( GLenum face, GLenum mode )
void
_mesa_polygon_stipple(GLcontext *ctx, const GLubyte *pattern)
{
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
/* Get/unpack the stipple pattern from a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Unpack, 32, 32, 1,
@@ -258,7 +258,7 @@ _mesa_GetPolygonStipple( GLubyte *dest )
/* XXX someday we may put this code into a separate function and call
* it with ctx->Driver.GetPolygonStipple().
*/
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Put/pack the stipple pattern into a PBO */
GLubyte *buf;
if (!_mesa_validate_pbo_access(2, &ctx->Pack, 32, 32, 1,
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 2326776ecb..feea1d375f 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -44,6 +44,10 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
GLboolean drawing)
{
const char *readDraw = drawing ? "Draw" : "Read";
+ const GLboolean reading = !drawing;
+
+ /* state validation should have already been done */
+ ASSERT(ctx->NewState == 0x0);
if (ctx->Extensions.EXT_packed_depth_stencil
&& type == GL_UNSIGNED_INT_24_8_EXT
@@ -73,32 +77,45 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
- if (drawing && !ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ if (drawing) {
+ if (!ctx->DrawBuffer->Visual.rgbMode) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(drawing RGB pixels into color index buffer)");
- return GL_TRUE;
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_COLOR_INDEX:
- if (!drawing && ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(reading color index format from RGB buffer)");
- return GL_TRUE;
+ if (drawing) {
+ if (ctx->DrawBuffer->Visual.rgbMode &&
+ (ctx->PixelMaps.ItoR.Size == 0 ||
+ ctx->PixelMaps.ItoG.Size == 0 ||
+ ctx->PixelMaps.ItoB.Size == 0)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(drawing color index pixels into RGB buffer)");
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_STENCIL_INDEX:
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no stencil buffer)", readDraw);
return GL_TRUE;
@@ -118,7 +135,7 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
return GL_TRUE;
}
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no depth or stencil buffer)", readDraw);
return GL_TRUE;
@@ -173,7 +190,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
if (width == 0 || height == 0)
return; /* nothing to do */
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -181,7 +198,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- if (ctx->Pack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
return;
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index ad6e6ce7cd..93bbccd3c7 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -196,7 +196,7 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData)
{
struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
GLcontext *ctx = (GLcontext *) userData;
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->Pointer = NULL;
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index d8191ab518..140a998df2 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -547,7 +547,8 @@ _mesa_update_state_locked( GLcontext *ctx )
/* Determine which state flags effect vertex/fragment program state */
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
prog_flags |= (_NEW_TEXTURE | _NEW_FOG |
- _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE);
+ _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
+ _NEW_PROGRAM);
}
if (ctx->VertexProgram._MaintainTnlProgram) {
prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
@@ -712,6 +713,6 @@ _mesa_set_vp_override(GLcontext *ctx, GLboolean flag)
/* Set one of the bits which will trigger fragment program
* regeneration:
*/
- ctx->NewState |= _NEW_ARRAY;
+ ctx->NewState |= _NEW_PROGRAM;
}
}
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 4c04a7ed37..6d86a4275c 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -35,6 +35,7 @@
#include "main/enums.h"
#include "main/macros.h"
#include "main/texenv.h"
+#include "main/texstate.h"
#define TE_ERROR(errCode, msg, value) \
@@ -466,7 +467,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
switch (pname) {
@@ -793,7 +794,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -857,7 +858,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -908,12 +909,26 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
}
}
-/* why does ATI_envmap_bumpmap require new entrypoints? Should just
- reuse TexEnv ones... */
+
+/**
+ * Why does ATI_envmap_bumpmap require new entrypoints? Should just
+ * reuse TexEnv ones...
+ */
void GLAPIENTRY
_mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
{
GLfloat p[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ /* This isn't an "official" error case, but let's tell the user
+ * that something's wrong.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterivATI");
+ return;
+ }
+
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
/* hope that conversion is correct here */
p[0] = INT_TO_FLOAT( param[0] );
@@ -923,11 +938,12 @@ _mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
}
else {
p[0] = (GLfloat) param[0];
- p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
+ p[1] = p[2] = p[3] = 0.0F; /* init to zero, just to be safe */
}
_mesa_TexBumpParameterfvATI( pname, p );
}
+
void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
{
@@ -935,8 +951,12 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
if (TEST_EQ_4V(param, texUnit->RotMatrix))
@@ -955,17 +975,21 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterivATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
@@ -982,12 +1006,13 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
param[3] = FLOAT_TO_INT(texUnit->RotMatrix[3]);
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = temp;
+ *param = count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1002,23 +1027,27 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
Don't think anyone would ever want to use it
(and apps might not understand it) so hardcode this. */
- *param = (GLfloat) 4;
+ *param = 4.0F;
}
else if (pname == GL_BUMP_ROT_MATRIX_ATI) {
param[0] = texUnit->RotMatrix[0];
@@ -1027,12 +1056,13 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
param[3] = texUnit->RotMatrix[3];
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = (GLfloat) temp;
+ *param = (GLfloat) count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1046,4 +1076,3 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
return;
}
}
-
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 6b090ff399..3736138b9e 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -275,6 +275,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
{
/* _NEW_PROGRAM */
const GLboolean vertexShader = (ctx->Shader.CurrentProgram &&
+ ctx->Shader.CurrentProgram->LinkStatus &&
ctx->Shader.CurrentProgram->VertexProgram);
const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
GLbitfield fp_inputs = 0x0;
@@ -321,8 +322,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
/* Then look at what might be varying as a result of enabled
* arrays, etc:
*/
- if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0;
- if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1;
+ if (varying_inputs & VERT_BIT_COLOR0)
+ fp_inputs |= FRAG_BIT_COL0;
+ if (varying_inputs & VERT_BIT_COLOR1)
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0)
<< FRAG_ATTRIB_TEX0);
@@ -340,7 +343,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (vertexShader)
vprog = ctx->Shader.CurrentProgram->VertexProgram;
else
- vprog = ctx->VertexProgram._Current;
+ vprog = ctx->VertexProgram.Current;
vp_outputs = vprog->Base.OutputsWritten;
@@ -351,8 +354,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (ctx->Point.PointSprite)
vp_outputs |= FRAG_BITS_TEX_ANY;
- if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0;
- if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1;
+ if (vp_outputs & (1 << VERT_RESULT_COL0))
+ fp_inputs |= FRAG_BIT_COL0;
+ if (vp_outputs & (1 << VERT_RESULT_COL1))
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0)
<< FRAG_ATTRIB_TEX0);
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index 02409d8009..14d6fc7659 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -30,11 +30,14 @@
#include "glheader.h"
+#include "bufferobj.h"
#include "context.h"
#include "image.h"
#include "texcompress.h"
#include "texformat.h"
#include "texgetimage.h"
+#include "teximage.h"
+#include "texstate.h"
@@ -116,7 +119,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
{
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Packing texture image into a PBO.
* Map the (potentially) VRAM-based buffer into our process space so
* we can write into it with the code below.
@@ -296,7 +299,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
} /* img */
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -316,7 +319,7 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
{
GLuint size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack texture image into a PBO */
GLubyte *buf;
if ((const GLubyte *) img + texImage->CompressedSize >
@@ -349,8 +352,230 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
/* just memcpy, no pixelstore or pixel transfer */
_mesa_memcpy(img, texImage->Data, size);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
}
+
+
+
+/**
+ * Do error checking for a glGetTexImage() call.
+ * \return GL_TRUE if any error, GL_FALSE if no errors.
+ */
+static GLboolean
+getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+
+ if (maxLevels == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target);
+ return GL_TRUE;
+ }
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_sizeof_packed_type(type) <= 0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_components_in_format(format) <= 0 ||
+ format == GL_STENCIL_INDEX) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_packed_depth_stencil
+ && _mesa_is_depthstencil_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap
+ && _mesa_is_dudv_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ if (!texObj || _mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+ return GL_TRUE;
+ }
+
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (!texImage) {
+ /* out of memory */
+ return GL_TRUE;
+ }
+
+ /* Make sure the requested image format is compatible with the
+ * texture's format. Note that a color index texture can be converted
+ * to RGBA so that combo is allowed.
+ */
+ if (_mesa_is_color_format(format)
+ && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_index_format(format)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depth_format(format)
+ && !_mesa_is_depth_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_ycbcr_format(format)
+ && !_mesa_is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depthstencil_format(format)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_dudv_format(format)
+ && !_mesa_is_dudv_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
+ /* packing texture image into a PBO */
+ const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
+ texImage->Height, texImage->Depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexImage(invalid PBO access)");
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+
+/**
+ * Get texture image. Called by glGetTexImage.
+ *
+ * \param target texture target.
+ * \param level image level.
+ * \param format pixel data format for returned image.
+ * \param type pixel data type for returned image.
+ * \param pixels returned pixel data.
+ */
+void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* typically, this will call _mesa_get_teximage() */
+ ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLint maxLevels;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (_mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return;
+ }
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (texImage) {
+ if (texImage->IsCompressed) {
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
+ texObj, texImage);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImageARB");
+ }
+ }
+ else {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetCompressedTexImageARB(level)");
+ }
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h
index 01f486e8f0..088d27c7e1 100644
--- a/src/mesa/main/texgetimage.h
+++ b/src/mesa/main/texgetimage.h
@@ -43,4 +43,13 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+extern void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
+
+
#endif /* TEXGETIMAGE_H */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 825f5e26bf..8228303040 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -182,6 +182,8 @@ logbase2( int n )
*
* This is the format which is used during texture application (i.e. the
* texture format and env mode determine the arithmetic used.
+ *
+ * XXX this could be static
*/
GLint
_mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
@@ -415,211 +417,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
/**
- * Test if the given image format is a color/RGBA format (i.e., not color
- * index, depth, stencil, etc).
- * \param format the image format value (may by an internal texture format)
- * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
- * XXX maybe move this func to image.c
- */
-GLboolean
-_mesa_is_color_format(GLenum format)
-{
- switch (format) {
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case 3:
- case GL_RGB:
- case GL_BGR:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- case 4:
- case GL_ABGR_EXT:
- case GL_RGBA:
- case GL_BGRA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- /* float texture formats */
- case GL_ALPHA16F_ARB:
- case GL_ALPHA32F_ARB:
- case GL_LUMINANCE16F_ARB:
- case GL_LUMINANCE32F_ARB:
- case GL_LUMINANCE_ALPHA16F_ARB:
- case GL_LUMINANCE_ALPHA32F_ARB:
- case GL_INTENSITY16F_ARB:
- case GL_INTENSITY32F_ARB:
- case GL_RGB16F_ARB:
- case GL_RGB32F_ARB:
- case GL_RGBA16F_ARB:
- case GL_RGBA32F_ARB:
- /* compressed formats */
- case GL_COMPRESSED_ALPHA:
- case GL_COMPRESSED_LUMINANCE:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- case GL_COMPRESSED_INTENSITY:
- case GL_COMPRESSED_RGB:
- case GL_COMPRESSED_RGBA:
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
-#if FEATURE_EXT_texture_sRGB
- case GL_SRGB_EXT:
- case GL_SRGB8_EXT:
- case GL_SRGB_ALPHA_EXT:
- case GL_SRGB8_ALPHA8_EXT:
- case GL_SLUMINANCE_ALPHA_EXT:
- case GL_SLUMINANCE8_ALPHA8_EXT:
- case GL_SLUMINANCE_EXT:
- case GL_SLUMINANCE8_EXT:
- case GL_COMPRESSED_SRGB_EXT:
- case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_SLUMINANCE_EXT:
- case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
-#endif /* FEATURE_EXT_texture_sRGB */
- return GL_TRUE;
- /* signed texture formats */
- case GL_RGBA_SNORM:
- case GL_RGBA8_SNORM:
- return GL_TRUE;
- case GL_YCBCR_MESA: /* not considered to be RGB */
- /* fall-through */
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a color index format.
- */
-static GLboolean
-is_index_format(GLenum format)
-{
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a depth component format.
- */
-static GLboolean
-is_depth_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- case GL_DEPTH_COMPONENT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a YCbCr format.
- */
-static GLboolean
-is_ycbcr_format(GLenum format)
-{
- switch (format) {
- case GL_YCBCR_MESA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a Depth/Stencil format.
- */
-static GLboolean
-is_depthstencil_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH24_STENCIL8_EXT:
- case GL_DEPTH_STENCIL_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-/**
- * Test if the given image format is a dudv format.
- */
-static GLboolean
-is_dudv_format(GLenum format)
-{
- switch (format) {
- case GL_DUDV_ATI:
- case GL_DU8DV8_ATI:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
* Test if it is a supported compressed format.
*
* \param internalFormat the internal format token provided by the user.
@@ -765,6 +562,9 @@ _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
GLboolean
_mesa_is_proxy_texture(GLenum target)
{
+ /* NUM_TEXTURE_TARGETS should match number of terms below */
+ assert(NUM_TEXTURE_TARGETS == 7);
+
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
target == GL_PROXY_TEXTURE_3D ||
@@ -776,18 +576,6 @@ _mesa_is_proxy_texture(GLenum target)
/**
- * Return pointer to current texture unit.
- * This the texture unit set by glActiveTexture(), not glClientActiveTexture().
- */
-static INLINE struct gl_texture_unit *
-get_current_tex_unit(GLcontext *ctx)
-{
- ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
- return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
-}
-
-
-/**
* Get the texture object that corresponds to the target of the given texture unit.
*
* \param ctx GL context.
@@ -996,10 +784,6 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_PROXY_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
return ctx->Const.MaxTextureLevels;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
@@ -1012,10 +796,17 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
case GL_TEXTURE_CUBE_MAP_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- return ctx->Const.MaxCubeTextureLevels;
+ return ctx->Extensions.ARB_texture_cube_map
+ ? ctx->Const.MaxCubeTextureLevels : 0;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return 1;
+ return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array
+ ? ctx->Const.MaxTextureLevels : 0;
default:
return 0; /* bad target */
}
@@ -1216,6 +1007,23 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
/**
+ * Free and clear fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param texImage texture image structure to be cleared.
+ *
+ * After the call, \p texImage will have no data associated with it. Its
+ * fields are cleared so that its parent object will test incomplete.
+ */
+void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage)
+{
+ ctx->Driver.FreeTexImageData(ctx, texImage);
+ clear_teximage_fields(texImage);
+}
+
+
+/**
* This is the fallback for Driver.TestProxyTexImage(). Test the texture
* level, width, height and depth against the ctx->Const limits for textures.
*
@@ -1529,13 +1337,13 @@ texture_error_check( GLcontext *ctx, GLenum target,
/* make sure internal format and format basically agree */
colorFormat = _mesa_is_color_format(format);
- indexFormat = is_index_format(format);
+ indexFormat = _mesa_is_index_format(format);
if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
- (is_index_format(internalFormat) && !indexFormat) ||
- (is_depth_format(internalFormat) != is_depth_format(format)) ||
- (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
- (is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
- (is_dudv_format(internalFormat) != is_dudv_format(format))) {
+ (_mesa_is_index_format(internalFormat) && !indexFormat) ||
+ (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
+ (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
+ (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
+ (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
@@ -1970,7 +1778,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depth_format(internalFormat)) {
+ else if (_mesa_is_depth_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -1978,7 +1786,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depthstencil_format(internalFormat)) {
+ else if (_mesa_is_depthstencil_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2203,169 +2011,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
-/**
- * Do error checking for a glGetTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
- */
-static GLboolean
-getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
-
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
- return GL_TRUE;
- }
-
- if (_mesa_sizeof_packed_type(type) <= 0) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
- return GL_TRUE;
- }
-
- if (_mesa_components_in_format(format) <= 0 ||
- format == GL_STENCIL_INDEX) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_packed_depth_stencil
- && is_depthstencil_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ATI_envmap_bumpmap
- && is_dudv_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* out of memory */
- return GL_TRUE;
- }
-
- /* Make sure the requested image format is compatible with the
- * texture's format. Note that a color index texture can be converted
- * to RGBA so that combo is allowed.
- */
- if (_mesa_is_color_format(format)
- && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_index_format(format)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_depth_format(format)
- && !is_depth_format(texImage->TexFormat->BaseFormat)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_ycbcr_format(format)
- && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_depthstencil_format(format)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (is_dudv_format(format)
- && !is_dudv_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
-
- if (ctx->Pack.BufferObj->Name) {
- /* packing texture image into a PBO */
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
- texImage->Height, texImage->Depth,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexImage(invalid PBO access)");
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
-}
-
-
-
-/**
- * Get texture image. Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param pixels returned pixel data.
- */
-void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj || _mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
- return;
- }
-
- if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- struct gl_texture_image *texImage =
- _mesa_select_tex_image(ctx, texObj, target, level);
-
- /* typically, this will call _mesa_get_teximage() */
- ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
- texObj, texImage);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
/** Callback info for walking over FBO hash table */
struct cb_info
{
@@ -2509,7 +2154,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2617,7 +2262,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2720,7 +2365,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2826,7 +2471,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
assert(texObj);
@@ -2886,7 +2531,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -2938,7 +2583,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -2999,7 +2644,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
postConvWidth, 1, border))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3065,7 +2710,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
postConvWidth, postConvHeight, border))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3125,7 +2770,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 1, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3180,7 +2825,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 2, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3235,7 +2880,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
if (copytexsubimage_error_check1(ctx, 3, target, level))
return;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3489,7 +3134,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3543,7 +3188,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3586,7 +3231,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3642,7 +3287,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3682,7 +3327,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3736,7 +3381,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3775,7 +3420,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3832,7 +3477,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3889,7 +3534,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = get_current_tex_unit(ctx);
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3926,55 +3571,3 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
}
-void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLint maxLevels;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = get_current_tex_unit(ctx);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
- return;
- }
-
- maxLevels = _mesa_max_texture_levels(ctx, target);
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
- return;
- }
-
- if (_mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (texImage) {
- if (texImage->IsCompressed) {
- /* this typically calls _mesa_get_compressed_teximage() */
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
- texObj, texImage);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImageARB");
- }
- }
- else {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(level)");
- }
- }
- _mesa_unlock_texture(ctx, texObj);
-}
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index eb60a1fa8f..094177da79 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -73,6 +73,10 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
extern void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage);
+
+
+extern void
_mesa_set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
struct gl_texture_image *texImage);
@@ -111,10 +115,6 @@ extern GLuint
_mesa_tex_target_to_face(GLenum target);
-extern GLboolean
-_mesa_is_color_format(GLenum format);
-
-
/**
* Lock a texture for updating. See also _mesa_lock_context_textures().
*/
@@ -164,11 +164,6 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
extern void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels );
-
-
-extern void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
GLsizei width,
GLenum format, GLenum type,
@@ -260,9 +255,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data);
-extern void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
-
/*@}*/
#endif
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 2082f945f1..d09c439250 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -261,6 +261,32 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
/**
+ * Clear all texture images of the given texture object.
+ *
+ * \param ctx GL context.
+ * \param t texture object.
+ *
+ * \sa _mesa_clear_texture_image().
+ */
+void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+ GLuint i, j;
+
+ if (texObj->Target == 0)
+ return;
+
+ for (i = 0; i < MAX_FACES; i++) {
+ for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
+ struct gl_texture_image *texImage = texObj->Image[i][j];
+ if (texImage)
+ _mesa_clear_texture_image(ctx, texImage);
+ }
+ }
+}
+
+
+/**
* Check if the given texture object is valid by examining its Target field.
* For debugging only.
*/
@@ -308,7 +334,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
GLboolean deleteFlag = GL_FALSE;
struct gl_texture_object *oldTex = *ptr;
- assert(valid_texture_object(oldTex));
+ ASSERT(valid_texture_object(oldTex));
_glthread_LOCK_MUTEX(oldTex->Mutex);
ASSERT(oldTex->RefCount > 0);
@@ -331,7 +357,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
if (tex) {
/* reference new texture */
- assert(valid_texture_object(tex));
+ ASSERT(valid_texture_object(tex));
_glthread_LOCK_MUTEX(tex->Mutex);
if (tex->RefCount == 0) {
/* this texture's being deleted (look just above) */
@@ -665,6 +691,24 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
/**
+ * Mark a texture object dirty. It forces the object to be incomplete
+ * and optionally forces the context to re-validate its state.
+ *
+ * \param ctx GL context.
+ * \param texObj texture object.
+ * \param invalidate_state also invalidate context state.
+ */
+void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state)
+{
+ texObj->_Complete = GL_FALSE;
+ if (invalidate_state)
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+/**
* Return pointer to a default/fallback texture.
* The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1).
* That's the value a sampler should get when sampling from an
@@ -715,7 +759,6 @@ _mesa_get_fallback_texture(GLcontext *ctx)
}
-
/*@}*/
@@ -1160,10 +1203,9 @@ _mesa_IsTexture( GLuint texture )
/**
- * Simplest implementation of texture locking: Grab the a new mutex in
- * the shared context. Examine the shared context state timestamp and
- * if there has been a change, set the appropriate bits in
- * ctx->NewState.
+ * Simplest implementation of texture locking: grab the shared tex
+ * mutex. Examine the shared context state timestamp and if there has
+ * been a change, set the appropriate bits in ctx->NewState.
*
* This is used to deal with synchronizing things when a texture object
* is used/modified by different contexts (or threads) which are sharing
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 2599c0816a..9bfebd45c8 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -58,6 +58,9 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
extern void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *obj);
+
+extern void
_mesa_reference_texobj(struct gl_texture_object **ptr,
struct gl_texture_object *tex);
@@ -65,6 +68,10 @@ extern void
_mesa_test_texobj_completeness( const GLcontext *ctx,
struct gl_texture_object *obj );
+extern void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state);
+
extern struct gl_texture_object *
_mesa_get_fallback_texture(GLcontext *ctx);
@@ -76,7 +83,6 @@ _mesa_lock_context_textures( GLcontext *ctx );
/*@}*/
-
/**
* \name API functions
*/
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index d27c59381c..05d144270e 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -38,6 +38,7 @@
#include "main/texcompress.h"
#include "main/texparam.h"
#include "main/teximage.h"
+#include "main/texstate.h"
#include "shader/prog_instruction.h"
@@ -88,7 +89,7 @@ get_texobj(GLcontext *ctx, GLenum target)
return NULL;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
switch (target) {
case GL_TEXTURE_1D:
@@ -716,44 +717,6 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
}
-static GLuint
-tex_image_dimensions(GLcontext *ctx, GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_PROXY_TEXTURE_1D:
- return 1;
- case GL_TEXTURE_2D:
- case GL_PROXY_TEXTURE_2D:
- return 2;
- case GL_TEXTURE_3D:
- case GL_PROXY_TEXTURE_3D:
- return 3;
- case GL_TEXTURE_CUBE_MAP:
- case GL_PROXY_TEXTURE_CUBE_MAP:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 2 : 0;
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 3 : 0;
- default:
- _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
- return 0;
- }
-}
-
-
void GLAPIENTRY
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
GLenum pname, GLint *params )
@@ -761,7 +724,6 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
const struct gl_texture_image *img = NULL;
- GLuint dimensions;
GLboolean isProxy;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
@@ -773,19 +735,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
/* this will catch bad target values */
- dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
- if (dimensions == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
- return;
- }
-
maxLevels = _mesa_max_texture_levels(ctx, target);
if (maxLevels == 0) {
- /* should not happen since <target> was just checked above */
- _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(target=0x%x)", target);
return;
}
@@ -1002,7 +958,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
@@ -1169,7 +1125,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
index a7d7088c62..17ac68000c 100644
--- a/src/mesa/main/texstate.h
+++ b/src/mesa/main/texstate.h
@@ -35,6 +35,18 @@
#include "mtypes.h"
+/**
+ * Return pointer to current texture unit.
+ * This the texture unit set by glActiveTexture(), not glClientActiveTexture().
+ */
+static INLINE struct gl_texture_unit *
+_mesa_get_current_tex_unit(GLcontext *ctx)
+{
+ ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
+ return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+}
+
+
extern void
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst );
@@ -48,16 +60,14 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit );
*/
/*@{*/
-
-/*
- * GL_ARB_multitexture
- */
extern void GLAPIENTRY
_mesa_ActiveTextureARB( GLenum target );
extern void GLAPIENTRY
_mesa_ClientActiveTextureARB( GLenum target );
+/*@}*/
+
/**
* \name Initialization, state maintenance
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index bfced1b3f4..a22db628d3 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -3138,7 +3138,7 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
{
GLubyte *buf;
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
return pixels;
}
@@ -3174,7 +3174,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
{
GLubyte *buf;
- if (packing->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(packing->BufferObj)) {
/* not using a PBO - return pointer unchanged */
return pixels;
}
@@ -3204,7 +3204,7 @@ void
_mesa_unmap_teximage_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 3d5b8faecf..be1c03cec2 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -135,7 +135,8 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -186,7 +187,8 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -265,7 +267,8 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -415,7 +418,8 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -476,7 +480,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -610,7 +615,8 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -1093,6 +1099,29 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
/**
+ * Copy one client vertex array to another.
+ */
+void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src)
+{
+ dst->Size = src->Size;
+ dst->Type = src->Type;
+ dst->Format = src->Format;
+ dst->Stride = src->Stride;
+ dst->StrideB = src->StrideB;
+ dst->Ptr = src->Ptr;
+ dst->Enabled = src->Enabled;
+ dst->Normalized = src->Normalized;
+ dst->_ElementSize = src->_ElementSize;
+ _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
+ dst->_MaxElement = src->_MaxElement;
+}
+
+
+
+/**
* Print vertex array's fields.
*/
static void
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index d4d505ae04..becc67c29d 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -161,6 +161,12 @@ _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
extern void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src);
+
+
+extern void
_mesa_print_arrays(GLcontext *ctx);
extern void
diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
index 50e0402d27..309308c983 100644
--- a/src/mesa/main/viewport.c
+++ b/src/mesa/main/viewport.c
@@ -120,6 +120,10 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval)
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval);
+ if (ctx->Viewport.Near == nearval &&
+ ctx->Viewport.Far == farval)
+ return;
+
ctx->Viewport.Near = (GLfloat) CLAMP(nearval, 0.0, 1.0);
ctx->Viewport.Far = (GLfloat) CLAMP(farval, 0.0, 1.0);
ctx->NewState |= _NEW_VIEWPORT;