mesa: add GL_EXT_window_rectangles state storage/retrieval functionality
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 10 Jun 2016 02:50:43 +0000 (22:50 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 18 Jun 2016 16:51:55 +0000 (12:51 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/attrib.c
src/mesa/main/config.h
src/mesa/main/dlist.c
src/mesa/main/extensions_table.h
src/mesa/main/get.c
src/mesa/main/get_hash_params.py
src/mesa/main/mtypes.h
src/mesa/main/scissor.c

index 52a8ba6336366dae5b31226b31332bc002888fc7..f859191f69c76dc4c3724170804a47b6da5e4c56 100644 (file)
@@ -1305,6 +1305,13 @@ _mesa_PopAttrib(void)
                   _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i,
                                     (scissor->EnableFlags >> i) & 1);
                }
+               if (ctx->Extensions.EXT_window_rectangles) {
+                  STATIC_ASSERT(sizeof(struct gl_scissor_rect) ==
+                                4 * sizeof(GLint));
+                  _mesa_WindowRectanglesEXT(
+                        scissor->WindowRectMode, scissor->NumWindowRects,
+                        (const GLint *)scissor->WindowRects);
+               }
             }
             break;
          case GL_STENCIL_BUFFER_BIT:
index bc5e56923b8954413fe5c4c9a0b8c2d42474153b..0d0ee90e678653dc64b8c82089ad5006bb08c076 100644 (file)
  */
 #define MAX_TEXTURE_UNITS ((MAX_TEXTURE_COORD_UNITS > MAX_TEXTURE_IMAGE_UNITS) ? MAX_TEXTURE_COORD_UNITS : MAX_TEXTURE_IMAGE_UNITS)
 
-/** Maximun number of viewports supported with ARB_viewport_array */
+/** Maximum number of viewports supported with ARB_viewport_array */
 #define MAX_VIEWPORTS 16
 
-/** Maxmimum size for CVA.  May be overridden by the drivers.  */
+/** Maximum number of window rectangles supported with EXT_window_rectangles */
+#define MAX_WINDOW_RECTANGLES 8
+
+/** Maximum size for CVA.  May be overridden by the drivers.  */
 #define MAX_ARRAY_LOCK_SIZE 3000
 
 /** Subpixel precision for antialiasing, window coordinate snapping */
index 43e2ffb3a784cf95ac7968746ad86d05020332bc..4e4b1385c0b73bb72f1110d5fe46cf32d849231a 100644 (file)
@@ -485,6 +485,9 @@ typedef enum
    /* EXT_polygon_offset_clamp */
    OPCODE_POLYGON_OFFSET_CLAMP,
 
+   /* EXT_window_rectangles */
+   OPCODE_WINDOW_RECTANGLES,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -1090,7 +1093,10 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
             free(get_pointer(&n[3]));
             n += InstSize[n[0].opcode];
             break;
-
+         case OPCODE_WINDOW_RECTANGLES:
+            free(get_pointer(&n[3]));
+            n += InstSize[n[0].opcode];
+            break;
          case OPCODE_CONTINUE:
             n = (Node *) get_pointer(&n[1]);
             free(block);
@@ -7922,6 +7928,27 @@ save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding)
    }
 }
 
+/** GL_EXT_window_rectangles */
+static void GLAPIENTRY
+save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_WINDOW_RECTANGLES, 2 + POINTER_DWORDS);
+   if (n) {
+      GLint *box_copy = NULL;
+
+      if (count > 0)
+         box_copy = memdup(box, sizeof(GLint) * 4 * count);
+      n[1].e = mode;
+      n[2].si = count;
+      save_pointer(&n[3], box_copy);
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_WindowRectanglesEXT(ctx->Exec, (mode, count, box));
+   }
+}
 
 /**
  * Save an error-generating command into display list.
@@ -9122,6 +9149,12 @@ execute_list(struct gl_context *ctx, GLuint list)
             CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui));
             break;
 
+         /* GL_EXT_window_rectangles */
+         case OPCODE_WINDOW_RECTANGLES:
+            CALL_WindowRectanglesEXT(
+                  ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3])));
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) get_pointer(&n[1]);
             break;
