diff options
-rw-r--r-- | src/mesa/state_tracker/st_atom_viewport.c | 14 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_readpixels.c | 16 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 27 |
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 |