summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/state_tracker/st_atom_viewport.c14
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c16
-rw-r--r--src/mesa/state_tracker/st_context.h27
3 files changed, 42 insertions, 15 deletions
diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
index 1307cbb6d2..a70f4c7434 100644
--- a/src/mesa/state_tracker/st_atom_viewport.c
+++ b/src/mesa/state_tracker/st_atom_viewport.c
@@ -39,27 +39,19 @@
* - depthrange
* - window pos/size or FBO size
*/
-static void update_viewport( struct st_context *st )
+static void
+update_viewport( struct st_context *st )
{
GLcontext *ctx = st->ctx;
GLfloat yScale, yBias;
- /* Negate Y scale to flip image vertically.
- * The NDC Y coords prior to viewport transformation are in the range
- * [y=-1=bottom, y=1=top]
- * Hardware window coords are in the range [y=0=top, y=H-1=bottom] where H
- * is the window height.
- * Use the viewport transformation to invert Y.
- */
-
/* _NEW_BUFFERS
*/
- if (ctx->DrawBuffer) {
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
yScale = -1;
yBias = ctx->DrawBuffer->Height ;
}
else {
- /* we won't be rendering anything */
yScale = 1.0;
yBias = 0.0;
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 22abc104e2..98604e5b6b 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -60,7 +60,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
struct pipe_context *pipe = ctx->st->pipe;
GLfloat temp[MAX_WIDTH][4];
const GLbitfield transferOps = ctx->_ImageTransferState;
- GLint i, yInv, dfStride;
+ GLint i, yStep, dfStride;
GLfloat *df;
struct st_renderbuffer *strb;
struct gl_pixelstore_attrib clippedPacking = *pack;
@@ -104,11 +104,19 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
dfStride = 0;
}
+ /* determine bottom-to-top vs. top-to-bottom order */
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ y = strb->Base.Height - 1 - y;
+ yStep = -1;
+ }
+ else {
+ yStep = 1;
+ }
+
/* Do a row at a time to flip image data vertically */
- yInv = strb->Base.Height - 1 - y;
for (i = 0; i < height; i++) {
- strb->surface->get_tile(strb->surface, x, yInv, width, 1, df);
- yInv--;
+ strb->surface->get_tile(strb->surface, x, y, width, 1, df);
+ y += yStep;
df += dfStride;
if (!dfStride) {
/* convert GLfloat to user's format/type */
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 8d82d53133..13843d9b7f 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -118,5 +118,32 @@ extern void st_init_driver_functions(struct dd_function_table *functions);
+#define Y_0_TOP 1
+#define Y_0_BOTTOM 2
+
+static INLINE GLuint
+st_fb_orientation(const struct gl_framebuffer *fb)
+{
+ if (fb && fb->Name == 0) {
+ /* Drawing into a window (on-screen buffer).
+ *
+ * Negate Y scale to flip image vertically.
+ * The NDC Y coords prior to viewport transformation are in the range
+ * [y=-1=bottom, y=1=top]
+ * Hardware window coords are in the range [y=0=top, y=H-1=bottom] where
+ * H is the window height.
+ * Use the viewport transformation to invert Y.
+ */
+ return Y_0_TOP;
+ }
+ else {
+ /* Drawing into user-created FBO (very likely a texture).
+ *
+ * For textures, T=0=Bottom, so by extension Y=0=Bottom for rendering.
+ */
+ return Y_0_BOTTOM;
+ }
+}
+
#endif