* - 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;
}
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;
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 */
+#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