[Mesa-dev] [PATCH v3 5/6] st/mesa: add support for GL_EXT_window_rectangles

Ilia Mirkin imirkin at alum.mit.edu
Sun Jun 12 06:37:00 UTC 2016


Make sure to pass the requisite information in draws, blits, and clears
that work on the context's draw buffer.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
 src/mesa/Makefile.sources                 |  2 ++
 src/mesa/state_tracker/st_atom.c          |  1 +
 src/mesa/state_tracker/st_atom.h          |  1 +
 src/mesa/state_tracker/st_atom_scissor.c  | 49 +++++++++++++++++++++++++++++
 src/mesa/state_tracker/st_cb_blit.c       |  5 +++
 src/mesa/state_tracker/st_cb_clear.c      | 17 ++++++++++-
 src/mesa/state_tracker/st_cb_drawpixels.c |  4 +++
 src/mesa/state_tracker/st_context.h       |  5 +++
 src/mesa/state_tracker/st_extensions.c    |  4 +++
 src/mesa/state_tracker/st_scissor.c       | 51 +++++++++++++++++++++++++++++++
 src/mesa/state_tracker/st_scissor.h       | 38 +++++++++++++++++++++++
 11 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 src/mesa/state_tracker/st_scissor.c
 create mode 100644 src/mesa/state_tracker/st_scissor.h

diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index a49ad95..d95153d 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -505,6 +505,8 @@ STATETRACKER_FILES = \
 	state_tracker/st_pbo.h \
 	state_tracker/st_program.c \
 	state_tracker/st_program.h \
+	state_tracker/st_scissor.c \
+	state_tracker/st_scissor.h \
 	state_tracker/st_texture.c \
 	state_tracker/st_texture.h \
 	state_tracker/st_vdpau.c \
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index fc80adf..b9d3191 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -55,6 +55,7 @@ static const struct st_tracked_state *render_atoms[] =
    &st_update_polygon_stipple,
    &st_update_viewport,
    &st_update_scissor,
+   &st_update_window_rectangles,
    &st_update_blend,
    &st_update_vertex_texture,
    &st_update_fragment_texture,
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index 31bb2dd..d5fb941 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -63,6 +63,7 @@ extern const struct st_tracked_state st_update_rasterizer;
 extern const struct st_tracked_state st_update_polygon_stipple;
 extern const struct st_tracked_state st_update_viewport;
 extern const struct st_tracked_state st_update_scissor;
+extern const struct st_tracked_state st_update_window_rectangles;
 extern const struct st_tracked_state st_update_blend;
 extern const struct st_tracked_state st_update_msaa;
 extern const struct st_tracked_state st_update_sample_shading;
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
index 605d5cb..357c4bb 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -99,6 +99,46 @@ update_scissor( struct st_context *st )
       st->pipe->set_scissor_states(st->pipe, 0, ctx->Const.MaxViewports, scissor); /* activate */
 }
 
+static void
+update_window_rectangles(struct st_context *st)
+{
+   struct pipe_scissor_state new_rects[PIPE_MAX_WINDOW_RECTANGLES];
+   const struct gl_context *ctx = st->ctx;
+   const struct gl_scissor_attrib *scissor = &ctx->Scissor;
+   unsigned i;
+   bool changed = false;
+   unsigned num_rects = scissor->NumWindowRects;
+   bool include = scissor->WindowRectMode == GL_INCLUSIVE_EXT;
+
+   if (ctx->DrawBuffer == ctx->WinSysDrawBuffer) {
+      num_rects = 0;
+      include = false;
+   }
+   for (i = 0; i < num_rects; i++) {
+      const struct gl_scissor_rect *rect = &scissor->WindowRects[i];
+      new_rects[i].minx = MAX2(rect->X, 0);
+      new_rects[i].miny = MAX2(rect->Y, 0);
+      new_rects[i].maxx = MAX2(rect->X + rect->Width, 0);
+      new_rects[i].maxy = MAX2(rect->Y + rect->Height, 0);
+   }
+   if (num_rects > 0 && memcmp(new_rects, st->state.window_rects.rects,
+                               num_rects * sizeof(struct pipe_scissor_state))) {
+      memcpy(st->state.window_rects.rects, new_rects,
+             num_rects * sizeof(struct pipe_scissor_state));
+      changed = true;
+   }
+   if (st->state.window_rects.num != num_rects) {
+      st->state.window_rects.num = num_rects;
+      changed = true;
+   }
+   if (st->state.window_rects.include != include) {
+      st->state.window_rects.include = include;
+      changed = true;
+   }
+   if (changed)
+      st->pipe->set_window_rectangle_states(
+            st->pipe, include, num_rects, new_rects);
+}
 
 const struct st_tracked_state st_update_scissor = {
    "st_update_scissor",					/* name */
@@ -108,3 +148,12 @@ const struct st_tracked_state st_update_scissor = {
    },
    update_scissor					/* update */
 };
