2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include "brw_meta_util.h"
25 #include "main/fbobject.h"
28 * Helper function for handling mirror image blits.
30 * If coord0 > coord1, swap them and invert the "mirror" boolean.
33 fixup_mirroring(bool *mirror
, float *coord0
, float *coord1
)
35 if (*coord0
> *coord1
) {
44 * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of
45 * destination coordinates.
47 * Return true if there is still blitting to do, false if all pixels got
48 * rejected by the clip and/or scissor.
50 * For clarity, the nomenclature of this function assumes we are clipping and
51 * scissoring the X coordinate; the exact same logic applies for Y
54 * Note: this function may also be used to account for clipping of source
55 * coordinates, by swapping the roles of src and dst.
58 clip_or_scissor(bool mirror
,
59 GLfloat
*src_x0
, GLfloat
*src_x1
,
60 GLfloat
*dst_x0
, GLfloat
*dst_x1
,
61 GLfloat fb_xmin
, GLfloat fb_xmax
)
63 float scale
= (float) (*src_x1
- *src_x0
) / (*dst_x1
- *dst_x0
);
64 /* If we are going to scissor everything away, stop. */
65 if (!(fb_xmin
< fb_xmax
&&
72 /* Clip the destination rectangle, and keep track of how many pixels we
73 * clipped off of the left and right sides of it.
75 int pixels_clipped_left
= 0;
76 int pixels_clipped_right
= 0;
77 if (*dst_x0
< fb_xmin
) {
78 pixels_clipped_left
= fb_xmin
- *dst_x0
;
81 if (fb_xmax
< *dst_x1
) {
82 pixels_clipped_right
= *dst_x1
- fb_xmax
;
86 /* If we are mirrored, then before applying pixels_clipped_{left,right} to
87 * the source coordinates, we need to flip them to account for the
91 int tmp
= pixels_clipped_left
;
92 pixels_clipped_left
= pixels_clipped_right
;
93 pixels_clipped_right
= tmp
;
96 /* Adjust the source rectangle to remove the pixels corresponding to those
97 * that were clipped/scissored out of the destination rectangle.
99 *src_x0
+= pixels_clipped_left
* scale
;
100 *src_x1
-= pixels_clipped_right
* scale
;
106 brw_meta_mirror_clip_and_scissor(const struct gl_context
*ctx
,
107 const struct gl_framebuffer
*read_fb
,
108 const struct gl_framebuffer
*draw_fb
,
109 GLfloat
*srcX0
, GLfloat
*srcY0
,
110 GLfloat
*srcX1
, GLfloat
*srcY1
,
111 GLfloat
*dstX0
, GLfloat
*dstY0
,
112 GLfloat
*dstX1
, GLfloat
*dstY1
,
113 bool *mirror_x
, bool *mirror_y
)
118 /* Detect if the blit needs to be mirrored */
119 fixup_mirroring(mirror_x
, srcX0
, srcX1
);
120 fixup_mirroring(mirror_x
, dstX0
, dstX1
);
121 fixup_mirroring(mirror_y
, srcY0
, srcY1
);
122 fixup_mirroring(mirror_y
, dstY0
, dstY1
);
124 /* If the destination rectangle needs to be clipped or scissored, do so. */
125 if (!(clip_or_scissor(*mirror_x
, srcX0
, srcX1
, dstX0
, dstX1
,
126 draw_fb
->_Xmin
, draw_fb
->_Xmax
) &&
127 clip_or_scissor(*mirror_y
, srcY0
, srcY1
, dstY0
, dstY1
,
128 draw_fb
->_Ymin
, draw_fb
->_Ymax
))) {
129 /* Everything got clipped/scissored away, so the blit was successful. */
133 /* If the source rectangle needs to be clipped or scissored, do so. */
134 if (!(clip_or_scissor(*mirror_x
, dstX0
, dstX1
, srcX0
, srcX1
,
135 0, read_fb
->Width
) &&
136 clip_or_scissor(*mirror_y
, dstY0
, dstY1
, srcY0
, srcY1
,
137 0, read_fb
->Height
))) {
138 /* Everything got clipped/scissored away, so the blit was successful. */
142 /* Account for the fact that in the system framebuffer, the origin is at
145 if (_mesa_is_winsys_fbo(read_fb
)) {
146 GLint tmp
= read_fb
->Height
- *srcY0
;
147 *srcY0
= read_fb
->Height
- *srcY1
;
149 *mirror_y
= !*mirror_y
;
151 if (_mesa_is_winsys_fbo(draw_fb
)) {
152 GLint tmp
= draw_fb
->Height
- *dstY0
;
153 *dstY0
= draw_fb
->Height
- *dstY1
;
155 *mirror_y
= !*mirror_y
;