From: Topi Pohjolainen Date: Tue, 22 Apr 2014 19:11:27 +0000 (+0300) Subject: i965/blorp: Expose coordinate scissoring and mirroring X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3a43cd0c3e611085347f67976a619b915dff07b7;p=mesa.git i965/blorp: Expose coordinate scissoring and mirroring Cc: "10.2" Signed-off-by: Topi Pohjolainen Reviewed-by: Kenneth Graunke --- diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 87c73baeca0..9379fd26122 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -76,6 +76,7 @@ i965_FILES = \ brw_lower_texture_gradients.cpp \ brw_lower_unnormalized_offset.cpp \ brw_meta_updownsample.c \ + brw_meta_util.c \ brw_misc_state.c \ brw_object_purgeable.c \ brw_performance_monitor.c \ diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp index 300ff5c42b7..fe75100d776 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -31,87 +31,10 @@ #include "brw_context.h" #include "brw_blorp_blit_eu.h" #include "brw_state.h" +#include "brw_meta_util.h" #define FILE_DEBUG_FLAG DEBUG_BLORP -/** - * Helper function for handling mirror image blits. - * - * If coord0 > coord1, swap them and invert the "mirror" boolean. - */ -static inline void -fixup_mirroring(bool &mirror, GLfloat &coord0, GLfloat &coord1) -{ - if (coord0 > coord1) { - mirror = !mirror; - GLfloat tmp = coord0; - coord0 = coord1; - coord1 = tmp; - } -} - - -/** - * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of - * destination coordinates. - * - * Return true if there is still blitting to do, false if all pixels got - * rejected by the clip and/or scissor. - * - * For clarity, the nomenclature of this function assumes we are clipping and - * scissoring the X coordinate; the exact same logic applies for Y - * coordinates. - * - * Note: this function may also be used to account for clipping of source - * coordinates, by swapping the roles of src and dst. - */ -static inline bool -clip_or_scissor(bool mirror, GLfloat &src_x0, GLfloat &src_x1, GLfloat &dst_x0, - GLfloat &dst_x1, GLfloat fb_xmin, GLfloat fb_xmax) -{ - float scale = (float) (src_x1 - src_x0) / (dst_x1 - dst_x0); - /* If we are going to scissor everything away, stop. */ - if (!(fb_xmin < fb_xmax && - dst_x0 < fb_xmax && - fb_xmin < dst_x1 && - dst_x0 < dst_x1)) { - return false; - } - - /* Clip the destination rectangle, and keep track of how many pixels we - * clipped off of the left and right sides of it. - */ - GLint pixels_clipped_left = 0; - GLint pixels_clipped_right = 0; - if (dst_x0 < fb_xmin) { - pixels_clipped_left = fb_xmin - dst_x0; - dst_x0 = fb_xmin; - } - if (fb_xmax < dst_x1) { - pixels_clipped_right = dst_x1 - fb_xmax; - dst_x1 = fb_xmax; - } - - /* If we are mirrored, then before applying pixels_clipped_{left,right} to - * the source coordinates, we need to flip them to account for the - * mirroring. - */ - if (mirror) { - GLint tmp = pixels_clipped_left; - pixels_clipped_left = pixels_clipped_right; - pixels_clipped_right = tmp; - } - - /* Adjust the source rectangle to remove the pixels corresponding to those - * that were clipped/scissored out of the destination rectangle. - */ - src_x0 += pixels_clipped_left * scale; - src_x1 -= pixels_clipped_right * scale; - - return true; -} - - static struct intel_mipmap_tree * find_miptree(GLbitfield buffer_bit, struct intel_renderbuffer *irb) { @@ -244,47 +167,12 @@ try_blorp_blit(struct brw_context *brw, const struct gl_framebuffer *read_fb = ctx->ReadBuffer; const struct gl_framebuffer *draw_fb = ctx->DrawBuffer; - /* Detect if the blit needs to be mirrored */ - bool mirror_x = false, mirror_y = false; - fixup_mirroring(mirror_x, srcX0, srcX1); - fixup_mirroring(mirror_x, dstX0, dstX1); - fixup_mirroring(mirror_y, srcY0, srcY1); - fixup_mirroring(mirror_y, dstY0, dstY1); - - /* If the destination rectangle needs to be clipped or scissored, do so. - */ - if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1, - draw_fb->_Xmin, draw_fb->_Xmax) && - clip_or_scissor(mirror_y, srcY0, srcY1, dstY0, dstY1, - draw_fb->_Ymin, draw_fb->_Ymax))) { - /* Everything got clipped/scissored away, so the blit was successful. */ - return true; - } - - /* If the source rectangle needs to be clipped or scissored, do so. */ - if (!(clip_or_scissor(mirror_x, dstX0, dstX1, srcX0, srcX1, - 0, read_fb->Width) && - clip_or_scissor(mirror_y, dstY0, dstY1, srcY0, srcY1, - 0, read_fb->Height))) { - /* Everything got clipped/scissored away, so the blit was successful. */ + bool mirror_x, mirror_y; + if (brw_meta_mirror_clip_and_scissor(ctx, + &srcX0, &srcY0, &srcX1, &srcY1, + &dstX0, &dstY0, &dstX1, &dstY1, + &mirror_x, &mirror_y)) return true; - } - - /* Account for the fact that in the system framebuffer, the origin is at - * the lower left. - */ - if (_mesa_is_winsys_fbo(read_fb)) { - GLint tmp = read_fb->Height - srcY0; - srcY0 = read_fb->Height - srcY1; - srcY1 = tmp; - mirror_y = !mirror_y; - } - if (_mesa_is_winsys_fbo(draw_fb)) { - GLint tmp = draw_fb->Height - dstY0; - dstY0 = draw_fb->Height - dstY1; - dstY1 = tmp; - mirror_y = !mirror_y; - } /* Find buffers */ struct intel_renderbuffer *src_irb; diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.c b/src/mesa/drivers/dri/i965/brw_meta_util.c new file mode 100644 index 00000000000..72ed96ce692 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_meta_util.c @@ -0,0 +1,160 @@ +/* + * Copyright © 2014 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 "brw_meta_util.h" +#include "main/fbobject.h" + +/** + * Helper function for handling mirror image blits. + * + * If coord0 > coord1, swap them and invert the "mirror" boolean. + */ +static inline void +fixup_mirroring(bool *mirror, float *coord0, float *coord1) +{ + if (*coord0 > *coord1) { + *mirror = !*mirror; + float tmp = *coord0; + *coord0 = *coord1; + *coord1 = tmp; + } +} + +/** + * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of + * destination coordinates. + * + * Return true if there is still blitting to do, false if all pixels got + * rejected by the clip and/or scissor. + * + * For clarity, the nomenclature of this function assumes we are clipping and + * scissoring the X coordinate; the exact same logic applies for Y + * coordinates. + * + * Note: this function may also be used to account for clipping of source + * coordinates, by swapping the roles of src and dst. + */ +static inline bool +clip_or_scissor(bool mirror, + GLfloat *src_x0, GLfloat *src_x1, + GLfloat *dst_x0, GLfloat *dst_x1, + GLfloat fb_xmin, GLfloat fb_xmax) +{ + float scale = (float) (*src_x1 - *src_x0) / (*dst_x1 - *dst_x0); + /* If we are going to scissor everything away, stop. */ + if (!(fb_xmin < fb_xmax && + *dst_x0 < fb_xmax && + fb_xmin < *dst_x1 && + *dst_x0 < *dst_x1)) { + return false; + } + + /* Clip the destination rectangle, and keep track of how many pixels we + * clipped off of the left and right sides of it. + */ + int pixels_clipped_left = 0; + int pixels_clipped_right = 0; + if (*dst_x0 < fb_xmin) { + pixels_clipped_left = fb_xmin - *dst_x0; + *dst_x0 = fb_xmin; + } + if (fb_xmax < *dst_x1) { + pixels_clipped_right = *dst_x1 - fb_xmax; + *dst_x1 = fb_xmax; + } + + /* If we are mirrored, then before applying pixels_clipped_{left,right} to + * the source coordinates, we need to flip them to account for the + * mirroring. + */ + if (mirror) { + int tmp = pixels_clipped_left; + pixels_clipped_left = pixels_clipped_right; + pixels_clipped_right = tmp; + } + + /* Adjust the source rectangle to remove the pixels corresponding to those + * that were clipped/scissored out of the destination rectangle. + */ + *src_x0 += pixels_clipped_left * scale; + *src_x1 -= pixels_clipped_right * scale; + + return true; +} + +bool +brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx, + GLfloat *srcX0, GLfloat *srcY0, + GLfloat *srcX1, GLfloat *srcY1, + GLfloat *dstX0, GLfloat *dstY0, + GLfloat *dstX1, GLfloat *dstY1, + bool *mirror_x, bool *mirror_y) +{ + const struct gl_framebuffer *read_fb = ctx->ReadBuffer; + const struct gl_framebuffer *draw_fb = ctx->DrawBuffer; + + *mirror_x = false; + *mirror_y = false; + + /* Detect if the blit needs to be mirrored */ + fixup_mirroring(mirror_x, srcX0, srcX1); + fixup_mirroring(mirror_x, dstX0, dstX1); + fixup_mirroring(mirror_y, srcY0, srcY1); + fixup_mirroring(mirror_y, dstY0, dstY1); + + /* If the destination rectangle needs to be clipped or scissored, do so. */ + if (!(clip_or_scissor(*mirror_x, srcX0, srcX1, dstX0, dstX1, + draw_fb->_Xmin, draw_fb->_Xmax) && + clip_or_scissor(*mirror_y, srcY0, srcY1, dstY0, dstY1, + draw_fb->_Ymin, draw_fb->_Ymax))) { + /* Everything got clipped/scissored away, so the blit was successful. */ + return true; + } + + /* If the source rectangle needs to be clipped or scissored, do so. */ + if (!(clip_or_scissor(*mirror_x, dstX0, dstX1, srcX0, srcX1, + 0, read_fb->Width) && + clip_or_scissor(*mirror_y, dstY0, dstY1, srcY0, srcY1, + 0, read_fb->Height))) { + /* Everything got clipped/scissored away, so the blit was successful. */ + return true; + } + + /* Account for the fact that in the system framebuffer, the origin is at + * the lower left. + */ + if (_mesa_is_winsys_fbo(read_fb)) { + GLint tmp = read_fb->Height - *srcY0; + *srcY0 = read_fb->Height - *srcY1; + *srcY1 = tmp; + *mirror_y = !*mirror_y; + } + if (_mesa_is_winsys_fbo(draw_fb)) { + GLint tmp = draw_fb->Height - *dstY0; + *dstY0 = draw_fb->Height - *dstY1; + *dstY1 = tmp; + *mirror_y = !*mirror_y; + } + + return false; +} diff --git a/src/mesa/drivers/dri/i965/brw_meta_util.h b/src/mesa/drivers/dri/i965/brw_meta_util.h new file mode 100644 index 00000000000..ccd8642010c --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_meta_util.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2014 Intel Corporation + * + * 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, sublicense, + * 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 BRW_META_UTIL_H +#define BRW_META_UTIL_H + +#include +#include "main/mtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool +brw_meta_mirror_clip_and_scissor(const struct gl_context *ctx, + GLfloat *srcX0, GLfloat *srcY0, + GLfloat *srcX1, GLfloat *srcY1, + GLfloat *dstX0, GLfloat *dstY0, + GLfloat *dstX1, GLfloat *dstY1, + bool *mirror_x, bool *mirror_y); + +#ifdef __cplusplus +} +#endif + +#endif /* BRW_META_UTIL_H */