+
+const struct st_tracked_state st_update_window_rectangles = {
+   "st_update_window_rectangles",			/* name */
+   {							/* dirty */
+      (_NEW_SCISSOR | _NEW_BUFFERS),			/* mesa */
+      0,						/* st */
+   },
+   update_window_rectangles				/* update */
+};
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index a05a5af..be0b103 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -40,6 +40,7 @@
 #include "st_cb_blit.h"
 #include "st_cb_fbo.h"
 #include "st_manager.h"
+#include "st_scissor.h"
 
 #include "util/u_format.h"
 
@@ -117,6 +118,7 @@ st_BlitFramebuffer(struct gl_context *ctx,
                         &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
       return; /* nothing to draw/blit */
    }
+   memset(&blit, 0, sizeof(struct pipe_blit_info));
    blit.scissor_enable =
       (dstX0 != clip.dstX0) ||
       (dstY0 != clip.dstY0) ||
@@ -190,6 +192,9 @@ st_BlitFramebuffer(struct gl_context *ctx,
       blit.src.box.height = srcY0 - srcY1;
    }
 
+   if (drawFB != ctx->WinSysDrawBuffer)
+      st_window_rectangles_to_blit(ctx, &blit);
+
    blit.filter = pFilter;
    blit.render_condition_enable = TRUE;
    blit.alpha_blend = FALSE;
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 362cef4..d630664 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -320,6 +320,18 @@ is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
            (unsigned) ctx->Scissor.ScissorArray[0].Height < rb->Height);
 }
 
+/**
+ * Return if window rectangles must be enabled during the clear.
+ */
+static inline bool
+is_window_rectangle_enabled(struct gl_context *ctx)
+{
+   if (ctx->DrawBuffer == ctx->WinSysDrawBuffer)
+      return false;
+   return ctx->Scissor.NumWindowRects > 0 ||
+      ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT;
+}
+
 
 /**
  * Return if all of the color channels are masked.
@@ -410,6 +422,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
                continue;
 
             if (is_scissor_enabled(ctx, rb) ||
+                is_window_rectangle_enabled(ctx) ||
                 is_color_masked(ctx, colormask_index))
                quad_buffers |= PIPE_CLEAR_COLOR0 << i;
             else
@@ -422,7 +435,8 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
 
       if (strb->surface && ctx->Depth.Mask) {
-         if (is_scissor_enabled(ctx, depthRb))
+         if (is_scissor_enabled(ctx, depthRb) ||
+             is_window_rectangle_enabled(ctx))
             quad_buffers |= PIPE_CLEAR_DEPTH;
          else
             clear_buffers |= PIPE_CLEAR_DEPTH;
@@ -433,6 +447,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
 
       if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
          if (is_scissor_enabled(ctx, stencilRb) ||
+             is_window_rectangle_enabled(ctx) ||
              is_stencil_masked(ctx, stencilRb))
             quad_buffers |= PIPE_CLEAR_STENCIL;
          else
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 311ba25..ae3ca7a 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -60,6 +60,7 @@
 #include "st_draw.h"
 #include "st_format.h"
 #include "st_program.h"
+#include "st_scissor.h"
 #include "st_texture.h"
 
 #include "pipe/p_context.h"
@@ -1394,6 +1395,9 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
          blit.mask = PIPE_MASK_RGBA;
          blit.filter = PIPE_TEX_FILTER_NEAREST;
 
+         if (ctx->DrawBuffer != ctx->WinSysDrawBuffer)
+            st_window_rectangles_to_blit(ctx, &blit);
+
          if (screen->is_format_supported(screen, blit.src.format,
                                          blit.src.resource->target,
                                          blit.src.resource->nr_samples,
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index a4f56ea..e3bee60 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -161,6 +161,11 @@ struct st_context
       struct pipe_framebuffer_state framebuffer;
       struct pipe_scissor_state scissor[PIPE_MAX_VIEWPORTS];
       struct pipe_viewport_state viewport[PIPE_MAX_VIEWPORTS];
+      struct {
+         unsigned num;
+         boolean include;
+         struct pipe_scissor_state rects[PIPE_MAX_WINDOW_RECTANGLES];
+      } window_rects;
       unsigned sample_mask;
 
       GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 13b0acc..04f6b1a 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -460,6 +460,9 @@ void st_init_limits(struct pipe_screen *screen,
     */
    c->MaxFramebufferLayers =
       screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
