X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fdlist.c;h=431c4b48b7979b3c8cf00293a8b0bde3ce2152e7;hb=c4925d7f3b66d63fbdd7b7607cd809db1e58bee9;hp=5c7160d0540f72be5ed14c0bcb18971078d0b747;hpb=4000c0112a49c28793844f454278b50e00943173;p=mesa.git diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 5c7160d0540..431c4b48b79 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -29,6 +29,7 @@ * Display lists management functions. */ +#include "c99_math.h" #include "glheader.h" #include "imports.h" #include "api_arrayelt.h" @@ -81,7 +82,7 @@ struct gl_list_instruction GLuint Size; void (*Execute)( struct gl_context *ctx, void *data ); void (*Destroy)( struct gl_context *ctx, void *data ); - void (*Print)( struct gl_context *ctx, void *data ); + void (*Print)( struct gl_context *ctx, void *data, FILE *f ); }; @@ -398,6 +399,9 @@ typedef enum OPCODE_PROGRAM_UNIFORM_MATRIX34F, OPCODE_PROGRAM_UNIFORM_MATRIX43F, + /* GL_ARB_clip_control */ + OPCODE_CLIP_CONTROL, + /* GL_ARB_color_buffer_float */ OPCODE_CLAMP_COLOR, @@ -481,9 +485,13 @@ typedef enum /* ARB_uniform_buffer_object */ OPCODE_UNIFORM_BLOCK_BINDING, + /* EXT_polygon_offset_clamp */ + OPCODE_POLYGON_OFFSET_CLAMP, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, + OPCODE_NOP, /* No-op (used for 8-byte alignment */ OPCODE_END_OF_LIST, OPCODE_EXT_0 } OpCode; @@ -542,13 +550,13 @@ union pointer * Save a 4 or 8-byte pointer at dest (and dest+1). */ static inline void -save_pointer(union gl_dlist_node *dest, void *src) +save_pointer(Node *dest, void *src) { union pointer p; unsigned i; STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2); - STATIC_ASSERT(sizeof(union gl_dlist_node) == 4); + STATIC_ASSERT(sizeof(Node) == 4); p.ptr = src; @@ -561,7 +569,7 @@ save_pointer(union gl_dlist_node *dest, void *src) * Retrieve a 4 or 8-byte pointer from node (node+1). */ static inline void * -get_pointer(const union gl_dlist_node *node) +get_pointer(const Node *node) { union pointer p; unsigned i; @@ -575,7 +583,7 @@ get_pointer(const union gl_dlist_node *node) /** * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit - * environment. In 64-bit env, sizeof(Node)==8 anyway. + * environment. */ union uint64_pair { @@ -663,11 +671,11 @@ ext_opcode_execute(struct gl_context *ctx, Node *node) /** Print an extended opcode instruction */ static GLint -ext_opcode_print(struct gl_context *ctx, Node *node) +ext_opcode_print(struct gl_context *ctx, Node *node, FILE *f) { const GLint i = node[0].opcode - OPCODE_EXT_0; GLint step; - ctx->ListExt->Opcode[i].Print(ctx, &node[1]); + ctx->ListExt->Opcode[i].Print(ctx, &node[1], f); step = ctx->ListExt->Opcode[i].Size; return step; } @@ -905,7 +913,7 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list) return (GLint) uiptr[n]; case GL_FLOAT: fptr = (GLfloat *) list; - return (GLint) FLOORF(fptr[n]); + return (GLint) floorf(fptr[n]); case GL_2_BYTES: ubptr = ((GLubyte *) list) + 2 * n; return (GLint) ubptr[0] * 256 @@ -954,11 +962,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, /* no PBO */ 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); + 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"); } @@ -980,11 +985,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, } src = ADD_POINTERS(map, pixels); - 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); + image = _mesa_unpack_image(dimensions, width, height, depth, + format, type, src, unpack); ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); @@ -1015,27 +1017,43 @@ memdup(const void *src, GLsizei bytes) * Allocate space for a display list instruction (opcode + payload space). * \param opcode the instruction opcode (OPCODE_* value) * \param bytes instruction payload size (not counting opcode) - * \return pointer to allocated memory (the opcode space) + * \param align8 does the payload need to be 8-byte aligned? + * This is only relevant in 64-bit environments. + * \return pointer to allocated memory (the payload will be at pointer+1) */ static Node * -dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) +dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) { const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ + GLuint nopNode; Node *n; - if (opcode < (GLuint) OPCODE_EXT_0) { + if (opcode < OPCODE_EXT_0) { if (InstSize[opcode] == 0) { /* save instruction size now */ InstSize[opcode] = numNodes; } else { /* make sure instruction size agrees */ - ASSERT(numNodes == InstSize[opcode]); + assert(numNodes == InstSize[opcode]); } } - if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) { + if (sizeof(void *) > sizeof(Node) && align8 + && ctx->ListState.CurrentPos % 2 == 0) { + /* The opcode would get placed at node[0] and the payload would start + * at node[1]. But the payload needs to be at an even offset (8-byte + * multiple). + */ + nopNode = 1; + } + else { + nopNode = 0; + } + + if (ctx->ListState.CurrentPos + nopNode + numNodes + contNodes + > BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; @@ -1045,13 +1063,34 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; } + + /* a fresh block should be 8-byte aligned on 64-bit systems */ + assert(((GLintptr) newblock) % sizeof(void *) == 0); + save_pointer(&n[1], newblock); ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; + + /* Display list nodes are always 4 bytes. If we need 8-byte alignment + * we have to insert a NOP so that the payload of the real opcode lands + * on an even location: + * node[0] = OPCODE_NOP + * node[1] = OPCODE_x; + * node[2] = start of payload + */ + nopNode = sizeof(void *) > sizeof(Node) && align8; } n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; - ctx->ListState.CurrentPos += numNodes; + if (nopNode) { + assert(ctx->ListState.CurrentPos % 2 == 0); /* even value */ + n[0].opcode = OPCODE_NOP; + n++; + /* The "real" opcode will now be at an odd location and the payload + * will be at an even location. + */ + } + ctx->ListState.CurrentPos += nopNode + numNodes; n[0].opcode = opcode; @@ -1072,7 +1111,22 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) void * _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes) { - Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes); + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, false); + if (n) + return n + 1; /* return pointer to payload area, after opcode */ + else + return NULL; +} + + +/** + * Same as _mesa_dlist_alloc(), but return a pointer which is 8-byte + * aligned in 64-bit environments, 4-byte aligned otherwise. + */ +void * +_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes) +{ + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, true); if (n) return n + 1; /* return pointer to payload area, after opcode */ else @@ -1095,7 +1149,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx, GLuint size, void (*execute) (struct gl_context *, void *), void (*destroy) (struct gl_context *, void *), - void (*print) (struct gl_context *, void *)) + void (*print) (struct gl_context *, void *, FILE *)) { if (ctx->ListExt->NumOpcodes < MAX_DLIST_EXT_OPCODES) { const GLuint i = ctx->ListExt->NumOpcodes++; @@ -1122,7 +1176,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx, static inline Node * alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) { - return dlist_alloc(ctx, opcode, nparams * sizeof(Node)); + return dlist_alloc(ctx, opcode, nparams * sizeof(Node), false); } @@ -3141,6 +3195,22 @@ save_PolygonOffsetEXT(GLfloat factor, GLfloat bias) save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias); } +static void GLAPIENTRY +save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET_CLAMP, 3); + if (n) { + n[1].f = factor; + n[2].f = units; + n[3].f = clamp; + } + if (ctx->ExecuteFlag) { + CALL_PolygonOffsetClampEXT(ctx->Exec, (factor, units, clamp)); + } +} static void GLAPIENTRY save_PopAttrib(void) @@ -5020,7 +5090,7 @@ save_Attr1fNV(GLenum attr, GLfloat x) n[2].f = x; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 1; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); @@ -5042,7 +5112,7 @@ save_Attr2fNV(GLenum attr, GLfloat x, GLfloat y) n[3].f = y; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 2; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); @@ -5065,7 +5135,7 @@ save_Attr3fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 3; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); @@ -5089,7 +5159,7 @@ save_Attr4fNV(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[5].f = w; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 4; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); @@ -5111,7 +5181,7 @@ save_Attr1fARB(GLenum attr, GLfloat x) n[2].f = x; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 1; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1); @@ -5133,7 +5203,7 @@ save_Attr2fARB(GLenum attr, GLfloat x, GLfloat y) n[3].f = y; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 2; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, 0, 1); @@ -5156,7 +5226,7 @@ save_Attr3fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 3; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, 1); @@ -5180,7 +5250,7 @@ save_Attr4fARB(GLenum attr, GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[5].f = w; } - ASSERT(attr < MAX_VERTEX_GENERIC_ATTRIBS); + assert(attr < MAX_VERTEX_GENERIC_ATTRIBS); ctx->ListState.ActiveAttribSize[attr] = 4; ASSIGN_4V(ctx->ListState.CurrentAttrib[attr], x, y, z, w); @@ -7207,6 +7277,22 @@ save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, } } +static void GLAPIENTRY +save_ClipControl(GLenum origin, GLenum depth) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_CLIP_CONTROL, 2); + if (n) { + n[1].e = origin; + n[2].e = depth; + } + if (ctx->ExecuteFlag) { + CALL_ClipControl(ctx->Exec, (origin, depth)); + } +} + static void GLAPIENTRY save_ClampColorARB(GLenum target, GLenum clamp) { @@ -7966,17 +8052,8 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_LoadIdentity(ctx->Exec, ()); break; case OPCODE_LOAD_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_LoadMatrixf(ctx->Exec, (m)); - } + STATIC_ASSERT(sizeof(Node) == sizeof(GLfloat)); + CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_LOAD_NAME: CALL_LoadName(ctx->Exec, (n[1].ui)); @@ -8022,17 +8099,7 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_MatrixMode(ctx->Exec, (n[1].e)); break; case OPCODE_MULT_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_MultMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_MultMatrixf(ctx->Exec, (m)); - } + CALL_MultMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_ORTHO: CALL_Ortho(ctx->Exec, @@ -8077,6 +8144,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_POLYGON_OFFSET: CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f)); break; + case OPCODE_POLYGON_OFFSET_CLAMP: + CALL_PolygonOffsetClampEXT(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + break; case OPCODE_POP_ATTRIB: CALL_PopAttrib(ctx->Exec, ()); break; @@ -8617,6 +8687,10 @@ execute_list(struct gl_context *ctx, GLuint list) get_pointer(&n[5]))); break; + case OPCODE_CLIP_CONTROL: + CALL_ClipControl(ctx->Exec, (n[1].e, n[2].e)); + break; + case OPCODE_CLAMP_COLOR: CALL_ClampColor(ctx->Exec, (n[1].e, n[2].e)); break; @@ -8625,84 +8699,34 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); break; case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI: - { - GLfloat values[4]; - GLuint i, dst = n[1].ui; - - for (i = 0; i < 4; i++) - values[i] = n[1 + i].f; - CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values)); - } + CALL_SetFragmentShaderConstantATI(ctx->Exec, (n[1].ui, &n[2].f)); break; case OPCODE_ATTR_1F_NV: CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_NV: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_1F_ARB: CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_ARB: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_MATERIAL: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); - else { - GLfloat f[4]; - f[0] = n[3].f; - f[1] = n[4].f; - f[2] = n[5].f; - f[3] = n[6].f; - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f)); - } + CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); break; case OPCODE_BEGIN: CALL_Begin(ctx->Exec, (n[1].e)); @@ -8880,6 +8904,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + /* no-op */ + break; case OPCODE_END_OF_LIST: done = GL_TRUE; break; @@ -9551,6 +9578,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_TexParameterIiv(table, save_TexParameterIiv); SET_TexParameterIuiv(table, save_TexParameterIuiv); + /* GL_ARB_clip_control */ + SET_ClipControl(table, save_ClipControl); + /* GL_ARB_color_buffer_float */ SET_ClampColor(table, save_ClampColorARB); @@ -9676,6 +9706,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv); SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv); SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv); + + /* GL_EXT_polygon_offset_clamp */ + SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT); } @@ -9690,16 +9723,24 @@ enum_string(GLenum k) /** * Print the commands in a display list. For debugging only. * TODO: many commands aren't handled yet. + * \param fname filename to write display list to. If null, use stdout. */ static void GLAPIENTRY -print_list(struct gl_context *ctx, GLuint list) +print_list(struct gl_context *ctx, GLuint list, const char *fname) { struct gl_display_list *dlist; Node *n; GLboolean done; + FILE *f = stdout; + + if (fname) { + f = fopen(fname, "w"); + if (!f) + return; + } if (!islist(ctx, list)) { - printf("%u is not a display list ID\n", list); + fprintf(f, "%u is not a display list ID\n", list); return; } @@ -9709,199 +9750,202 @@ print_list(struct gl_context *ctx, GLuint list) n = dlist->Head; - printf("START-LIST %u, address %p\n", list, (void *) n); + fprintf(f, "START-LIST %u, address %p\n", list, (void *) n); done = n ? GL_FALSE : GL_TRUE; while (!done) { const OpCode opcode = n[0].opcode; if (is_ext_opcode(opcode)) { - n += ext_opcode_print(ctx, n); + n += ext_opcode_print(ctx, n, f); } else { switch (opcode) { case OPCODE_ACCUM: - printf("Accum %s %g\n", enum_string(n[1].e), n[2].f); + fprintf(f, "Accum %s %g\n", enum_string(n[1].e), n[2].f); + break; + case OPCODE_ACTIVE_TEXTURE: + fprintf(f, "ActiveTexture(%s)\n", enum_string(n[1].e)); break; case OPCODE_BITMAP: - printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, + fprintf(f, "Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f, get_pointer(&n[7])); break; case OPCODE_CALL_LIST: - printf("CallList %d\n", (int) n[1].ui); + fprintf(f, "CallList %d\n", (int) n[1].ui); break; case OPCODE_CALL_LIST_OFFSET: - printf("CallList %d + offset %u = %u\n", (int) n[1].ui, + fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui, ctx->List.ListBase, ctx->List.ListBase + n[1].ui); break; case OPCODE_DISABLE: - printf("Disable %s\n", enum_string(n[1].e)); + fprintf(f, "Disable %s\n", enum_string(n[1].e)); break; case OPCODE_ENABLE: - printf("Enable %s\n", enum_string(n[1].e)); + fprintf(f, "Enable %s\n", enum_string(n[1].e)); break; case OPCODE_FRUSTUM: - printf("Frustum %g %g %g %g %g %g\n", + fprintf(f, "Frustum %g %g %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_LINE_STIPPLE: - printf("LineStipple %d %x\n", n[1].i, (int) n[2].us); + fprintf(f, "LineStipple %d %x\n", n[1].i, (int) n[2].us); break; case OPCODE_LOAD_IDENTITY: - printf("LoadIdentity\n"); + fprintf(f, "LoadIdentity\n"); break; case OPCODE_LOAD_MATRIX: - printf("LoadMatrix\n"); - printf(" %8f %8f %8f %8f\n", + fprintf(f, "LoadMatrix\n"); + fprintf(f, " %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); break; case OPCODE_MULT_MATRIX: - printf("MultMatrix (or Rotate)\n"); - printf(" %8f %8f %8f %8f\n", + fprintf(f, "MultMatrix (or Rotate)\n"); + fprintf(f, " %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); - printf(" %8f %8f %8f %8f\n", + fprintf(f, " %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); break; case OPCODE_ORTHO: - printf("Ortho %g %g %g %g %g %g\n", + fprintf(f, "Ortho %g %g %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_POP_ATTRIB: - printf("PopAttrib\n"); + fprintf(f, "PopAttrib\n"); break; case OPCODE_POP_MATRIX: - printf("PopMatrix\n"); + fprintf(f, "PopMatrix\n"); break; case OPCODE_POP_NAME: - printf("PopName\n"); + fprintf(f, "PopName\n"); break; case OPCODE_PUSH_ATTRIB: - printf("PushAttrib %x\n", n[1].bf); + fprintf(f, "PushAttrib %x\n", n[1].bf); break; case OPCODE_PUSH_MATRIX: - printf("PushMatrix\n"); + fprintf(f, "PushMatrix\n"); break; case OPCODE_PUSH_NAME: - printf("PushName %d\n", (int) n[1].ui); + fprintf(f, "PushName %d\n", (int) n[1].ui); break; case OPCODE_RASTER_POS: - printf("RasterPos %g %g %g %g\n", + fprintf(f, "RasterPos %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_ROTATE: - printf("Rotate %g %g %g %g\n", + fprintf(f, "Rotate %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_SCALE: - printf("Scale %g %g %g\n", n[1].f, n[2].f, n[3].f); + fprintf(f, "Scale %g %g %g\n", n[1].f, n[2].f, n[3].f); break; case OPCODE_TRANSLATE: - printf("Translate %g %g %g\n", n[1].f, n[2].f, n[3].f); + fprintf(f, "Translate %g %g %g\n", n[1].f, n[2].f, n[3].f); break; case OPCODE_BIND_TEXTURE: - printf("BindTexture %s %d\n", + fprintf(f, "BindTexture %s %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].ui); break; case OPCODE_SHADE_MODEL: - printf("ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); + fprintf(f, "ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); break; case OPCODE_MAP1: - printf("Map1 %s %.3f %.3f %d %d\n", + fprintf(f, "Map1 %s %.3f %.3f %d %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].f, n[3].f, n[4].i, n[5].i); break; case OPCODE_MAP2: - printf("Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n", + fprintf(f, "Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n", _mesa_lookup_enum_by_nr(n[1].ui), n[2].f, n[3].f, n[4].f, n[5].f, n[6].i, n[7].i, n[8].i, n[9].i); break; case OPCODE_MAPGRID1: - printf("MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f); + fprintf(f, "MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_MAPGRID2: - printf("MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n", + fprintf(f, "MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f); break; case OPCODE_EVALMESH1: - printf("EvalMesh1 %d %d\n", n[1].i, n[2].i); + fprintf(f, "EvalMesh1 %d %d\n", n[1].i, n[2].i); break; case OPCODE_EVALMESH2: - printf("EvalMesh2 %d %d %d %d\n", + fprintf(f, "EvalMesh2 %d %d %d %d\n", n[1].i, n[2].i, n[3].i, n[4].i); break; case OPCODE_ATTR_1F_NV: - printf("ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f); + fprintf(f, "ATTR_1F_NV attr %d: %f\n", n[1].i, n[2].f); break; case OPCODE_ATTR_2F_NV: - printf("ATTR_2F_NV attr %d: %f %f\n", + fprintf(f, "ATTR_2F_NV attr %d: %f %f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_ATTR_3F_NV: - printf("ATTR_3F_NV attr %d: %f %f %f\n", + fprintf(f, "ATTR_3F_NV attr %d: %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f); break; case OPCODE_ATTR_4F_NV: - printf("ATTR_4F_NV attr %d: %f %f %f %f\n", + fprintf(f, "ATTR_4F_NV attr %d: %f %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f, n[5].f); break; case OPCODE_ATTR_1F_ARB: - printf("ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f); + fprintf(f, "ATTR_1F_ARB attr %d: %f\n", n[1].i, n[2].f); break; case OPCODE_ATTR_2F_ARB: - printf("ATTR_2F_ARB attr %d: %f %f\n", + fprintf(f, "ATTR_2F_ARB attr %d: %f %f\n", n[1].i, n[2].f, n[3].f); break; case OPCODE_ATTR_3F_ARB: - printf("ATTR_3F_ARB attr %d: %f %f %f\n", + fprintf(f, "ATTR_3F_ARB attr %d: %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f); break; case OPCODE_ATTR_4F_ARB: - printf("ATTR_4F_ARB attr %d: %f %f %f %f\n", + fprintf(f, "ATTR_4F_ARB attr %d: %f %f %f %f\n", n[1].i, n[2].f, n[3].f, n[4].f, n[5].f); break; case OPCODE_MATERIAL: - printf("MATERIAL %x %x: %f %f %f %f\n", + fprintf(f, "MATERIAL %x %x: %f %f %f %f\n", n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f); break; case OPCODE_BEGIN: - printf("BEGIN %x\n", n[1].i); + fprintf(f, "BEGIN %x\n", n[1].i); break; case OPCODE_END: - printf("END\n"); + fprintf(f, "END\n"); break; case OPCODE_RECTF: - printf("RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f, + fprintf(f, "RECTF %f %f %f %f\n", n[1].f, n[2].f, n[3].f, n[4].f); break; case OPCODE_EVAL_C1: - printf("EVAL_C1 %f\n", n[1].f); + fprintf(f, "EVAL_C1 %f\n", n[1].f); break; case OPCODE_EVAL_C2: - printf("EVAL_C2 %f %f\n", n[1].f, n[2].f); + fprintf(f, "EVAL_C2 %f %f\n", n[1].f, n[2].f); break; case OPCODE_EVAL_P1: - printf("EVAL_P1 %d\n", n[1].i); + fprintf(f, "EVAL_P1 %d\n", n[1].i); break; case OPCODE_EVAL_P2: - printf("EVAL_P2 %d %d\n", n[1].i, n[2].i); + fprintf(f, "EVAL_P2 %d %d\n", n[1].i, n[2].i); break; case OPCODE_PROVOKING_VERTEX: - printf("ProvokingVertex %s\n", + fprintf(f, "ProvokingVertex %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); break; @@ -9909,15 +9953,18 @@ print_list(struct gl_context *ctx, GLuint list) * meta opcodes/commands */ case OPCODE_ERROR: - printf("Error: %s %s\n", enum_string(n[1].e), + fprintf(f, "Error: %s %s\n", enum_string(n[1].e), (const char *) get_pointer(&n[2])); break; case OPCODE_CONTINUE: - printf("DISPLAY-LIST-CONTINUE\n"); + fprintf(f, "DISPLAY-LIST-CONTINUE\n"); n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + fprintf(f, "NOP\n"); + break; case OPCODE_END_OF_LIST: - printf("END-LIST %u\n", list); + fprintf(f, "END-LIST %u\n", list); done = GL_TRUE; break; default: @@ -9928,7 +9975,7 @@ print_list(struct gl_context *ctx, GLuint list) return; } else { - printf("command %d, %u operands\n", opcode, + fprintf(f, "command %d, %u operands\n", opcode, InstSize[opcode]); } } @@ -9938,6 +9985,10 @@ print_list(struct gl_context *ctx, GLuint list) } } } + + fflush(f); + if (fname) + fclose(f); } @@ -9951,7 +10002,7 @@ void mesa_print_display_list(GLuint list) { GET_CURRENT_CONTEXT(ctx); - print_list(ctx, list); + print_list(ctx, list, NULL); } @@ -10062,6 +10113,8 @@ _mesa_init_display_list(struct gl_context *ctx) ctx->List.ListBase = 0; save_vtxfmt_init(&ctx->ListState.ListVtxfmt); + + InstSize[OPCODE_NOP] = 1; }