Re: [Mesa-dev] [PATCH] mesa: rewrite save_CallLists() code
On 02/08/2016 06:25 PM, Ian Romanick wrote: On 02/08/2016 05:06 PM, Brian Paul wrote: When glCallLists() is compiled into a display list, preserve the call as a single glCallLists rather than 'n' glCallList calls. This will matter for an upcoming display list optimization project. I think this code is generally better than what was here before, but reading that last sentence made me die inside just a little. :) Yeah, I know what you mean. But legacy GL apps will be with us for a long time and here at VMware we find people are very interested in running legacy apps on legacy OSes in VMs. In this particular case, we have an app that makes quite a few calls to glCallLists() to render GLbitmap text. I'm working on a texture atlas optimization which puts all the glBitmap glyphs into a texture so we can render glCallLists() text by drawing textured quads. This greatly reduces texture uploads and gives us a worthwhile speed-up. The code's nearly done. Just working on some last details... -Brian ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] mesa: rewrite save_CallLists() code
When glCallLists() is compiled into a display list, preserve the call as a single glCallLists rather than 'n' glCallList calls. This will matter for an upcoming display list optimization project. --- src/mesa/main/dlist.c | 61 +-- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 65f0929..fb31d2f 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -194,7 +194,7 @@ typedef enum OPCODE_BLEND_FUNC_SEPARATE_I, OPCODE_CALL_LIST, - OPCODE_CALL_LIST_OFFSET, + OPCODE_CALL_LISTS, OPCODE_CLEAR, OPCODE_CLEAR_ACCUM, OPCODE_CLEAR_COLOR, @@ -706,6 +706,10 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) free(get_pointer([10])); n += InstSize[n[0].opcode]; break; + case OPCODE_CALL_LISTS: +free(get_pointer([3])); +n += InstSize[n[0].opcode]; +break; case OPCODE_DRAW_PIXELS: free(get_pointer([5])); n += InstSize[n[0].opcode]; @@ -1569,37 +1573,49 @@ static void GLAPIENTRY save_CallLists(GLsizei num, GLenum type, const GLvoid * lists) { GET_CURRENT_CONTEXT(ctx); - GLint i; - GLboolean typeErrorFlag; + unsigned type_size; + Node *n; + void *lists_copy; SAVE_FLUSH_VERTICES(ctx); switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: + type_size = 1; + break; case GL_SHORT: case GL_UNSIGNED_SHORT: + case GL_2_BYTES: + type_size = 2; + break; + case GL_3_BYTES: + type_size = 3; + break; case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: - case GL_2_BYTES: - case GL_3_BYTES: case GL_4_BYTES: - typeErrorFlag = GL_FALSE; + type_size = 4; break; default: - typeErrorFlag = GL_TRUE; + type_size = 0; } - 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) { - n[1].i = list; - n[2].b = typeErrorFlag; - } + if (num > 0 && type_size > 0) { + /* create a copy of the array of list IDs to save in the display list */ + lists_copy = memdup(lists, num * type_size); + } else { + lists_copy = NULL; } + n = alloc_instruction(ctx, OPCODE_CALL_LISTS, 2 + POINTER_DWORDS); + if (n) { + n[1].i = num; + n[2].e = type; + save_pointer([3], lists_copy); + }; + /* After this, we don't know what state we're in. Invalidate all * cached information previously gathered: */ @@ -7772,15 +7788,9 @@ execute_list(struct gl_context *ctx, GLuint list) execute_list(ctx, n[1].ui); } break; - case OPCODE_CALL_LIST_OFFSET: -/* Generated by glCallLists() so we must add ListBase */ -if (n[2].b) { - /* user specified a bad data type at compile time */ - _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)"); -} -else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { - GLuint list = (GLuint) (ctx->List.ListBase + n[1].i); - execute_list(ctx, list); + case OPCODE_CALL_LISTS: +if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { + CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, get_pointer([3]))); } break; case OPCODE_CLEAR: @@ -9736,9 +9746,8 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) case OPCODE_CALL_LIST: fprintf(f, "CallList %d\n", (int) n[1].ui); break; - case OPCODE_CALL_LIST_OFFSET: -fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui, - ctx->List.ListBase, ctx->List.ListBase + n[1].ui); + case OPCODE_CALL_LISTS: +fprintf(f, "CallLists %d, %s\n", n[1].i, enum_string(n[1].e)); break; case OPCODE_DISABLE: fprintf(f, "Disable %s\n", enum_string(n[1].e)); -- 1.9.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] mesa: rewrite save_CallLists() code
On 02/08/2016 05:06 PM, Brian Paul wrote: > When glCallLists() is compiled into a display list, preserve the call > as a single glCallLists rather than 'n' glCallList calls. This will > matter for an upcoming display list optimization project. I think this code is generally better than what was here before, but reading that last sentence made me die inside just a little. :) Reviewed-by: Ian Romanick> --- > src/mesa/main/dlist.c | 61 > +-- > 1 file changed, 35 insertions(+), 26 deletions(-) > > diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c > index 65f0929..fb31d2f 100644 > --- a/src/mesa/main/dlist.c > +++ b/src/mesa/main/dlist.c > @@ -194,7 +194,7 @@ typedef enum > OPCODE_BLEND_FUNC_SEPARATE_I, > > OPCODE_CALL_LIST, > - OPCODE_CALL_LIST_OFFSET, > + OPCODE_CALL_LISTS, > OPCODE_CLEAR, > OPCODE_CLEAR_ACCUM, > OPCODE_CLEAR_COLOR, > @@ -706,6 +706,10 @@ _mesa_delete_list(struct gl_context *ctx, struct > gl_display_list *dlist) > free(get_pointer([10])); > n += InstSize[n[0].opcode]; > break; > + case OPCODE_CALL_LISTS: > +free(get_pointer([3])); > +n += InstSize[n[0].opcode]; > +break; > case OPCODE_DRAW_PIXELS: > free(get_pointer([5])); > n += InstSize[n[0].opcode]; > @@ -1569,37 +1573,49 @@ static void GLAPIENTRY > save_CallLists(GLsizei num, GLenum type, const GLvoid * lists) > { > GET_CURRENT_CONTEXT(ctx); > - GLint i; > - GLboolean typeErrorFlag; > + unsigned type_size; > + Node *n; > + void *lists_copy; > > SAVE_FLUSH_VERTICES(ctx); > > switch (type) { > case GL_BYTE: > case GL_UNSIGNED_BYTE: > + type_size = 1; > + break; > case GL_SHORT: > case GL_UNSIGNED_SHORT: > + case GL_2_BYTES: > + type_size = 2; > + break; > + case GL_3_BYTES: > + type_size = 3; > + break; > case GL_INT: > case GL_UNSIGNED_INT: > case GL_FLOAT: > - case GL_2_BYTES: > - case GL_3_BYTES: > case GL_4_BYTES: > - typeErrorFlag = GL_FALSE; > + type_size = 4; >break; > default: > - typeErrorFlag = GL_TRUE; > + type_size = 0; > } > > - 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) { > - n[1].i = list; > - n[2].b = typeErrorFlag; > - } > + if (num > 0 && type_size > 0) { > + /* create a copy of the array of list IDs to save in the display list > */ > + lists_copy = memdup(lists, num * type_size); > + } else { > + lists_copy = NULL; > } > > + n = alloc_instruction(ctx, OPCODE_CALL_LISTS, 2 + POINTER_DWORDS); > + if (n) { > + n[1].i = num; > + n[2].e = type; > + save_pointer([3], lists_copy); > + }; > + > /* After this, we don't know what state we're in. Invalidate all > * cached information previously gathered: > */ > @@ -7772,15 +7788,9 @@ execute_list(struct gl_context *ctx, GLuint list) > execute_list(ctx, n[1].ui); > } > break; > - case OPCODE_CALL_LIST_OFFSET: > -/* Generated by glCallLists() so we must add ListBase */ > -if (n[2].b) { > - /* user specified a bad data type at compile time */ > - _mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)"); > -} > -else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { > - GLuint list = (GLuint) (ctx->List.ListBase + n[1].i); > - execute_list(ctx, list); > + case OPCODE_CALL_LISTS: > +if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { > + CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, > get_pointer([3]))); > } > break; > case OPCODE_CLEAR: > @@ -9736,9 +9746,8 @@ print_list(struct gl_context *ctx, GLuint list, const > char *fname) > case OPCODE_CALL_LIST: > fprintf(f, "CallList %d\n", (int) n[1].ui); > break; > - case OPCODE_CALL_LIST_OFFSET: > -fprintf(f, "CallList %d + offset %u = %u\n", (int) n[1].ui, > - ctx->List.ListBase, ctx->List.ListBase + n[1].ui); > + case OPCODE_CALL_LISTS: > +fprintf(f, "CallLists %d, %s\n", n[1].i, enum_string(n[1].e)); > break; > case OPCODE_DISABLE: > fprintf(f, "Disable %s\n", enum_string(n[1].e)); > ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev