#include "api_arrayelt.h"
#include "api_exec.h"
#include "api_loopback.h"
+#include "api_validate.h"
#if FEATURE_ATI_fragment_shader
#include "atifragshader.h"
#endif
#include "config.h"
#include "mfeatures.h"
-#if FEATURE_ARB_vertex_buffer_object
#include "bufferobj.h"
-#endif
#include "arrayobj.h"
#include "context.h"
#include "dlist.h"
#include "enums.h"
#include "eval.h"
+#if FEATURE_EXT_framebuffer_object
+#include "fbobject.h"
+#endif
#include "framebuffer.h"
#include "glapi/glapi.h"
-#include "glapidispatch.h"
+#include "glformats.h"
#include "hash.h"
#include "image.h"
#include "light.h"
#include "shaderapi.h"
#include "syncobj.h"
#include "teximage.h"
+#include "texstorage.h"
#include "mtypes.h"
#include "varray.h"
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
#include "nvprogram.h"
#endif
+#if FEATURE_EXT_transform_feedback
+#include "transformfeedback.h"
+#endif
#include "math/m_matrix.h"
do { \
if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
return retval; \
} \
} while (0)
do { \
if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
- _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glBegin/End" ); \
return; \
} \
} while (0)
/* GL_EXT_transform_feedback */
OPCODE_BEGIN_TRANSFORM_FEEDBACK,
OPCODE_END_TRANSFORM_FEEDBACK,
+ OPCODE_BIND_TRANSFORM_FEEDBACK,
+ OPCODE_PAUSE_TRANSFORM_FEEDBACK,
+ OPCODE_RESUME_TRANSFORM_FEEDBACK,
+ OPCODE_DRAW_TRANSFORM_FEEDBACK,
/* GL_EXT_texture_integer */
OPCODE_CLEARCOLOR_I,
/* GL_ARB_geometry_shader4 */
OPCODE_PROGRAM_PARAMETERI,
+ OPCODE_FRAMEBUFFER_TEXTURE,
+ OPCODE_FRAMEBUFFER_TEXTURE_FACE,
/* GL_ARB_sync */
OPCODE_WAIT_SYNC,
+ /* GL_NV_conditional_render */
+ OPCODE_BEGIN_CONDITIONAL_RENDER,
+ OPCODE_END_CONDITIONAL_RENDER,
+
+ /* ARB_timer_query */
+ OPCODE_QUERY_COUNTER,
+
+ /* ARB_transform_feedback3 */
+ OPCODE_BEGIN_QUERY_INDEXED,
+ OPCODE_END_QUERY_INDEXED,
+ OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM,
+
+ /* ARB_transform_feedback_instanced */
+ OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED,
+ OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED,
+
+ /* ARB_uniform_buffer_object */
+ OPCODE_UNIFORM_BLOCK_BINDING,
+
/* The following three are meta instructions */
OPCODE_ERROR, /* raise compiled-in error */
OPCODE_CONTINUE,
GLuint ui;
GLenum e;
GLfloat f;
+ GLsizei si;
GLvoid *data;
void *next; /* If prev node's opcode==OPCODE_CONTINUE */
};
{
struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list);
dlist->Name = name;
- dlist->Head = (Node *) malloc(sizeof(Node) * count);
+ dlist->Head = malloc(sizeof(Node) * count);
dlist->Head[0].opcode = OPCODE_END_OF_LIST;
return dlist;
}
/**
* Lookup function to just encapsulate casting.
*/
-static INLINE struct gl_display_list *
+static inline struct gl_display_list *
lookup_list(struct gl_context *ctx, GLuint list)
{
return (struct gl_display_list *)
/** Is the given opcode an extension code? */
-static INLINE GLboolean
+static inline GLboolean
is_ext_opcode(OpCode opcode)
{
return (opcode >= OPCODE_EXT_0);
/**********************************************************************/
/**
- * Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
- * If we run out of memory, GL_OUT_OF_MEMORY will be recorded.
+ * Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
+ * If width < 0 or height < 0 or format or type are invalid we'll just
+ * return NULL. We will not generate an error since OpenGL command
+ * arguments aren't error-checked until the command is actually executed
+ * (not when they're compiled).
+ * But if we run out of memory, GL_OUT_OF_MEMORY will be recorded.
*/
static GLvoid *
unpack_image(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, const GLvoid * pixels,
const struct gl_pixelstore_attrib *unpack)
{
+ if (width <= 0 || height <= 0) {
+ return NULL;
+ }
+
+ if (_mesa_bytes_per_pixel(format, type) < 0) {
+ /* bad format and/or type */
+ return NULL;
+ }
+
if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
- GLvoid *image = _mesa_unpack_image(dimensions, width, height, depth,
- format, type, pixels, unpack);
+ GLvoid *image;
+
+ if (type == GL_BITMAP)
+ image = _mesa_unpack_bitmap(width, height, pixels, unpack);
+ else
+ 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");
}
GLvoid *image;
map = (GLubyte *)
- ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB, unpack->BufferObj);
+ ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
+ GL_MAP_READ_BIT, unpack->BufferObj);
if (!map) {
/* unable to map src buffer! */
_mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
}
src = ADD_POINTERS(map, pixels);
- image = _mesa_unpack_image(dimensions, width, height, depth,
- format, type, src, unpack);
+ if (type == GL_BITMAP)
+ image = _mesa_unpack_bitmap(width, height, src, unpack);
+ else
+ image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, src, unpack);
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
}
return image;
}
+
/* bad access! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "invalid PBO access");
return NULL;
}
-
/**
* Allocate space for a display list instruction (opcode + payload space).
* \param opcode the instruction opcode (OPCODE_* value)
Node *newblock;
n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
n[0].opcode = OPCODE_CONTINUE;
- newblock = (Node *) malloc(sizeof(Node) * BLOCK_SIZE);
+ newblock = malloc(sizeof(Node) * BLOCK_SIZE);
if (!newblock) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
return NULL;
* \param nparams number of function parameters
* \return pointer to start of instruction space
*/
-static INLINE Node *
+static inline Node *
alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
{
return dlist_alloc(ctx, opcode, nparams * sizeof(Node));
n[4].f = yorig;
n[5].f = xmove;
n[6].f = ymove;
- n[7].data = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
+ n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
+ GL_BITMAP, pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_Bitmap(ctx->Exec, (width, height,
}
+/* GL_ARB_draw_instanced. */
+static void GLAPIENTRY
+save_DrawArraysInstancedARB(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawArraysInstanced() during display list compile");
+}
+
+static void GLAPIENTRY
+save_DrawElementsInstancedARB(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElementsInstanced() during display list compile");
+}
+
+static void GLAPIENTRY
+save_DrawElementsInstancedBaseVertexARB(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei primcount,
+ GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElementsInstancedBaseVertex() during display list compile");
+}
+
+/* GL_ARB_base_instance. */
+static void GLAPIENTRY
+save_DrawArraysInstancedBaseInstance(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount,
+ GLuint baseinstance)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawArraysInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseInstance(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount,
+ GLuint baseinstance)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElementsInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
+}
+
static void invalidate_saved_current_state( struct gl_context *ctx )
{
GLint i;
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));
}
}
}
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value));
}
}
n[4].i = stencil;
}
if (ctx->ExecuteFlag) {
- /*CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));*/
+ CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil));
}
}
if (n) {
n[1].e = map;
n[2].i = mapsize;
- n[3].data = (void *) malloc(mapsize * sizeof(GLfloat));
+ n[3].data = malloc(mapsize * sizeof(GLfloat));
memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
}
if (ctx->ExecuteFlag) {
save_MultMatrixf(tm);
}
+static GLvoid *copy_data(const GLvoid *data, GLsizei size, const char *func)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLvoid *image;
+
+ if (!data)
+ return NULL;
+
+ image = malloc(size);
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+ return NULL;
+ }
+ memcpy(image, data, size);
+
+ return image;
+}
+
/* GL_ARB_texture_compression */
static void GLAPIENTRY
}
else {
Node *n;
- GLvoid *image;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB");
- return;
- }
- memcpy(image, data, imageSize);
+
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7);
if (n) {
n[1].e = target;
n[4].i = (GLint) width;
n[5].i = border;
n[6].i = imageSize;
- n[7].data = image;
- }
- else if (image) {
- free(image);
+ n[7].data = copy_data(data, imageSize, "glCompressedTexImage1DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage1DARB(ctx->Exec,
}
else {
Node *n;
- GLvoid *image;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
- return;
- }
- memcpy(image, data, imageSize);
+
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8);
if (n) {
n[1].e = target;
n[5].i = (GLint) height;
n[6].i = border;
n[7].i = imageSize;
- n[8].data = image;
- }
- else if (image) {
- free(image);
+ n[8].data = copy_data(data, imageSize, "glCompressedTexImage2DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage2DARB(ctx->Exec,
}
else {
Node *n;
- GLvoid *image;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB");
- return;
- }
- memcpy(image, data, imageSize);
+
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9);
if (n) {
n[1].e = target;
n[6].i = (GLint) depth;
n[7].i = border;
n[8].i = imageSize;
- n[9].data = image;
- }
- else if (image) {
- free(image);
+ n[9].data = copy_data(data, imageSize, "glCompressedTexImage3DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage3DARB(ctx->Exec,
GLsizei imageSize, const GLvoid * data)
{
Node *n;
- GLvoid *image;
-
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB");
- return;
- }
- memcpy(image, data, imageSize);
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7);
if (n) {
n[1].e = target;
n[4].i = (GLint) width;
n[5].e = format;
n[6].i = imageSize;
- n[7].data = image;
- }
- else if (image) {
- free(image);
+ n[7].data = copy_data(data, imageSize, "glCompressedTexSubImage1DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage1DARB(ctx->Exec, (target, level, xoffset,
const GLvoid * data)
{
Node *n;
- GLvoid *image;
-
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB");
- return;
- }
- memcpy(image, data, imageSize);
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9);
if (n) {
n[1].e = target;
n[6].i = (GLint) height;
n[7].e = format;
n[8].i = imageSize;
- n[9].data = image;
- }
- else if (image) {
- free(image);
+ n[9].data = copy_data(data, imageSize, "glCompressedTexSubImage2DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage2DARB(ctx->Exec,
GLsizei imageSize, const GLvoid * data)
{
Node *n;
- GLvoid *image;
-
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- /* make copy of image */
- image = malloc(imageSize);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB");
- return;
- }
- memcpy(image, data, imageSize);
n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11);
if (n) {
n[1].e = target;
n[8].i = (GLint) depth;
n[9].e = format;
n[10].i = imageSize;
- n[11].data = image;
- }
- else if (image) {
- free(image);
+ n[11].data = copy_data(data, imageSize, "glCompressedTexSubImage3DARB");
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage3DARB(ctx->Exec,
n = alloc_instruction(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
if (n) {
- GLubyte *programCopy = (GLubyte *) malloc(len);
+ GLubyte *programCopy = malloc(len);
if (!programCopy) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return;
n = alloc_instruction(ctx, OPCODE_TRACK_MATRIX_NV, 2);
if (n) {
- GLuint *idCopy = (GLuint *) malloc(num * sizeof(GLuint));
+ GLuint *idCopy = malloc(num * sizeof(GLuint));
if (!idCopy) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
return;
n = alloc_instruction(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
if (n) {
- GLubyte *nameCopy = (GLubyte *) malloc(len);
+ GLubyte *nameCopy = malloc(len);
if (!nameCopy) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
return;
n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
if (n) {
- GLubyte *programCopy = (GLubyte *) malloc(len);
+ GLubyte *programCopy = malloc(len);
if (!programCopy) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
return;
}
}
-
static void GLAPIENTRY
save_EndQueryARB(GLenum target)
{
}
}
+static void GLAPIENTRY
+save_QueryCounter(GLuint id, GLenum target)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_QUERY_COUNTER, 2);
+ if (n) {
+ n[1].ui = id;
+ n[2].e = target;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_QueryCounter(ctx->Exec, (id, target));
+ }
+}
+
+static void GLAPIENTRY
+save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_BEGIN_QUERY_INDEXED, 3);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ n[3].ui = id;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BeginQueryIndexed(ctx->Exec, (target, index, id));
+ }
+}
+
+static void GLAPIENTRY
+save_EndQueryIndexed(GLenum target, GLuint index)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_END_QUERY_INDEXED, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = index;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_EndQueryIndexed(ctx->Exec, (target, index));
+ }
+}
+
#endif /* FEATURE_queryobj */
static void GLAPIENTRY
save_EdgeFlag(GLboolean x)
{
- save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
+ save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0f : 0.0f);
}
-static INLINE GLboolean compare4fv( const GLfloat *a,
- const GLfloat *b,
- GLuint count )
+
+/**
+ * Compare 'count' elements of vectors 'a' and 'b'.
+ * \return GL_TRUE if equal, GL_FALSE if different.
+ */
+static inline GLboolean
+compare_vec(const GLfloat *a, const GLfloat *b, GLuint count)
{
return memcmp( a, b, count * sizeof(GLfloat) ) == 0;
}
-
+
+/**
+ * This glMaterial function is used for glMaterial calls that are outside
+ * a glBegin/End pair. For glMaterial inside glBegin/End, see the VBO code.
+ */
static void GLAPIENTRY
save_Materialfv(GLenum face, GLenum pname, const GLfloat * param)
{
case GL_FRONT_AND_BACK:
break;
default:
- _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(face)");
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(face)");
return;
}
args = 3;
break;
default:
- _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)");
+ _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMaterial(pname)");
return;
}
for (i = 0; i < MAT_ATTRIB_MAX; i++) {
if (bitmask & (1 << i)) {
if (ctx->ListState.ActiveMaterialSize[i] == args &&
- compare4fv(ctx->ListState.CurrentMaterial[i], param, args)) {
+ compare_vec(ctx->ListState.CurrentMaterial[i], param, args)) {
+ /* no change in material value */
bitmask &= ~(1 << i);
}
else {
}
}
- /* If this call has effect, return early:
- */
+ /* If this call has no effect, return early */
if (bitmask == 0)
return;
Node *n;
GLboolean error = GL_FALSE;
- if ( /*mode < GL_POINTS || */ mode > GL_POLYGON) {
- _mesa_compile_error(ctx, GL_INVALID_ENUM, "Begin (mode)");
+ if (mode > GL_POLYGON) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBegin(mode=%x)", mode);
error = GL_TRUE;
}
+ if (ctx->ExecuteFlag) {
+ if (!_mesa_valid_prim_mode(ctx, mode, "glBegin")) {
+ error = GL_TRUE;
+ }
+ }
+
else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
/* Typically the first begin. This may raise an error on
* playback, depending on whether CallList is issued from inside
}
}
+static void GLAPIENTRY
+save_BindTransformFeedback(GLenum target, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_BIND_TRANSFORM_FEEDBACK, 2);
+ if (n) {
+ n[1].e = target;
+ n[2].ui = name;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BindTransformFeedback(ctx->Exec, (target, name));
+ }
+}
+
+static void GLAPIENTRY
+save_PauseTransformFeedback(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) alloc_instruction(ctx, OPCODE_PAUSE_TRANSFORM_FEEDBACK, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PauseTransformFeedback(ctx->Exec, ());
+ }
+}
+
+static void GLAPIENTRY
+save_ResumeTransformFeedback(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) alloc_instruction(ctx, OPCODE_RESUME_TRANSFORM_FEEDBACK, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_ResumeTransformFeedback(ctx->Exec, ());
+ }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedback(GLenum mode, GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK, 2);
+ if (n) {
+ n[1].e = mode;
+ n[2].ui = name;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawTransformFeedback(ctx->Exec, (mode, name));
+ }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM, 3);
+ if (n) {
+ n[1].e = mode;
+ n[2].ui = name;
+ n[3].ui = stream;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawTransformFeedbackStream(ctx->Exec, (mode, name, stream));
+ }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
+ GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED, 3);
+ if (n) {
+ n[1].e = mode;
+ n[2].ui = name;
+ n[3].si = primcount;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawTransformFeedbackInstanced(ctx->Exec, (mode, name, primcount));
+ }
+}
+
+static void GLAPIENTRY
+save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name,
+ GLuint stream, GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED, 4);
+ if (n) {
+ n[1].e = mode;
+ n[2].ui = name;
+ n[3].ui = stream;
+ n[4].si = primcount;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec, (mode, name, stream,
+ primcount));
+ }
+}
/* aka UseProgram() */
static void GLAPIENTRY
}
}
+static void GLAPIENTRY
+save_FramebufferTexture(GLenum target, GLenum attachment,
+ GLuint texture, GLint level)
+{
+ Node *n;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE, 4);
+ if (n) {
+ n[1].e = target;
+ n[2].e = attachment;
+ n[3].ui = texture;
+ n[4].i = level;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_FramebufferTextureARB(ctx->Exec, (target, attachment, texture, level));
+ }
+}
+
+static void GLAPIENTRY
+save_FramebufferTextureFace(GLenum target, GLenum attachment,
+ GLuint texture, GLint level, GLenum face)
+{
+ Node *n;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_FRAMEBUFFER_TEXTURE_FACE, 5);
+ if (n) {
+ n[1].e = target;
+ n[2].e = attachment;
+ n[3].ui = texture;
+ n[4].i = level;
+ n[5].e = face;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_FramebufferTextureFaceARB(ctx->Exec, (target, attachment, texture,
+ level, face));
+ }
+}
+
+
static void GLAPIENTRY
save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
}
+/** GL_NV_conditional_render */
+static void GLAPIENTRY
+save_BeginConditionalRender(GLuint queryId, GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_BEGIN_CONDITIONAL_RENDER, 2);
+ if (n) {
+ n[1].i = queryId;
+ n[2].e = mode;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_BeginConditionalRenderNV(ctx->Exec, (queryId, mode));
+ }
+}
+
+static void GLAPIENTRY
+save_EndConditionalRender(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ alloc_instruction(ctx, OPCODE_END_CONDITIONAL_RENDER, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_EndConditionalRenderNV(ctx->Exec, ());
+ }
+}
+
+static void GLAPIENTRY
+save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_BLOCK_BINDING, 3);
+ if (n) {
+ n[1].ui = prog;
+ n[2].ui = index;
+ n[3].ui = binding;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformBlockBinding(ctx->Exec, (prog, index, binding));
+ }
+}
+
+
/**
* Save an error-generating command into display list.
*
value[1] = n[4].i;
value[2] = n[5].i;
value[3] = n[6].i;
- /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_UIV:
value[1] = n[4].ui;
value[2] = n[5].ui;
value[3] = n[6].ui;
- /*CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FV:
value[1] = n[4].f;
value[2] = n[5].f;
value[3] = n[6].f;
- /*CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));*/
+ CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value));
}
break;
case OPCODE_CLEAR_BUFFER_FI:
- /*CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));*/
+ CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i));
break;
case OPCODE_CLEAR_COLOR:
CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
case OPCODE_PROVOKING_VERTEX:
CALL_ProvokingVertexEXT(ctx->Exec, (n[1].e));
break;
- case OPCODE_BEGIN_TRANSFORM_FEEDBACK:
- CALL_BeginTransformFeedbackEXT(ctx->Exec, (n[1].e));
- break;
- case OPCODE_END_TRANSFORM_FEEDBACK:
- CALL_EndTransformFeedbackEXT(ctx->Exec, ());
- break;
case OPCODE_STENCIL_FUNC:
CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui));
break;
case OPCODE_END_QUERY_ARB:
CALL_EndQueryARB(ctx->Exec, (n[1].e));
break;
+ case OPCODE_QUERY_COUNTER:
+ CALL_QueryCounter(ctx->Exec, (n[1].ui, n[2].e));
+ break;
+ case OPCODE_BEGIN_QUERY_INDEXED:
+ CALL_BeginQueryIndexed(ctx->Exec, (n[1].e, n[2].ui, n[3].ui));
+ break;
+ case OPCODE_END_QUERY_INDEXED:
+ CALL_EndQueryIndexed(ctx->Exec, (n[1].e, n[2].ui));
+ break;
#endif
case OPCODE_DRAW_BUFFERS_ARB:
{
CALL_TextureBarrierNV(ctx->Exec, ());
break;
+ /* GL_EXT/ARB_transform_feedback */
+ case OPCODE_BEGIN_TRANSFORM_FEEDBACK:
+ CALL_BeginTransformFeedbackEXT(ctx->Exec, (n[1].e));
+ break;
+ case OPCODE_END_TRANSFORM_FEEDBACK:
+ CALL_EndTransformFeedbackEXT(ctx->Exec, ());
+ break;
+ case OPCODE_BIND_TRANSFORM_FEEDBACK:
+ CALL_BindTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+ case OPCODE_PAUSE_TRANSFORM_FEEDBACK:
+ CALL_PauseTransformFeedback(ctx->Exec, ());
+ break;
+ case OPCODE_RESUME_TRANSFORM_FEEDBACK:
+ CALL_ResumeTransformFeedback(ctx->Exec, ());
+ break;
+ case OPCODE_DRAW_TRANSFORM_FEEDBACK:
+ CALL_DrawTransformFeedback(ctx->Exec, (n[1].e, n[2].ui));
+ break;
+ case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM:
+ CALL_DrawTransformFeedbackStream(ctx->Exec,
+ (n[1].e, n[2].ui, n[3].ui));
+ break;
+ case OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED:
+ CALL_DrawTransformFeedbackInstanced(ctx->Exec,
+ (n[1].e, n[2].ui, n[3].si));
+ break;
+ case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED:
+ CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec,
+ (n[1].e, n[2].ui, n[3].ui, n[4].si));
+ break;
+
+
case OPCODE_BIND_SAMPLER:
CALL_BindSampler(ctx->Exec, (n[1].ui, n[2].ui));
break;
case OPCODE_PROGRAM_PARAMETERI:
CALL_ProgramParameteriARB(ctx->Exec, (n[1].ui, n[2].e, n[3].i));
break;
+ case OPCODE_FRAMEBUFFER_TEXTURE:
+ CALL_FramebufferTextureARB(ctx->Exec, (n[1].e, n[2].e,
+ n[3].ui, n[4].i));
+ break;
+ case OPCODE_FRAMEBUFFER_TEXTURE_FACE:
+ CALL_FramebufferTextureFaceARB(ctx->Exec, (n[1].e, n[2].e,
+ n[3].ui, n[4].i, n[5].e));
+ break;
/* GL_ARB_sync */
case OPCODE_WAIT_SYNC:
}
break;
+ /* GL_NV_conditional_render */
+ case OPCODE_BEGIN_CONDITIONAL_RENDER:
+ CALL_BeginConditionalRenderNV(ctx->Exec, (n[1].i, n[2].e));
+ break;
+ case OPCODE_END_CONDITIONAL_RENDER:
+ CALL_EndConditionalRenderNV(ctx->Exec, ());
+ break;
+
+ case OPCODE_UNIFORM_BLOCK_BINDING:
+ CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
+ break;
+
case OPCODE_CONTINUE:
n = (Node *) n[1].next;
break;
modestride));
}
-
-
/**
* Setup the given dispatch table to point to Mesa's display list
* building functions.
SET_GenVertexArraysAPPLE(table, _mesa_GenVertexArraysAPPLE);
SET_IsVertexArrayAPPLE(table, _mesa_IsVertexArrayAPPLE);
+ /* 310. GL_EXT_framebuffer_object */
+ SET_GenFramebuffersEXT(table, _mesa_GenFramebuffersEXT);
+ SET_BindFramebufferEXT(table, _mesa_BindFramebufferEXT);
+ SET_DeleteFramebuffersEXT(table, _mesa_DeleteFramebuffersEXT);
+ SET_CheckFramebufferStatusEXT(table, _mesa_CheckFramebufferStatusEXT);
+ SET_GenRenderbuffersEXT(table, _mesa_GenRenderbuffersEXT);
+ SET_BindRenderbufferEXT(table, _mesa_BindRenderbufferEXT);
+ SET_DeleteRenderbuffersEXT(table, _mesa_DeleteRenderbuffersEXT);
+ SET_RenderbufferStorageEXT(table, _mesa_RenderbufferStorageEXT);
+ SET_FramebufferTexture1DEXT(table, _mesa_FramebufferTexture1DEXT);
+ SET_FramebufferTexture2DEXT(table, _mesa_FramebufferTexture2DEXT);
+ SET_FramebufferTexture3DEXT(table, _mesa_FramebufferTexture3DEXT);
+ SET_FramebufferRenderbufferEXT(table, _mesa_FramebufferRenderbufferEXT);
+ SET_GenerateMipmapEXT(table, _mesa_GenerateMipmapEXT);
+
+ /* 317. GL_EXT_framebuffer_multisample */
+ SET_RenderbufferStorageMultisample(table, _mesa_RenderbufferStorageMultisample);
+
+ /* GL_ARB_vertex_array_object */
+ SET_BindVertexArray(table, _mesa_BindVertexArray);
+ SET_GenVertexArrays(table, _mesa_GenVertexArrays);
+
/* ???. GL_EXT_depth_bounds_test */
SET_DepthBoundsEXT(table, save_DepthBoundsEXT);
#endif
/* ARB 28. GL_ARB_vertex_buffer_object */
-#if FEATURE_ARB_vertex_buffer_object
/* None of the extension's functions get compiled */
SET_BindBufferARB(table, _mesa_BindBufferARB);
SET_BufferDataARB(table, _mesa_BufferDataARB);
SET_IsBufferARB(table, _mesa_IsBufferARB);
SET_MapBufferARB(table, _mesa_MapBufferARB);
SET_UnmapBufferARB(table, _mesa_UnmapBufferARB);
-#endif
#if FEATURE_queryobj
+ _mesa_init_queryobj_dispatch(table); /* glGetQuery, etc */
SET_BeginQueryARB(table, save_BeginQueryARB);
SET_EndQueryARB(table, save_EndQueryARB);
- SET_GenQueriesARB(table, _mesa_GenQueriesARB);
- SET_DeleteQueriesARB(table, _mesa_DeleteQueriesARB);
- SET_IsQueryARB(table, _mesa_IsQueryARB);
- SET_GetQueryivARB(table, _mesa_GetQueryivARB);
- SET_GetQueryObjectivARB(table, _mesa_GetQueryObjectivARB);
- SET_GetQueryObjectuivARB(table, _mesa_GetQueryObjectuivARB);
+ SET_QueryCounter(table, save_QueryCounter);
#endif
+
SET_DrawBuffersARB(table, save_DrawBuffersARB);
#if FEATURE_EXT_framebuffer_blit
SET_FlushMappedBufferRange(table, _mesa_FlushMappedBufferRange); /* no dl */
#endif
+ /* ARB 51. GL_ARB_texture_buffer_object */
+ SET_TexBufferARB(table, _mesa_TexBuffer); /* no dlist save */
+
/* ARB 59. GL_ARB_copy_buffer */
SET_CopyBufferSubData(table, _mesa_CopyBufferSubData); /* no dlist save */
- /* 352. GL_EXT_transform_feedback */
-#if FEATURE_EXT_transform_feedback
- SET_BeginTransformFeedbackEXT(table, save_BeginTransformFeedback);
- SET_EndTransformFeedbackEXT(table, save_EndTransformFeedback);
-#endif
-
/* 364. GL_EXT_provoking_vertex */
SET_ProvokingVertexEXT(table, save_ProvokingVertexEXT);
#if FEATURE_APPLE_object_purgeable
SET_ObjectPurgeableAPPLE(table, _mesa_ObjectPurgeableAPPLE);
SET_ObjectUnpurgeableAPPLE(table, _mesa_ObjectUnpurgeableAPPLE);
+ SET_GetObjectParameterivAPPLE(table, _mesa_GetObjectParameterivAPPLE);
#endif
/* GL_EXT_texture_integer */
(void) save_Uniform4uiv;
#endif
+#if FEATURE_EXT_transform_feedback
+ /* These are not compiled into display lists: */
+ SET_BindBufferBaseEXT(table, _mesa_BindBufferBase);
+ SET_BindBufferOffsetEXT(table, _mesa_BindBufferOffsetEXT);
+ SET_BindBufferRangeEXT(table, _mesa_BindBufferRange);
+ SET_TransformFeedbackVaryingsEXT(table, _mesa_TransformFeedbackVaryings);
+ /* These are: */
+ SET_BeginTransformFeedbackEXT(table, save_BeginTransformFeedback);
+ SET_EndTransformFeedbackEXT(table, save_EndTransformFeedback);
+ SET_BindTransformFeedback(table, save_BindTransformFeedback);
+ SET_PauseTransformFeedback(table, save_PauseTransformFeedback);
+ SET_ResumeTransformFeedback(table, save_ResumeTransformFeedback);
+ SET_DrawTransformFeedback(table, save_DrawTransformFeedback);
+ SET_DrawTransformFeedbackStream(table, save_DrawTransformFeedbackStream);
+ SET_DrawTransformFeedbackInstanced(table,
+ save_DrawTransformFeedbackInstanced);
+ SET_DrawTransformFeedbackStreamInstanced(table,
+ save_DrawTransformFeedbackStreamInstanced);
+#if FEATURE_queryobj
+ SET_BeginQueryIndexed(table, save_BeginQueryIndexed);
+ SET_EndQueryIndexed(table, save_EndQueryIndexed);
+#endif
+#endif
+
/* GL_ARB_instanced_arrays */
SET_VertexAttribDivisorARB(table, save_VertexAttribDivisor);
/* GL_ARB_geometry_shader4 */
SET_ProgramParameteriARB(table, save_ProgramParameteri);
+ SET_FramebufferTextureARB(table, save_FramebufferTexture);
+ SET_FramebufferTextureFaceARB(table, save_FramebufferTextureFace);
+
+ /* GL_NV_conditional_render */
+ SET_BeginConditionalRenderNV(table, save_BeginConditionalRender);
+ SET_EndConditionalRenderNV(table, save_EndConditionalRender);
/* GL_ARB_sync */
_mesa_init_sync_dispatch(table);
SET_WaitSync(table, save_WaitSync);
+ /* GL_ARB_texture_storage (no dlist support) */
+ SET_TexStorage1D(table, _mesa_TexStorage1D);
+ SET_TexStorage2D(table, _mesa_TexStorage2D);
+ SET_TexStorage3D(table, _mesa_TexStorage3D);
+ SET_TextureStorage1DEXT(table, _mesa_TextureStorage1DEXT);
+ SET_TextureStorage2DEXT(table, _mesa_TextureStorage2DEXT);
+ SET_TextureStorage3DEXT(table, _mesa_TextureStorage3DEXT);
+
+ /* GL_ARB_debug_output (no dlist support) */
+ _mesa_init_errors_dispatch(table);
+
+ /* GL_ARB_uniform_buffer_object */
+ SET_UniformBlockBinding(table, save_UniformBlockBinding);
+
+ /* GL_NV_primitive_restart */
+ SET_PrimitiveRestartIndexNV(table, _mesa_PrimitiveRestartIndex);
+
return table;
}
vfmt->Rectf = save_Rectf;
+ /* GL_ARB_draw_instanced */
+ vfmt->DrawArraysInstanced = save_DrawArraysInstancedARB;
+ vfmt->DrawElementsInstanced = save_DrawElementsInstancedARB;
+
+ /* GL_ARB_draw_elements_base_vertex */
+ vfmt->DrawElementsInstancedBaseVertex = save_DrawElementsInstancedBaseVertexARB;
+
+ /* GL_ARB_base_instance */
+ vfmt->DrawArraysInstancedBaseInstance = save_DrawArraysInstancedBaseInstance;
+ vfmt->DrawElementsInstancedBaseInstance = save_DrawElementsInstancedBaseInstance;
+ vfmt->DrawElementsInstancedBaseVertexBaseInstance = save_DrawElementsInstancedBaseVertexBaseInstance;
+
/* The driver is required to implement these as
* 1) They can probably do a better job.
* 2) A lot of new mechanisms would have to be added to this module