Re: [Mesa-dev] [PATCH] mesa: rewrite save_CallLists() code

2016-02-08 Thread Brian Paul

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

2016-02-08 Thread Brian Paul
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

2016-02-08 Thread Ian Romanick
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