diff options
Diffstat (limited to 'src/mesa/main/dlist.c')
-rw-r--r-- | src/mesa/main/dlist.c | 714 |
1 files changed, 447 insertions, 267 deletions
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index d3aee196c7..f793b60284 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -33,6 +33,7 @@ #include "api_arrayelt.h" #include "api_loopback.h" #include "config.h" +#include "mfeatures.h" #include "attrib.h" #include "blend.h" #include "buffers.h" @@ -72,6 +73,7 @@ #include "texstate.h" #include "mtypes.h" #include "varray.h" +#include "vtxfmt.h" #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program #include "shader/arbprogram.h" #include "shader/program.h" @@ -85,7 +87,6 @@ #endif #include "math/m_matrix.h" -#include "math/m_xform.h" #include "glapi/dispatch.h" @@ -320,6 +321,8 @@ typedef enum /* GL_ARB_draw_buffers */ OPCODE_DRAW_BUFFERS_ARB, /* GL_ATI_fragment_shader */ + OPCODE_TEX_BUMP_PARAMETER_ATI, + /* GL_ATI_fragment_shader */ OPCODE_BIND_FRAGMENT_SHADER_ATI, OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, /* OpenGL 2.0 */ @@ -350,6 +353,9 @@ typedef enum OPCODE_EVAL_P1, OPCODE_EVAL_P2, + /* GL_EXT_provoking_vertex */ + OPCODE_PROVOKING_VERTEX, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -370,7 +376,7 @@ typedef enum * contiguous nodes in memory. * Each node is the union of a variety of data types. */ -union node +union gl_dlist_node { OpCode opcode; GLboolean b; @@ -387,6 +393,9 @@ union node }; +typedef union gl_dlist_node Node; + + /** * How many nodes to allocate at a time. * @@ -402,6 +411,10 @@ union node */ static GLuint InstSize[OPCODE_END_OF_LIST + 1]; + +#if FEATURE_dlist + + void mesa_print_display_list(GLuint list); @@ -414,13 +427,13 @@ void mesa_print_display_list(GLuint list); * Make an empty display list. This is used by glGenLists() to * reserve display list IDs. */ -static struct mesa_display_list * -make_list(GLuint list, GLuint count) +static struct gl_display_list * +make_list(GLuint name, GLuint count) { - struct mesa_display_list *dlist = CALLOC_STRUCT(mesa_display_list); - dlist->id = list; - dlist->node = (Node *) _mesa_malloc(sizeof(Node) * count); - dlist->node[0].opcode = OPCODE_END_OF_LIST; + struct gl_display_list *dlist = CALLOC_STRUCT(gl_display_list); + dlist->Name = name; + dlist->Head = (Node *) _mesa_malloc(sizeof(Node) * count); + dlist->Head[0].opcode = OPCODE_END_OF_LIST; return dlist; } @@ -428,10 +441,10 @@ make_list(GLuint list, GLuint count) /** * Lookup function to just encapsulate casting. */ -static INLINE struct mesa_display_list * +static INLINE struct gl_display_list * lookup_list(GLcontext *ctx, GLuint list) { - return (struct mesa_display_list *) + return (struct gl_display_list *) _mesa_HashLookup(ctx->Shared->DisplayList, list); } @@ -442,12 +455,12 @@ lookup_list(GLcontext *ctx, GLuint list) * \param dlist - display list pointer */ void -_mesa_delete_list(GLcontext *ctx, struct mesa_display_list *dlist) +_mesa_delete_list(GLcontext *ctx, struct gl_display_list *dlist) { Node *n, *block; GLboolean done; - n = block = dlist->node; + n = block = dlist->Head; done = block ? GL_FALSE : GL_TRUE; while (!done) { @@ -596,7 +609,7 @@ _mesa_delete_list(GLcontext *ctx, struct mesa_display_list *dlist) static void destroy_list(GLcontext *ctx, GLuint list) { - struct mesa_display_list *dlist; + struct gl_display_list *dlist; if (list == 0) return; @@ -675,24 +688,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; @@ -702,7 +739,7 @@ unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth, /** * Allocate space for a display list instruction. * \param opcode the instruction opcode (OPCODE_* value) - * \param size instruction size in bytes, not counting opcode. + * \param bytes instruction size in bytes, not counting opcode. * \return pointer to the usable data area (not including the internal * opcode). */ @@ -850,7 +887,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); @@ -861,10 +897,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, @@ -952,6 +985,20 @@ save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) } } +static void invalidate_saved_current_state( GLcontext *ctx ) +{ + GLint i; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + ctx->ListState.ActiveAttribSize[i] = 0; + + for (i = 0; i < MAT_ATTRIB_MAX; i++) + ctx->ListState.ActiveMaterialSize[i] = 0; + + memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current); + + ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; +} void GLAPIENTRY _mesa_save_CallList(GLuint list) @@ -965,18 +1012,19 @@ _mesa_save_CallList(GLuint list) n[1].ui = list; } - /* After this, we don't know what begin/end state we're in: + /* After this, we don't know what state we're in. Invalidate all + * cached information previously gathered: */ - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; + invalidate_saved_current_state( ctx ); if (ctx->ExecuteFlag) { - CALL_CallList(ctx->Exec, (list)); + _mesa_CallList(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; @@ -1001,7 +1049,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) { @@ -1010,12 +1058,13 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists) } } - /* After this, we don't know what begin/end state we're in: + /* After this, we don't know what state we're in. Invalidate all + * cached information previously gathered: */ - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; + invalidate_saved_current_state( ctx ); if (ctx->ExecuteFlag) { - CALL_CallLists(ctx->Exec, (n, type, lists)); + CALL_CallLists(ctx->Exec, (num, type, lists)); } } @@ -1193,8 +1242,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); @@ -1204,10 +1251,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, @@ -1283,8 +1328,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); @@ -1294,10 +1337,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, @@ -1355,10 +1396,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; @@ -1366,10 +1407,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, @@ -1384,10 +1423,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; @@ -1396,10 +1435,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, @@ -1754,20 +1791,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)); @@ -1794,7 +1829,7 @@ save_Enable(GLenum cap) static void GLAPIENTRY -_mesa_save_EvalMesh1(GLenum mode, GLint i1, GLint i2) +save_EvalMesh1(GLenum mode, GLint i1, GLint i2) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1812,7 +1847,7 @@ _mesa_save_EvalMesh1(GLenum mode, GLint i1, GLint i2) static void GLAPIENTRY -_mesa_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1856,7 +1891,10 @@ save_Fogfv(GLenum pname, const GLfloat *params) static void GLAPIENTRY save_Fogf(GLenum pname, GLfloat param) { - save_Fogfv(pname, ¶m); + GLfloat parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0.0F; + save_Fogfv(pname, parray); } @@ -1880,7 +1918,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); } @@ -1889,7 +1927,10 @@ save_Fogiv(GLenum pname, const GLint *params) static void GLAPIENTRY save_Fogi(GLenum pname, GLint param) { - save_Fogiv(pname, ¶m); + GLint parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0; + save_Fogiv(pname, parray); } @@ -2053,9 +2094,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, ¶ms); + GLfloat parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0.0F; + save_Lightfv(light, pname, parray); } @@ -2101,7 +2145,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, ¶m); + GLint parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0; + save_Lightiv(light, pname, parray); } @@ -2128,7 +2175,10 @@ save_LightModelfv(GLenum pname, const GLfloat *params) static void GLAPIENTRY save_LightModelf(GLenum pname, GLfloat param) { - save_LightModelfv(pname, ¶m); + GLfloat parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0.0F; + save_LightModelfv(pname, parray); } @@ -2150,7 +2200,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); } @@ -2159,7 +2209,10 @@ save_LightModeliv(GLenum pname, const GLint *params) static void GLAPIENTRY save_LightModeli(GLenum pname, GLint param) { - save_LightModeliv(pname, ¶m); + GLint parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0; + save_LightModeliv(pname, parray); } @@ -2521,12 +2574,12 @@ save_MultMatrixd(const GLdouble * m) static void GLAPIENTRY -save_NewList(GLuint list, GLenum mode) +save_NewList(GLuint name, GLenum mode) { GET_CURRENT_CONTEXT(ctx); /* It's an error to call this function while building a display list */ _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList"); - (void) list; + (void) name; (void) mode; } @@ -2674,21 +2727,28 @@ save_PointParameterfvEXT(GLenum pname, const GLfloat *params) static void GLAPIENTRY save_PointParameterfEXT(GLenum pname, GLfloat param) { - save_PointParameterfvEXT(pname, ¶m); + 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); } @@ -2729,16 +2789,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)); @@ -3172,14 +3230,26 @@ save_ShadeModel(GLenum mode) { GET_CURRENT_CONTEXT(ctx); Node *n; - ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); + + if (ctx->ExecuteFlag) { + CALL_ShadeModel(ctx->Exec, (mode)); + } + + if (ctx->ListState.Current.ShadeModel == mode) + return; + + SAVE_FLUSH_VERTICES(ctx); + + /* Only save the value if we know the statechange will take effect: + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) + ctx->ListState.Current.ShadeModel = mode; + n = ALLOC_INSTRUCTION(ctx, OPCODE_SHADE_MODEL, 1); if (n) { n[1].e = mode; } - if (ctx->ExecuteFlag) { - CALL_ShadeModel(ctx->Exec, (mode)); - } } @@ -3350,7 +3420,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, ¶m); + GLfloat parray[4]; + parray[0] = (GLfloat) param; + parray[1] = parray[2] = parray[3] = 0.0F; + save_TexEnvfv(target, pname, parray); } @@ -3418,8 +3491,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); } @@ -3438,14 +3513,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, ¶m); + 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, ¶m); + GLint parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0; + save_TexGeniv(coord, pname, parray); } @@ -3473,7 +3554,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, ¶m); + GLfloat parray[4]; + parray[0] = param; + parray[1] = parray[2] = parray[3] = 0.0F; + save_TexParameterfv(target, pname, parray); } @@ -3510,8 +3594,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); @@ -3523,10 +3605,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, @@ -3549,8 +3629,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); @@ -3563,10 +3641,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, @@ -3592,8 +3668,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) { @@ -3606,10 +3680,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, @@ -3627,9 +3699,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; @@ -3638,10 +3710,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, @@ -3658,9 +3728,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; @@ -3671,10 +3741,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, @@ -3691,9 +3759,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; @@ -3706,10 +3774,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, @@ -4422,18 +4488,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; @@ -4450,15 +4515,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; } @@ -4619,16 +4686,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; @@ -4717,18 +4785,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; @@ -4742,7 +4809,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, #endif /* FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program */ -#if FEATURE_ARB_occlusion_query +#if FEATURE_queryobj static void GLAPIENTRY save_BeginQueryARB(GLenum target, GLuint id) @@ -4776,7 +4843,7 @@ save_EndQueryARB(GLenum target) } } -#endif /* FEATURE_ARB_occlusion_query */ +#endif /* FEATURE_queryobj */ static void GLAPIENTRY @@ -4800,6 +4867,36 @@ save_DrawBuffersARB(GLsizei count, const GLenum * buffers) } } +static void GLAPIENTRY +save_TexBumpParameterfvATI(GLenum pname, const GLfloat *param) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_BUMP_PARAMETER_ATI, 5); + if (n) { + n[1].ui = pname; + n[2].f = param[0]; + n[3].f = param[1]; + n[4].f = param[2]; + n[5].f = param[3]; + } + if (ctx->ExecuteFlag) { + CALL_TexBumpParameterfvATI(ctx->Exec, (pname, param)); + } +} + +static void GLAPIENTRY +save_TexBumpParameterivATI(GLenum pname, const GLint *param) +{ + GLfloat p[4]; + p[0] = INT_TO_FLOAT(param[0]); + p[1] = INT_TO_FLOAT(param[1]); + p[2] = INT_TO_FLOAT(param[2]); + p[3] = INT_TO_FLOAT(param[3]); + save_TexBumpParameterfvATI(pname, p); +} + #if FEATURE_ATI_fragment_shader static void GLAPIENTRY save_BindFragmentShaderATI(GLuint id) @@ -4848,7 +4945,7 @@ save_Attr1fNV(GLenum attr, GLfloat x) n[2].f = x; } - ASSERT(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 1; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); @@ -4870,7 +4967,7 @@ save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y) n[3].f = y; } - ASSERT(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 2; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); @@ -4893,7 +4990,7 @@ save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } - ASSERT(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 3; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); @@ -4917,7 +5014,7 @@ save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[5].f = w; } - ASSERT(attr < MAX_VERTEX_PROGRAM_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 4; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); @@ -4939,7 +5036,7 @@ save_Attr1fARB(GLenum attr, GLfloat x) n[2].f = x; } - ASSERT(attr < MAX_VERTEX_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 1; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); @@ -4961,7 +5058,7 @@ save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y) n[3].f = y; } - ASSERT(attr < MAX_VERTEX_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 2; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); @@ -4984,7 +5081,7 @@ save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } - ASSERT(attr < MAX_VERTEX_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 3; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); @@ -5008,7 +5105,7 @@ save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[5].f = w; } - ASSERT(attr < MAX_VERTEX_ATTRIBS); + ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 4; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); @@ -5111,14 +5208,21 @@ save_EdgeFlag(GLboolean x) save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0); } +static INLINE GLboolean compare4fv( const GLfloat *a, + const GLfloat *b, + GLuint count ) +{ + return memcmp( a, b, count * sizeof(GLfloat) ) == 0; +} + + static void GLAPIENTRY save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) { GET_CURRENT_CONTEXT(ctx); Node *n; int args, i; - - SAVE_FLUSH_VERTICES(ctx); + GLuint bitmask; switch (face) { case GL_BACK: @@ -5148,26 +5252,43 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) _mesa_compile_error(ctx, GL_INVALID_ENUM, "material(pname)"); return; } - - n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6); - if (n) { - n[1].e = face; - n[2].e = pname; - for (i = 0; i < args; i++) - n[3 + i].f = param[i]; + + if (ctx->ExecuteFlag) { + CALL_Materialfv(ctx->Exec, (face, pname, param)); } - { - GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); - for (i = 0; i < MAT_ATTRIB_MAX; i++) - if (bitmask & (1 << i)) { + bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); + + /* Try to eliminate redundant statechanges. Because it is legal to + * call glMaterial even inside begin/end calls, don't need to worry + * about ctx->Driver.CurrentSavePrimitive here. + */ + 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)) { + bitmask &= ~(1 << i); + } + else { ctx->ListState.ActiveMaterialSize[i] = args; COPY_SZ_4V(ctx->ListState.CurrentMaterial[i], args, param); } + } } - if (ctx->ExecuteFlag) { - CALL_Materialfv(ctx->Exec, (face, pname, param)); + /* If this call has effect, return early: + */ + if (bitmask == 0) + return; + + SAVE_FLUSH_VERTICES(ctx); + + n = ALLOC_INSTRUCTION(ctx, OPCODE_MATERIAL, 6); + if (n) { + n[1].e = face; + n[2].e = pname; + for (i = 0; i < args; i++) + n[3 + i].f = param[i]; } } @@ -5471,7 +5592,7 @@ index_error(void) static void GLAPIENTRY save_VertexAttrib1fNV(GLuint index, GLfloat x) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr1fNV(index, x); else index_error(); @@ -5480,7 +5601,7 @@ save_VertexAttrib1fNV(GLuint index, GLfloat x) static void GLAPIENTRY save_VertexAttrib1fvNV(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr1fNV(index, v[0]); else index_error(); @@ -5489,7 +5610,7 @@ save_VertexAttrib1fvNV(GLuint index, const GLfloat * v) static void GLAPIENTRY save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr2fNV(index, x, y); else index_error(); @@ -5498,7 +5619,7 @@ save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) static void GLAPIENTRY save_VertexAttrib2fvNV(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr2fNV(index, v[0], v[1]); else index_error(); @@ -5507,7 +5628,7 @@ save_VertexAttrib2fvNV(GLuint index, const GLfloat * v) static void GLAPIENTRY save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr3fNV(index, x, y, z); else index_error(); @@ -5516,7 +5637,7 @@ save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) static void GLAPIENTRY save_VertexAttrib3fvNV(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr3fNV(index, v[0], v[1], v[2]); else index_error(); @@ -5526,7 +5647,7 @@ static void GLAPIENTRY save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr4fNV(index, x, y, z, w); else index_error(); @@ -5535,7 +5656,7 @@ save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, static void GLAPIENTRY save_VertexAttrib4fvNV(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_PROGRAM_ATTRIBS) + if (index < MAX_NV_VERTEX_PROGRAM_INPUTS) save_Attr4fNV(index, v[0], v[1], v[2], v[3]); else index_error(); @@ -5547,7 +5668,7 @@ save_VertexAttrib4fvNV(GLuint index, const GLfloat * v) static void GLAPIENTRY save_VertexAttrib1fARB(GLuint index, GLfloat x) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr1fARB(index, x); else index_error(); @@ -5556,7 +5677,7 @@ save_VertexAttrib1fARB(GLuint index, GLfloat x) static void GLAPIENTRY save_VertexAttrib1fvARB(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr1fARB(index, v[0]); else index_error(); @@ -5565,7 +5686,7 @@ save_VertexAttrib1fvARB(GLuint index, const GLfloat * v) static void GLAPIENTRY save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr2fARB(index, x, y); else index_error(); @@ -5574,7 +5695,7 @@ save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) static void GLAPIENTRY save_VertexAttrib2fvARB(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr2fARB(index, v[0], v[1]); else index_error(); @@ -5583,7 +5704,7 @@ save_VertexAttrib2fvARB(GLuint index, const GLfloat * v) static void GLAPIENTRY save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr3fARB(index, x, y, z); else index_error(); @@ -5592,7 +5713,7 @@ save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) static void GLAPIENTRY save_VertexAttrib3fvARB(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr3fARB(index, v[0], v[1], v[2]); else index_error(); @@ -5602,7 +5723,7 @@ static void GLAPIENTRY save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr4fARB(index, x, y, z, w); else index_error(); @@ -5611,7 +5732,7 @@ save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, static void GLAPIENTRY save_VertexAttrib4fvARB(GLuint index, const GLfloat * v) { - if (index < MAX_VERTEX_ATTRIBS) + if (index < MAX_VERTEX_GENERIC_ATTRIBS) save_Attr4fARB(index, v[0], v[1], v[2], v[3]); else index_error(); @@ -5670,6 +5791,25 @@ save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, #endif +/** GL_EXT_provoking_vertex */ +static void GLAPIENTRY +save_ProvokingVertexEXT(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_PROVOKING_VERTEX, 1); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + /*CALL_ProvokingVertexEXT(ctx->Exec, (mode));*/ + _mesa_ProvokingVertexEXT(mode); + } +} + + + /** * Save an error-generating command into display list. * @@ -5731,7 +5871,7 @@ islist(GLcontext *ctx, GLuint list) static void execute_list(GLcontext *ctx, GLuint list) { - struct mesa_display_list *dlist; + struct gl_display_list *dlist; Node *n; GLboolean done; @@ -5752,7 +5892,7 @@ execute_list(GLcontext *ctx, GLuint list) if (ctx->Driver.BeginCallList) ctx->Driver.BeginCallList(ctx, dlist); - n = dlist->node; + n = dlist->Head; done = GL_FALSE; while (!done) { @@ -6234,6 +6374,9 @@ execute_list(GLcontext *ctx, GLuint list) case OPCODE_SHADE_MODEL: CALL_ShadeModel(ctx->Exec, (n[1].e)); break; + case OPCODE_PROVOKING_VERTEX: + CALL_ProvokingVertexEXT(ctx->Exec, (n[1].e)); + break; case OPCODE_STENCIL_FUNC: CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui)); break; @@ -6478,7 +6621,7 @@ execute_list(GLcontext *ctx, GLuint list) n[6].f)); break; #endif -#if FEATURE_ARB_occlusion_query +#if FEATURE_queryobj case OPCODE_BEGIN_QUERY_ARB: CALL_BeginQueryARB(ctx->Exec, (n[1].e, n[2].ui)); break; @@ -6502,6 +6645,16 @@ execute_list(GLcontext *ctx, GLuint list) n[9].i, n[10].e)); break; #endif + case OPCODE_TEX_BUMP_PARAMETER_ATI: + { + GLfloat values[4]; + GLuint i, pname = n[1].ui; + + for (i = 0; i < 4; i++) + values[i] = n[1 + i].f; + CALL_TexBumpParameterfvATI(ctx->Exec, (pname, values)); + } + break; #if FEATURE_ATI_fragment_shader case OPCODE_BIND_FRAGMENT_SHADER_ATI: CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); @@ -6723,19 +6876,18 @@ _mesa_GenLists(GLsizei range) * Begin a new display list. */ void GLAPIENTRY -_mesa_NewList(GLuint list, GLenum mode) +_mesa_NewList(GLuint name, GLenum mode) { GET_CURRENT_CONTEXT(ctx); - GLint i; FLUSH_CURRENT(ctx, 0); /* must be called before assert */ ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glNewList %u %s\n", list, + _mesa_debug(ctx, "glNewList %u %s\n", name, _mesa_lookup_enum_by_nr(mode)); - if (list == 0) { + if (name == 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glNewList"); return; } @@ -6745,7 +6897,7 @@ _mesa_NewList(GLuint list, GLenum mode) return; } - if (ctx->ListState.CurrentListPtr) { + if (ctx->ListState.CurrentList) { /* already compiling a display list */ _mesa_error(ctx, GL_INVALID_OPERATION, "glNewList"); return; @@ -6754,23 +6906,16 @@ _mesa_NewList(GLuint list, GLenum mode) ctx->CompileFlag = GL_TRUE; ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE); - /* Allocate new display list */ - ctx->ListState.CurrentListNum = list; - ctx->ListState.CurrentList = make_list(list, BLOCK_SIZE); - ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->node; - ctx->ListState.CurrentListPtr = ctx->ListState.CurrentBlock; - ctx->ListState.CurrentPos = 0; - /* Reset acumulated list state: */ - for (i = 0; i < VERT_ATTRIB_MAX; i++) - ctx->ListState.ActiveAttribSize[i] = 0; + invalidate_saved_current_state( ctx ); - for (i = 0; i < MAT_ATTRIB_MAX; i++) - ctx->ListState.ActiveMaterialSize[i] = 0; + /* Allocate new display list */ + ctx->ListState.CurrentList = make_list(name, BLOCK_SIZE); + ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->Head; + ctx->ListState.CurrentPos = 0; - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; - ctx->Driver.NewList(ctx, list, mode); + ctx->Driver.NewList(ctx, name, mode); ctx->CurrentDispatch = ctx->Save; _glapi_set_dispatch(ctx->CurrentDispatch); @@ -6791,7 +6936,7 @@ _mesa_EndList(void) _mesa_debug(ctx, "glEndList\n"); /* Check that a list is under construction */ - if (!ctx->ListState.CurrentListPtr) { + if (!ctx->ListState.CurrentList) { _mesa_error(ctx, GL_INVALID_OPERATION, "glEndList"); return; } @@ -6804,18 +6949,18 @@ _mesa_EndList(void) (void) ALLOC_INSTRUCTION(ctx, OPCODE_END_OF_LIST, 0); /* Destroy old list, if any */ - destroy_list(ctx, ctx->ListState.CurrentListNum); - /* Install the list */ - _mesa_HashInsert(ctx->Shared->DisplayList, ctx->ListState.CurrentListNum, + destroy_list(ctx, ctx->ListState.CurrentList->Name); + + /* Install the new list */ + _mesa_HashInsert(ctx->Shared->DisplayList, + ctx->ListState.CurrentList->Name, ctx->ListState.CurrentList); if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) - mesa_print_display_list(ctx->ListState.CurrentListNum); + mesa_print_display_list(ctx->ListState.CurrentList->Name); ctx->ListState.CurrentList = NULL; - ctx->ListState.CurrentListNum = 0; - ctx->ListState.CurrentListPtr = NULL; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; @@ -7611,18 +7756,6 @@ exec_MultiDrawArraysEXT(GLenum mode, GLint * first, CALL_MultiDrawArraysEXT(ctx->Exec, (mode, first, count, primcount)); } -/* GL_EXT_multi_draw_arrays */ -static void GLAPIENTRY -exec_MultiDrawElementsEXT(GLenum mode, const GLsizei * count, - GLenum type, const GLvoid ** indices, - GLsizei primcount) -{ - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - CALL_MultiDrawElementsEXT(ctx->Exec, - (mode, count, type, indices, primcount)); -} - /* GL_IBM_multimode_draw_arrays */ static void GLAPIENTRY exec_MultiModeDrawArraysIBM(const GLenum * mode, const GLint * first, @@ -7661,7 +7794,7 @@ exec_MultiModeDrawElementsIBM(const GLenum * mode, * struct. */ void -_mesa_init_dlist_table(struct _glapi_table *table) +_mesa_init_save_table(struct _glapi_table *table) { _mesa_loopback_init_api_table(table); @@ -7692,8 +7825,8 @@ _mesa_init_dlist_table(struct _glapi_table *table) SET_DrawPixels(table, save_DrawPixels); SET_Enable(table, save_Enable); SET_EndList(table, _mesa_EndList); - SET_EvalMesh1(table, _mesa_save_EvalMesh1); - SET_EvalMesh2(table, _mesa_save_EvalMesh2); + SET_EvalMesh1(table, save_EvalMesh1); + SET_EvalMesh2(table, save_EvalMesh2); SET_Finish(table, exec_Finish); SET_Flush(table, exec_Flush); SET_Fogf(table, save_Fogf); @@ -7968,7 +8101,6 @@ _mesa_init_dlist_table(struct _glapi_table *table) /* 148. GL_EXT_multi_draw_arrays */ SET_MultiDrawArraysEXT(table, exec_MultiDrawArraysEXT); - SET_MultiDrawElementsEXT(table, exec_MultiDrawElementsEXT); /* 149. GL_EXT_fog_coord */ SET_FogCoordPointerEXT(table, exec_FogCoordPointerEXT); @@ -8042,6 +8174,10 @@ _mesa_init_dlist_table(struct _glapi_table *table) SET_VertexAttribPointerNV(table, _mesa_VertexAttribPointerNV); #endif + /* 244. GL_ATI_envmap_bumpmap */ + SET_TexBumpParameterivATI(table, save_TexBumpParameterivATI); + SET_TexBumpParameterfvATI(table, save_TexBumpParameterfvATI); + /* 245. GL_ATI_fragment_shader */ #if FEATURE_ATI_fragment_shader SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI); @@ -8162,7 +8298,7 @@ _mesa_init_dlist_table(struct _glapi_table *table) SET_UnmapBufferARB(table, _mesa_UnmapBufferARB); #endif -#if FEATURE_ARB_occlusion_query +#if FEATURE_queryobj SET_BeginQueryARB(table, save_BeginQueryARB); SET_EndQueryARB(table, save_EndQueryARB); SET_GenQueriesARB(table, _mesa_GenQueriesARB); @@ -8191,6 +8327,18 @@ _mesa_init_dlist_table(struct _glapi_table *table) SET_ProgramEnvParameters4fvEXT(table, save_ProgramEnvParameters4fvEXT); SET_ProgramLocalParameters4fvEXT(table, save_ProgramLocalParameters4fvEXT); #endif + + /* ARB 50. GL_ARB_map_buffer_range */ +#if FEATURE_ARB_map_buffer_range + SET_MapBufferRange(table, _mesa_MapBufferRange); /* no dlist save */ + SET_FlushMappedBufferRange(table, _mesa_FlushMappedBufferRange); /* no dl */ +#endif + + /* ARB 59. GL_ARB_copy_buffer */ + SET_CopyBufferSubData(table, _mesa_CopyBufferSubData); /* no dlist save */ + + /* 364. GL_EXT_provoking_vertex */ + SET_ProvokingVertexEXT(table, save_ProvokingVertexEXT); } @@ -8209,7 +8357,7 @@ enum_string(GLenum k) static void GLAPIENTRY print_list(GLcontext *ctx, GLuint list) { - struct mesa_display_list *dlist; + struct gl_display_list *dlist; Node *n; GLboolean done; @@ -8222,7 +8370,7 @@ print_list(GLcontext *ctx, GLuint list) if (!dlist) return; - n = dlist->node; + n = dlist->Head; _mesa_printf("START-LIST %u, address %p\n", list, (void *) n); @@ -8427,6 +8575,11 @@ print_list(GLcontext *ctx, GLuint list) _mesa_printf("EVAL_P2 %d %d\n", n[1].i, n[2].i); break; + case OPCODE_PROVOKING_VERTEX: + _mesa_printf("ProvokingVertex %s\n", + _mesa_lookup_enum_by_nr(n[1].ui)); + break; + /* * meta opcodes/commands */ @@ -8484,22 +8637,21 @@ mesa_print_display_list(GLuint list) void _mesa_save_vtxfmt_init(GLvertexformat * vfmt) { - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_); + vfmt->Begin = save_Begin; - vfmt->CallList = _mesa_save_CallList; - vfmt->CallLists = _mesa_save_CallLists; + + _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_save_); + vfmt->Color3f = save_Color3f; vfmt->Color3fv = save_Color3fv; vfmt->Color4f = save_Color4f; vfmt->Color4fv = save_Color4fv; vfmt->EdgeFlag = save_EdgeFlag; vfmt->End = save_End; - vfmt->EvalCoord1f = save_EvalCoord1f; - vfmt->EvalCoord1fv = save_EvalCoord1fv; - vfmt->EvalCoord2f = save_EvalCoord2f; - vfmt->EvalCoord2fv = save_EvalCoord2fv; - vfmt->EvalPoint1 = save_EvalPoint1; - vfmt->EvalPoint2 = save_EvalPoint2; + + _MESA_INIT_EVAL_VTXFMT(vfmt, save_); + vfmt->FogCoordfEXT = save_FogCoordfEXT; vfmt->FogCoordfvEXT = save_FogCoordfvEXT; vfmt->Indexf = save_Indexf; @@ -8548,8 +8700,6 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt) vfmt->VertexAttrib4fARB = save_VertexAttrib4fARB; vfmt->VertexAttrib4fvARB = save_VertexAttrib4fvARB; - vfmt->EvalMesh1 = _mesa_save_EvalMesh1; - vfmt->EvalMesh2 = _mesa_save_EvalMesh2; vfmt->Rectf = save_Rectf; /* The driver is required to implement these as @@ -8562,10 +8712,40 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt) vfmt->DrawArrays = 0; vfmt->DrawElements = 0; vfmt->DrawRangeElements = 0; + vfmt->MultiDrawElemementsEXT = 0; + vfmt->DrawElementsBaseVertex = 0; + vfmt->DrawRangeElementsBaseVertex = 0; + vfmt->MultiDrawElemementsBaseVertex = 0; #endif } +void +_mesa_install_dlist_vtxfmt(struct _glapi_table *disp, + const GLvertexformat *vfmt) +{ + SET_CallList(disp, vfmt->CallList); + SET_CallLists(disp, vfmt->CallLists); +} + + +void _mesa_init_dlist_dispatch(struct _glapi_table *disp) +{ + SET_CallList(disp, _mesa_CallList); + SET_CallLists(disp, _mesa_CallLists); + + SET_DeleteLists(disp, _mesa_DeleteLists); + SET_EndList(disp, _mesa_EndList); + SET_GenLists(disp, _mesa_GenLists); + SET_IsList(disp, _mesa_IsList); + SET_ListBase(disp, _mesa_ListBase); + SET_NewList(disp, _mesa_NewList); +} + + +#endif /* FEATURE_dlist */ + + /** * Initialize display list state for given context. */ @@ -8584,13 +8764,13 @@ _mesa_init_display_list(GLcontext *ctx) ctx->ListState.CallDepth = 0; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; - ctx->ListState.CurrentListPtr = NULL; ctx->ListState.CurrentBlock = NULL; - ctx->ListState.CurrentListNum = 0; ctx->ListState.CurrentPos = 0; /* Display List group */ ctx->List.ListBase = 0; +#if FEATURE_dlist _mesa_save_vtxfmt_init(&ctx->ListState.ListVtxfmt); +#endif } |