+
+   c->MaxWindowRectangles =
+      screen->get_param(screen, PIPE_CAP_MAX_WINDOW_RECTANGLES);
 }
 
 
@@ -624,6 +627,7 @@ void st_init_extensions(struct pipe_screen *screen,
       { o(EXT_texture_mirror_clamp),         PIPE_CAP_TEXTURE_MIRROR_CLAMP             },
       { o(EXT_texture_swizzle),              PIPE_CAP_TEXTURE_SWIZZLE                  },
       { o(EXT_transform_feedback),           PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS        },
+      { o(EXT_window_rectangles),            PIPE_CAP_MAX_WINDOW_RECTANGLES            },
 
       { o(AMD_pinned_memory),                PIPE_CAP_RESOURCE_FROM_USER_MEMORY        },
       { o(ATI_meminfo),                      PIPE_CAP_QUERY_MEMORY_INFO                },
diff --git a/src/mesa/state_tracker/st_scissor.c b/src/mesa/state_tracker/st_scissor.c
new file mode 100644
index 0000000..40b8ecc
--- /dev/null
+++ b/src/mesa/state_tracker/st_scissor.c
@@ -0,0 +1,51 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Ilia Mirkin
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "pipe/p_state.h"
+
+#include "st_scissor.h"
+
+void
+st_window_rectangles_to_blit(const struct gl_context *ctx,
+                             struct pipe_blit_info *blit)
+{
+   unsigned i;
+
+   blit->num_window_rectangles = ctx->Scissor.NumWindowRects;
+   blit->window_rectangle_include =
+      ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT;
+   for (i = 0; i < blit->num_window_rectangles; i++) {
+      const struct gl_scissor_rect *src_rect = &ctx->Scissor.WindowRects[i];
+      struct pipe_scissor_state *dst_rect = &blit->window_rectangles[i];
+      dst_rect->minx = MAX2(src_rect->X, 0);
+      dst_rect->miny = MAX2(src_rect->Y, 0);
+      dst_rect->maxx = MAX2(src_rect->X + src_rect->Width, 0);
+      dst_rect->maxy = MAX2(src_rect->Y + src_rect->Height, 0);
+   }
+}
diff --git a/src/mesa/state_tracker/st_scissor.h b/src/mesa/state_tracker/st_scissor.h
new file mode 100644
index 0000000..4608cb9
--- /dev/null
+++ b/src/mesa/state_tracker/st_scissor.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Ilia Mirkin.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef ST_SCISSOR_H
+#define ST_SCISSOR_H
+
+struct gl_context;
+struct pipe_blit_info;
+
+void
+st_window_rectangles_to_blit(const struct gl_context *ctx,
+                             struct pipe_blit_info *blit);
+
+#endif /* ST_SCISSOR_H */
-- 
2.7.3



More information about the mesa-dev mailing list