summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2016-02-08 17:50:23 -0700
committerBrian Paul <[email protected]>2016-02-09 11:27:48 -0700
commit0193e20df531039e89de089bdb33abd4e2095e19 (patch)
tree60e708b14749446c4db18bb8fab25e3dd2daa62c
parent711d5347cf4e4cae60461487bcf416c915aa7395 (diff)
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. Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/main/dlist.c61
1 files changed, 35 insertions, 26 deletions
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 65f092936b3..fb31d2f2706 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(&n[10]));
n += InstSize[n[0].opcode];
break;
+ case OPCODE_CALL_LISTS:
+ free(get_pointer(&n[3]));
+ n += InstSize[n[0].opcode];
+ break;
case OPCODE_DRAW_PIXELS:
free(get_pointer(&n[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(&n[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(&n[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));