@@ -10018,6 +10051,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
 
    /* GL_EXT_polygon_offset_clamp */
    SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT);
+
+   /* GL_EXT_window_rectangles */
+   SET_WindowRectanglesEXT(table, save_WindowRectanglesEXT);
 }
 
 
index ea8eb306f592195a5b8e62b198c27ccc349c5451..ad3bffc068a0584fc88c81321d8073743cd67602 100644 (file)
@@ -267,6 +267,7 @@ EXT(EXT_transform_feedback                  , EXT_transform_feedback
 EXT(EXT_unpack_subimage                     , dummy_true                             ,  x ,  x ,  x , ES2, 2011)
 EXT(EXT_vertex_array                        , dummy_true                             , GLL,  x ,  x ,  x , 1995)
 EXT(EXT_vertex_array_bgra                   , EXT_vertex_array_bgra                  , GLL, GLC,  x ,  x , 2008)
+EXT(EXT_window_rectangles                   , EXT_window_rectangles                  , GLL, GLC,  x ,  30, 2016)
 
 EXT(GREMEDY_string_marker                   , GREMEDY_string_marker                  , GLL, GLC,  x ,  x , 2007)
 
index 6ffa99ca01edf7fd9add5beac9d00fe0fbd76e05..8cb0cc713e3b572b9d7dd67e95671c27edf7e753 100644 (file)
@@ -464,6 +464,7 @@ EXTRA_EXT(ARB_indirect_parameters);
 EXTRA_EXT(ATI_meminfo);
 EXTRA_EXT(NVX_gpu_memory_info);
 EXTRA_EXT(ARB_cull_distance);
+EXTRA_EXT(EXT_window_rectangles);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
@@ -1944,6 +1945,17 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
       v->value_int_4[3] = ctx->Scissor.ScissorArray[index].Height;
       return TYPE_INT_4;
 
+   case GL_WINDOW_RECTANGLE_EXT:
+      if (!ctx->Extensions.EXT_window_rectangles)
+         goto invalid_enum;
+      if (index >= ctx->Const.MaxWindowRectangles)
+         goto invalid_value;
+      v->value_int_4[0] = ctx->Scissor.WindowRects[index].X;
+      v->value_int_4[1] = ctx->Scissor.WindowRects[index].Y;
+      v->value_int_4[2] = ctx->Scissor.WindowRects[index].Width;
+      v->value_int_4[3] = ctx->Scissor.WindowRects[index].Height;
+      return TYPE_INT_4;
+
    case GL_VIEWPORT:
       if (index >= ctx->Const.MaxViewports)
          goto invalid_value;
index bfcbfd687db8cb643c7868b289e6fa67e8b4f543..0672b0718e620f5c905ad510873ee8989497dc0b 100644 (file)
@@ -416,6 +416,11 @@ descriptor=[
   [ "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", "CONTEXT_INT(Const.MaxTransformFeedbackInterleavedComponents), extra_EXT_transform_feedback" ],
   [ "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", "CONTEXT_INT(Const.MaxTransformFeedbackBuffers), extra_EXT_transform_feedback" ],
   [ "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", "CONTEXT_INT(Const.MaxTransformFeedbackSeparateComponents), extra_EXT_transform_feedback" ],
+
+# GL_EXT_window_rectangles
+  [ "MAX_WINDOW_RECTANGLES_EXT", "CONTEXT_INT(Const.MaxWindowRectangles), extra_EXT_window_rectangles" ],
+  [ "NUM_WINDOW_RECTANGLES_EXT", "CONTEXT_INT(Scissor.NumWindowRects), extra_EXT_window_rectangles" ],
+  [ "WINDOW_RECTANGLE_MODE_EXT", "CONTEXT_ENUM(Scissor.WindowRectMode), extra_EXT_window_rectangles" ],
 ]},
 
 { "apis": ["GLES", "GLES2"], "params": [
index 87e3c0cbf362ab8189a3e0ae6cd23e5879b065f5..7f03c040c40c54e09cdcbe085ee72fa858a0dd65 100644 (file)
@@ -794,6 +794,9 @@ struct gl_scissor_attrib
 {
    GLbitfield EnableFlags;     /**< Scissor test enabled? */
    struct gl_scissor_rect ScissorArray[MAX_VIEWPORTS];
+   GLint NumWindowRects;        /**< Count of enabled window rectangles */
+   GLenum WindowRectMode;       /**< Whether to include or exclude the rects */
+   struct gl_scissor_rect WindowRects[MAX_WINDOW_RECTANGLES];
 };
 
 
@@ -3447,6 +3450,7 @@ struct gl_constants
       GLfloat Min;
       GLfloat Max;
    } ViewportBounds;                         /**< GL_ARB_viewport_array */
+   GLuint MaxWindowRectangles;               /**< GL_EXT_window_rectangles */
 
    struct gl_program_constants Program[MESA_SHADER_STAGES];
    GLuint MaxProgramMatrices;
@@ -3916,6 +3920,7 @@ struct gl_extensions
    GLboolean EXT_transform_feedback;
    GLboolean EXT_timer_query;
    GLboolean EXT_vertex_array_bgra;
+   GLboolean EXT_window_rectangles;
    GLboolean OES_copy_image;
    GLboolean OES_sample_variables;
    GLboolean OES_shader_io_blocks;
index 2b568e4926b18d7fad6258e4cc594fb7a80bf9c5..631ea4d32055accc70d40fb8b30fa48c9e9893bc 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "main/glheader.h"
 #include "main/context.h"
+#include "main/enums.h"
 #include "main/mtypes.h"
 #include "main/scissor.h"
 
@@ -213,7 +214,53 @@ _mesa_ScissorIndexedv(GLuint index, const GLint *v)
 void GLAPIENTRY
 _mesa_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box)
 {
+   int i;
+   struct gl_scissor_rect newval[MAX_WINDOW_RECTANGLES];
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glWindowRectanglesEXT(%s, %d, %p)\n",
+                  _mesa_enum_to_string(mode), count, box);
+
+   if (mode != GL_INCLUSIVE_EXT && mode != GL_EXCLUSIVE_EXT) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glWindowRectanglesEXT(invalid mode 0x%x)", mode);
+      return;
+   }
+
+   if (count < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glWindowRectanglesEXT(count < 0)");
+      return;
+   }
+
+   if (count > ctx->Const.MaxWindowRectangles) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glWindowRectanglesEXT(count >= MaxWindowRectangles (%d)",
+                  ctx->Const.MaxWindowRectangles);
+      return;
+   }
+
+   for (i = 0; i < count; i++) {
+      if (box[2] < 0 || box[3] < 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glWindowRectanglesEXT(box %d: w < 0 || h < 0)", i);
+         return;
+      }
+      newval[i].X = box[0];
+      newval[i].Y = box[1];
+      newval[i].Width = box[2];
+      newval[i].Height = box[3];
+      box += 4;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+   memcpy(ctx->Scissor.WindowRects, newval,
+          sizeof(struct gl_scissor_rect) * count);
+   ctx->Scissor.NumWindowRects = count;
+   ctx->Scissor.WindowRectMode = mode;
 
+   if (ctx->Driver.Scissor)
+      ctx->Driver.Scissor(ctx);
 }
 
 
@@ -228,6 +275,7 @@ _mesa_init_scissor(struct gl_context *ctx)
 
    /* Scissor group */
    ctx->Scissor.EnableFlags = 0;
+   ctx->Scissor.WindowRectMode = GL_EXCLUSIVE_EXT;
 
    /* Note: ctx->Const.MaxViewports may not have been set by the driver yet,
     * so just initialize all of them.