From d1bdc1238a39469e6760758876e8832019795a54 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sat, 11 Jun 2016 16:52:17 -0400 Subject: [PATCH] st/mesa: add support for GL_EXT_window_rectangles MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Nicolai Hähnle --- 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 a49ad953c04..d95153d5fd5 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 fc80adf6f8d..b9d31919474 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 31bb2dd98bf..d5fb94141ca 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 605d5cba9e7..72539df24fc 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_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 */ +}; diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index a05a5aff4c6..be0b1030996 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 362cef46286..d630664704b 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 311ba25c17f..ae3ca7a2033 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 a4f56eac7f8..e3bee60d4d7 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 13b0accfd4d..04f6b1a5a75 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 00000000000..40b8ecc4d26 --- /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 00000000000..4608cb90fcc --- /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.30.2