st/mesa: add support for GL_EXT_window_rectangles
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 11 Jun 2016 20:52:17 +0000 (16:52 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 18 Jun 2016 17:38:30 +0000 (13:38 -0400)
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@alum.mit.edu>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/mesa/Makefile.sources
src/mesa/state_tracker/st_atom.c
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_scissor.c
src/mesa/state_tracker/st_cb_blit.c
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_extensions.c
src/mesa/state_tracker/st_scissor.c [new file with mode: 0644]
src/mesa/state_tracker/st_scissor.h [new file with mode: 0644]

index a49ad953c041ac4ff6ad6e62f4a9338a7bebd1e4..d95153d5fd5a87c32edd26d676eaf77e84f9cdc3 100644 (file)
@@ -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 \
index fc80adf6f8dc1106e235573c9d0127e5cc50d723..b9d31919474593ebc4b241d67f643e096d805d5c 100644 (file)
@@ -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,
index 31bb2dd98bfb8815cfa19732cc63e63df342d335..d5fb94141caab7cf55f3832aaeb0b1cc0d402fc0 100644 (file)
@@ -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;
index 605d5cba9e7cebac3e14c60b940943fa991e271b..72539df24fc1da03805705da00fda9288ca4ebd5 100644 (file)
@@ -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_rectangles(
+            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 */
+};
index a05a5aff4c6ee2d153c17001e939335965ae5336..be0b103099656e82eaeba6b013321e07ed5ba8cb 100644 (file)
@@ -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;
index 362cef46286c7435fd7f09a1eb0f4f298c05d9bf..d630664704b07d13d6ab79e130ac6f68d2547335 100644 (file)
@@ -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
index 311ba25c17fc00668d2172bb1235e3b92bd98705..ae3ca7a2033d8691bd50dd183c1465a826236273 100644 (file)
@@ -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,
index a4f56eac7f84c523f65446547cd4739b1d855f87..e3bee60d4d70358fd4e23ffcacb1e78c0cd3c3e8 100644 (file)
@@ -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 */
index 13b0accfd4dfd4a4ef02e6b67802aee13f150ae2..04f6b1a5a75eaaac015663c5e2c441ae9a16e0b6 100644 (file)
@@ -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 (file)
index 0000000..40b8ecc
--- /dev/null
@@ -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 (file)
index 0000000..4608cb9
--- /dev/null
@@ -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 */