72ed96ce692a4d961fcd39883593ac1fdd166dc1
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 GLfloat
*srcX0
, GLfloat
*srcY0
,
108 GLfloat
*srcX1
, GLfloat
*srcY1
,
109 GLfloat
*dstX0
, GLfloat
*dstY0
,
110 GLfloat
*dstX1
, GLfloat
*dstY1
,
111 bool *mirror_x
, bool *mirror_y
)
113 const struct gl_framebuffer
*read_fb
= ctx
->ReadBuffer
;
114 const struct gl_framebuffer
*draw_fb
= ctx
->DrawBuffer
;
119 /* Detect if the blit needs to be mirrored */
120 fixup_mirroring(mirror_x
, srcX0
, srcX1
);
121 fixup_mirroring(mirror_x
, dstX0
, dstX1
);
122 fixup_mirroring(mirror_y
, srcY0
, srcY1
);
123 fixup_mirroring(mirror_y
, dstY0
, dstY1
);
125 /* If the destination rectangle needs to be clipped or scissored, do so. */
126 if (!(clip_or_scissor(*mirror_x
, srcX0
, srcX1
, dstX0
, dstX1
,
127 draw_fb
->_Xmin
, draw_fb
->_Xmax
) &&
128 clip_or_scissor(*mirror_y
, srcY0
, srcY1
, dstY0
, dstY1
,
129 draw_fb
->_Ymin
, draw_fb
->_Ymax
))) {
130 /* Everything got clipped/scissored away, so the blit was successful. */
134 /* If the source rectangle needs to be clipped or scissored, do so. */
135 if (!(clip_or_scissor(*mirror_x
, dstX0
, dstX1
, srcX0
, srcX1
,
136 0, read_fb
->Width
) &&
137 clip_or_scissor(*mirror_y
, dstY0
, dstY1
, srcY0
, srcY1
,
138 0, read_fb
->Height
))) {
139 /* Everything got clipped/scissored away, so the blit was successful. */
143 /* Account for the fact that in the system framebuffer, the origin is at
146 if (_mesa_is_winsys_fbo(read_fb
)) {
147 GLint tmp
= read_fb
->Height
- *srcY0
;
148 *srcY0
= read_fb
->Height
- *srcY1
;
150 *mirror_y
= !*mirror_y
;
152 if (_mesa_is_winsys_fbo(draw_fb
)) {
153 GLint tmp
= draw_fb
->Height
- *dstY0
;
154 *dstY0
= draw_fb
->Height
- *dstY1
;
156 *mirror_y
= !*mirror_y
;