summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/specs/MESA_framebuffer_flip_y.txt81
-rw-r--r--docs/specs/enums.txt3
-rw-r--r--include/GLES2/gl2ext.h5
-rw-r--r--src/mapi/glapi/registry/gl.xml6
-rw-r--r--src/mesa/drivers/dri/i915/intel_fbo.c6
-rw-r--r--src/mesa/drivers/dri/i965/intel_fbo.c6
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fbo.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c9
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c6
-rw-r--r--src/mesa/drivers/osmesa/osmesa.c5
-rw-r--r--src/mesa/drivers/x11/xm_buffer.c3
-rw-r--r--src/mesa/drivers/x11/xmesaP.h3
-rw-r--r--src/mesa/main/accum.c17
-rw-r--r--src/mesa/main/dd.h3
-rw-r--r--src/mesa/main/extensions_table.h1
-rw-r--r--src/mesa/main/fbobject.c16
-rw-r--r--src/mesa/main/framebuffer.c1
-rw-r--r--src/mesa/main/glheader.h3
-rw-r--r--src/mesa/main/mtypes.h4
-rw-r--r--src/mesa/main/readpix.c20
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c6
-rw-r--r--src/mesa/swrast/s_blit.c17
-rw-r--r--src/mesa/swrast/s_clear.c3
-rw-r--r--src/mesa/swrast/s_copypix.c11
-rw-r--r--src/mesa/swrast/s_depth.c6
-rw-r--r--src/mesa/swrast/s_drawpix.c26
-rw-r--r--src/mesa/swrast/s_renderbuffer.c6
-rw-r--r--src/mesa/swrast/s_renderbuffer.h3
-rw-r--r--src/mesa/swrast/s_stencil.c3
30 files changed, 235 insertions, 56 deletions
diff --git a/docs/specs/MESA_framebuffer_flip_y.txt b/docs/specs/MESA_framebuffer_flip_y.txt
new file mode 100644
index 00000000000..697ab4e75d6
--- /dev/null
+++ b/docs/specs/MESA_framebuffer_flip_y.txt
@@ -0,0 +1,81 @@
+Name
+
+ MESA_framebuffer_flip_y
+
+Name Strings
+
+ GL_MESA_framebuffer_flip_y
+
+Contact
+
+ Fritz Koenig <frkoenig@google.com>
+
+Contributors
+
+ Fritz Koenig, Google
+ Kristian Høgsberg, Google
+ Chad Versace, Google
+
+Status
+
+ Proposal
+
+Version
+
+ Version 1, June 7, 2018
+
+Number
+
+ 302
+
+Dependencies
+
+ OpenGL ES 3.1 is required, for FramebufferParameteri.
+
+Overview
+
+ This extension defines a new framebuffer parameter,
+ GL_FRAMEBUFFER_FLIP_Y_MESA, that changes the behavior of the reads and
+ writes to the framebuffer attachment points. When GL_FRAMEBUFFER_FLIP_Y_MESA
+ is GL_TRUE, render commands and pixel transfer operations access the
+ backing store of each attachment point with an y-inverted coordinate
+ system. This y-inversion is relative to the coordinate system set when
+ GL_FRAMEBUFFER_FLIP_Y_MESA is GL_FALSE.
+
+ Access through TexSubImage2D and similar calls will notice the effect of
+ the flip when they are not attached to framebuffer objects because
+ GL_FRAMEBUFFER_FLIP_Y_MESA is associated with the framebuffer object and
+ not the attachment points.
+
+IP Status
+
+ None
+
+Issues
+
+ None
+
+New Procedures and Functions
+
+ None
+
+New Types
+
+ None
+
+New Tokens
+
+ Accepted by the <pname> argument of FramebufferParameteri and
+ GetFramebufferParameteriv:
+
+ GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+
+Errors
+
+ An INVALID_OPERATION error is generated by GetFramebufferParameteriv if the
+ default framebuffer is bound to <target> and <pname> is FRAMEBUFFER_FLIP_Y_MESA.
+
+Revision History
+
+ Version 1, June, 2018
+ Initial draft (Fritz Koenig)
diff --git a/docs/specs/enums.txt b/docs/specs/enums.txt
index bf3ca9c1762..e1b95ec8746 100644
--- a/docs/specs/enums.txt
+++ b/docs/specs/enums.txt
@@ -71,6 +71,9 @@ GL_MESA_tile_raster_order
GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9
GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA
+GL_MESA_framebuffer_flip_y
+ GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+
EGL_MESA_drm_image
EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
EGL_DRM_BUFFER_USE_MESA 0x31D1
diff --git a/include/GLES2/gl2ext.h b/include/GLES2/gl2ext.h
index a7d19a1fc83..0a93bfb8652 100644
--- a/include/GLES2/gl2ext.h
+++ b/include/GLES2/gl2ext.h
@@ -2334,6 +2334,11 @@ GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint quer
#endif
#endif /* GL_INTEL_performance_query */
+#ifndef GL_MESA_framebuffer_flip_y
+#define GL_MESA_framebuffer_flip_y 1
+#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+#endif /* GL_MESA_framebuffer_flip_y */
+
#ifndef GL_MESA_program_binary_formats
#define GL_MESA_program_binary_formats 1
#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F
diff --git a/src/mapi/glapi/registry/gl.xml b/src/mapi/glapi/registry/gl.xml
index 833478aa515..13882eff7bb 100644
--- a/src/mapi/glapi/registry/gl.xml
+++ b/src/mapi/glapi/registry/gl.xml
@@ -6568,6 +6568,7 @@ typedef unsigned int GLhandleARB;
<enum value="0x8BB5" name="GL_VERTEX_PROGRAM_CALLBACK_MESA"/>
<enum value="0x8BB6" name="GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA"/>
<enum value="0x8BB7" name="GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA"/>
+ <enum value="0x8BBB" name="GL_FRAMEBUFFER_FLIP_Y_MESA"/>
</enums>
<enums namespace="GL" start="0x8BC0" end="0x8BFF" vendor="QCOM" comment="Reassigned from AMD to QCOM">
@@ -44356,6 +44357,11 @@ typedef unsigned int GLhandleARB;
<enum name="GL_TEXTURE_2D_STACK_BINDING_MESAX"/>
</require>
</extension>
+ <extension name="GL_MESA_framebuffer_flip_y" supported="gles2">
+ <require>
+ <enum name="GL_FRAMEBUFFER_FLIP_Y_MESA"/>
+ </require>
+ </extension>
<extension name="GL_MESA_pack_invert" supported="gl">
<require>
<enum name="GL_PACK_INVERT_MESA"/>
diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c
index 827a77f7223..78e2c1e6614 100644
--- a/src/mesa/drivers/dri/i915/intel_fbo.c
+++ b/src/mesa/drivers/dri/i915/intel_fbo.c
@@ -86,7 +86,8 @@ intel_map_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct intel_context *intel = intel_context(ctx);
struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
@@ -94,6 +95,9 @@ intel_map_renderbuffer(struct gl_context *ctx,
void *map;
int stride;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (srb->Buffer) {
/* this is a malloc'd renderbuffer (accum buffer), not an irb */
GLint bpp = _mesa_get_format_bytes(rb->Format);
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.c b/src/mesa/drivers/dri/i965/intel_fbo.c
index fb84b738c08..d370e8bb131 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.c
+++ b/src/mesa/drivers/dri/i965/intel_fbo.c
@@ -105,7 +105,8 @@ intel_map_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct brw_context *brw = brw_context(ctx);
struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
@@ -114,6 +115,9 @@ intel_map_renderbuffer(struct gl_context *ctx,
void *map;
ptrdiff_t stride;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (srb->Buffer) {
/* this is a malloc'd renderbuffer (accum buffer), not an irb */
GLint bpp = _mesa_get_format_bytes(rb->Format);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
index c78d4baa124..77e7be1124c 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
@@ -133,13 +133,17 @@ nouveau_renderbuffer_map(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
GLubyte *map;
int stride;
int flags = 0;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (mode & GL_MAP_READ_BIT)
flags |= NOUVEAU_BO_RD;
if (mode & GL_MAP_WRITE_BIT)
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 37c9c3f094b..439b95bf7b1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -226,7 +226,8 @@ radeon_map_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct radeon_context *const rmesa = RADEON_CONTEXT(ctx);
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
@@ -236,6 +237,9 @@ radeon_map_renderbuffer(struct gl_context *ctx,
int ret;
int src_x, src_y;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (!rrb || !rrb->bo) {
*out_map = NULL;
*out_stride = 0;
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index 648df5cc146..fa5b2d98ff4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -53,7 +53,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void
-radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
+radeon_renderbuffer_map(struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ bool flip_y)
{
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
GLubyte *map;
@@ -64,7 +66,7 @@ radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &map, &stride);
+ &map, &stride, flip_y);
rrb->base.Map = map;
rrb->base.RowStride = stride;
@@ -96,7 +98,8 @@ radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
/* check for render to textures */
for (i = 0; i < BUFFER_COUNT; i++)
- radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer);
+ radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer,
+ fb->FlipY);
if (_mesa_is_front_buffer_drawing(fb))
RADEON_CONTEXT(ctx)->front_buffer_dirty = true;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index a88ece97f3b..4be993a9532 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -470,13 +470,17 @@ swrast_map_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
GLubyte *map = xrb->Base.Buffer;
int cpp = _mesa_get_format_bytes(rb->Format);
int stride = rb->Width * cpp;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (rb->AllocStorage == swrast_alloc_front_storage) {
__DRIdrawable *dPriv = xrb->dPriv;
__DRIscreen *sPriv = dPriv->driScreenPriv;
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c
index 3423eb63236..be683d4583e 100644
--- a/src/mesa/drivers/osmesa/osmesa.c
+++ b/src/mesa/drivers/osmesa/osmesa.c
@@ -573,7 +573,8 @@ osmesa_MapRenderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
- GLubyte **mapOut, GLint *rowStrideOut)
+ GLubyte **mapOut, GLint *rowStrideOut,
+ bool flip_y)
{
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
@@ -601,7 +602,7 @@ osmesa_MapRenderbuffer(struct gl_context *ctx,
}
else {
_swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
- mapOut, rowStrideOut);
+ mapOut, rowStrideOut, flip_y);
}
}
diff --git a/src/mesa/drivers/x11/xm_buffer.c b/src/mesa/drivers/x11/xm_buffer.c
index 97c78145858..0c39029ba01 100644
--- a/src/mesa/drivers/x11/xm_buffer.c
+++ b/src/mesa/drivers/x11/xm_buffer.c
@@ -423,7 +423,8 @@ xmesa_MapRenderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
- GLubyte **mapOut, GLint *rowStrideOut)
+ GLubyte **mapOut, GLint *rowStrideOut,
+ bool flip_y)
{
struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index ff3ddc4ddd0..97f15aba9b3 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -358,7 +358,8 @@ xmesa_MapRenderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
- GLubyte **mapOut, GLint *rowStrideOut);
+ GLubyte **mapOut, GLint *rowStrideOut,
+ bool flip_y);
extern void
xmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb);
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c
index f5ac8a10270..a0a206bea67 100644
--- a/src/mesa/main/accum.c
+++ b/src/mesa/main/accum.c
@@ -82,7 +82,8 @@ _mesa_clear_accum_buffer(struct gl_context *ctx)
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height,
- GL_MAP_WRITE_BIT, &accMap, &accRowStride);
+ GL_MAP_WRITE_BIT, &accMap, &accRowStride,
+ ctx->DrawBuffer->FlipY);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
@@ -137,7 +138,8 @@ accum_scale_or_bias(struct gl_context *ctx, GLfloat value,
ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &accMap, &accRowStride);
+ &accMap, &accRowStride,
+ ctx->DrawBuffer->FlipY);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
@@ -206,7 +208,8 @@ accum_or_load(struct gl_context *ctx, GLfloat value,
/* Map accum buffer */
ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
- mappingFlags, &accMap, &accRowStride);
+ mappingFlags, &accMap, &accRowStride,
+ ctx->DrawBuffer->FlipY);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
return;
@@ -215,7 +218,8 @@ accum_or_load(struct gl_context *ctx, GLfloat value,
/* Map color buffer */
ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
GL_MAP_READ_BIT,
- &colorMap, &colorRowStride);
+ &colorMap, &colorRowStride,
+ ctx->DrawBuffer->FlipY);
if (!colorMap) {
ctx->Driver.UnmapRenderbuffer(ctx, accRb);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
@@ -288,7 +292,7 @@ accum_return(struct gl_context *ctx, GLfloat value,
/* Map accum buffer */
ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height,
GL_MAP_READ_BIT,
- &accMap, &accRowStride);
+ &accMap, &accRowStride, fb->FlipY);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
return;
@@ -308,7 +312,8 @@ accum_return(struct gl_context *ctx, GLfloat value,
/* Map color buffer */
ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
- mappingFlags, &colorMap, &colorRowStride);
+ mappingFlags, &colorMap, &colorRowStride,
+ fb->FlipY);
if (!colorMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
continue;
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 78e99bfa235..f14c3e04e91 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -429,7 +429,8 @@ struct dd_function_table {
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
- GLubyte **mapOut, GLint *rowStrideOut);
+ GLubyte **mapOut, GLint *rowStrideOut,
+ bool flip_y);
void (*UnmapRenderbuffer)(struct gl_context *ctx,
struct gl_renderbuffer *rb);
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index f4f7f01d6e4..3f01896cae7 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -323,6 +323,7 @@ EXT(KHR_texture_compression_astc_hdr , KHR_texture_compression_astc_hdr
EXT(KHR_texture_compression_astc_ldr , KHR_texture_compression_astc_ldr , GLL, GLC, x , ES2, 2012)
EXT(KHR_texture_compression_astc_sliced_3d , KHR_texture_compression_astc_sliced_3d , GLL, GLC, x , ES2, 2015)
+EXT(MESA_framebuffer_flip_y , MESA_framebuffer_flip_y , x, x, x , 31, 2018)
EXT(MESA_pack_invert , MESA_pack_invert , GLL, GLC, x , x , 2002)
EXT(MESA_shader_integer_functions , MESA_shader_integer_functions , GLL, GLC, x , 30, 2016)
EXT(MESA_texture_signed_rgba , EXT_texture_snorm , GLL, GLC, x , x , 2009)
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index fa7a9361dfc..750d7f45e34 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1430,6 +1430,10 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
if (!ctx->Extensions.ARB_sample_locations)
goto invalid_pname_enum;
break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ if (!ctx->Extensions.MESA_framebuffer_flip_y)
+ goto invalid_pname_enum;
+ cannot_be_winsys_fbo = true;
default:
goto invalid_pname_enum;
}
@@ -1482,6 +1486,9 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
fb->SampleLocationPixelGrid = !!param;
break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ fb->FlipY = param;
+ break;
}
switch (pname) {
@@ -1574,6 +1581,12 @@ validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx,
goto invalid_pname_enum;
cannot_be_winsys_fbo = false;
break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ if (!ctx->Extensions.MESA_framebuffer_flip_y) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
+ return false;
+ }
+ break;
default:
goto invalid_pname_enum;
}
@@ -1638,6 +1651,9 @@ get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB:
*params = fb->SampleLocationPixelGrid;
break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ *params = fb->FlipY;
+ break;
}
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 78a80649a04..10dd2fde446 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -159,6 +159,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
fb->_AllColorBuffersFixedPoint = !visual->floatMode;
fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
fb->_HasAttachments = true;
+ fb->FlipY = true;
fb->SampleLocationTable = NULL;
fb->ProgrammableSampleLocations = 0;
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
index 16648820b1b..1a91d543126 100644
--- a/src/mesa/main/glheader.h
+++ b/src/mesa/main/glheader.h
@@ -160,6 +160,9 @@ typedef void *GLeglImageOES;
#define GL_HALF_FLOAT_OES 0x8D61
#endif
+#ifndef GL_MESA_framebuffer_flip_y
+#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+#endif
/**
* Internal token to represent a GLSL shader program (a collection of
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7ef7a3f1106..d71872835d1 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3507,6 +3507,9 @@ struct gl_framebuffer
struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
struct gl_renderbuffer *_ColorReadBuffer;
+ /* GL_MESA_framebuffer_flip_y */
+ bool FlipY;
+
/** Delete this framebuffer */
void (*Delete)(struct gl_framebuffer *fb);
};
@@ -4253,6 +4256,7 @@ struct gl_extensions
GLboolean KHR_texture_compression_astc_hdr;
GLboolean KHR_texture_compression_astc_ldr;
GLboolean KHR_texture_compression_astc_sliced_3d;
+ GLboolean MESA_framebuffer_flip_y;
GLboolean MESA_tile_raster_order;
GLboolean MESA_pack_invert;
GLboolean EXT_shader_framebuffer_fetch;
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index c5fc66988b7..e8c28d86162 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -234,7 +234,7 @@ readpixels_memcpy(struct gl_context *ctx,
format, type, 0, 0);
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
+ &map, &stride, ctx->ReadBuffer->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return GL_TRUE; /* don't bother trying the slow path */
@@ -285,7 +285,7 @@ read_uint_depth_pixels( struct gl_context *ctx,
return GL_FALSE;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
+ &map, &stride, fb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
@@ -343,7 +343,7 @@ read_depth_pixels( struct gl_context *ctx,
GL_DEPTH_COMPONENT, type, 0, 0);
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
+ &map, &stride, fb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
@@ -391,7 +391,7 @@ read_stencil_pixels( struct gl_context *ctx,
return;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
+ &map, &stride, fb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
@@ -462,7 +462,7 @@ read_rgba_pixels( struct gl_context *ctx,
/* Map the source render buffer */
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &rb_stride);
+ &map, &rb_stride, fb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
@@ -652,7 +652,7 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx,
return GL_FALSE;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
- &map, &stride);
+ &map, &stride, fb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return GL_TRUE; /* don't bother trying the slow path */
@@ -692,14 +692,14 @@ fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
return GL_FALSE;
ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
- GL_MAP_READ_BIT, &depthMap, &depthStride);
+ GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
if (!depthMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return GL_TRUE; /* don't bother trying the slow path */
}
ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
- GL_MAP_READ_BIT, &stencilMap, &stencilStride);
+ GL_MAP_READ_BIT, &stencilMap, &stencilStride, fb->FlipY);
if (!stencilMap) {
ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
@@ -756,7 +756,7 @@ slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
* If one buffer, only map it once.
*/
ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
- GL_MAP_READ_BIT, &depthMap, &depthStride);
+ GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY);
if (!depthMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
@@ -765,7 +765,7 @@ slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
if (stencilRb != depthRb) {
ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
GL_MAP_READ_BIT, &stencilMap,
- &stencilStride);
+ &stencilStride, fb->FlipY);
if (!stencilMap) {
ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index b851db64886..698c7046c1a 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -770,7 +770,8 @@ st_MapRenderbuffer(struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
- GLubyte **mapOut, GLint *rowStrideOut)
+ GLubyte **mapOut, GLint *rowStrideOut,
+ bool flip_y)
{
struct st_context *st = st_context(ctx);
struct st_renderbuffer *strb = st_renderbuffer(rb);
@@ -779,6 +780,9 @@ st_MapRenderbuffer(struct gl_context *ctx,
GLuint y2;
GLubyte *map;
+ /* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
+ assert((rb->Name == 0) == flip_y);
+
if (strb->software) {
/* software-allocated renderbuffer (probably an accum buffer) */
if (strb->data) {
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c
index 19fe8484eb9..107e41307ee 100644
--- a/src/mesa/swrast/s_blit.c
+++ b/src/mesa/swrast/s_blit.c
@@ -253,7 +253,7 @@ blit_nearest(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0,
readRb->Width, readRb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &map, &rowStride);
+ &map, &rowStride, readFb->FlipY);
if (!map) {
goto fail_no_memory;
}
@@ -280,14 +280,16 @@ blit_nearest(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, readRb,
srcXpos, srcYpos,
srcWidth, srcHeight,
- GL_MAP_READ_BIT, &srcMap, &srcRowStride);
+ GL_MAP_READ_BIT, &srcMap, &srcRowStride,
+ readFb->FlipY);
if (!srcMap) {
goto fail_no_memory;
}
ctx->Driver.MapRenderbuffer(ctx, drawRb,
dstXpos, dstYpos,
dstWidth, dstHeight,
- GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dstMap, &dstRowStride,
+ drawFb->FlipY);
if (!dstMap) {
ctx->Driver.UnmapRenderbuffer(ctx, readRb);
goto fail_no_memory;
@@ -594,7 +596,8 @@ blit_linear(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, readRb,
0, 0, readRb->Width, readRb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &srcMap, &srcRowStride);
+ &srcMap, &srcRowStride,
+ readFb->FlipY);
if (!srcMap) {
goto fail_no_memory;
}
@@ -609,13 +612,15 @@ blit_linear(struct gl_context *ctx,
*/
ctx->Driver.MapRenderbuffer(ctx, readRb,
0, 0, readRb->Width, readRb->Height,
- GL_MAP_READ_BIT, &srcMap, &srcRowStride);
+ GL_MAP_READ_BIT, &srcMap, &srcRowStride,
+ readFb->FlipY);
if (!srcMap) {
goto fail_no_memory;
}
ctx->Driver.MapRenderbuffer(ctx, drawRb,
0, 0, drawRb->Width, drawRb->Height,
- GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dstMap, &dstRowStride,
+ drawFb->FlipY);
if (!dstMap) {
ctx->Driver.UnmapRenderbuffer(ctx, readRb);
goto fail_no_memory;
diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c
index ddafb67c98f..ef0f6df9d9c 100644
--- a/src/mesa/swrast/s_clear.c
+++ b/src/mesa/swrast/s_clear.c
@@ -66,7 +66,8 @@ clear_rgba_buffer(struct gl_context *ctx, struct gl_renderbuffer *rb,
/* map dest buffer */
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- mapMode, &map, &rowStride);
+ mapMode, &map, &rowStride,
+ ctx->DrawBuffer->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(color)");
return;
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c
index 0dbccc0f61d..d0703fa07a6 100644
--- a/src/mesa/swrast/s_copypix.c
+++ b/src/mesa/swrast/s_copypix.c
@@ -503,7 +503,7 @@ swrast_fast_copy_pixels(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0,
srcRb->Width, srcRb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &map, &rowStride);
+ &map, &rowStride, srcFb->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
return GL_TRUE; /* don't retry with slow path */
@@ -530,14 +530,16 @@ swrast_fast_copy_pixels(struct gl_context *ctx,
/* different src/dst buffers */
ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY,
width, height,
- GL_MAP_READ_BIT, &srcMap, &srcRowStride);
+ GL_MAP_READ_BIT, &srcMap, &srcRowStride,
+ srcFb->FlipY);
if (!srcMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
return GL_TRUE; /* don't retry with slow path */
}
ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY,
width, height,
- GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dstMap, &dstRowStride,
+ dstFb->FlipY);
if (!dstMap) {
ctx->Driver.UnmapRenderbuffer(ctx, srcRb);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
@@ -598,7 +600,8 @@ map_readbuffer(struct gl_context *ctx, GLenum type)
ctx->Driver.MapRenderbuffer(ctx, rb,
0, 0, rb->Width, rb->Height,
GL_MAP_READ_BIT,
- &srb->Map, &srb->RowStride);
+ &srb->Map, &srb->RowStride,
+ fb->FlipY);
return rb;
}
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index ffadc05a732..4b9640d3190 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -570,7 +570,8 @@ _swrast_clear_depth_buffer(struct gl_context *ctx)
}
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- mapMode, &map, &rowStride);
+ mapMode, &map, &rowStride,
+ ctx->DrawBuffer->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
return;
@@ -695,7 +696,8 @@ _swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
}
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- mapMode, &map, &rowStride);
+ mapMode, &map, &rowStride,
+ ctx->DrawBuffer->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
return;
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index f05528d0d27..7ee401b2d4c 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -55,7 +55,8 @@ fast_draw_rgb_ubyte_pixels(struct gl_context *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
+ const GLvoid *pixels,
+ bool flip_y)
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address2d(unpack, pixels, width,
@@ -67,7 +68,8 @@ fast_draw_rgb_ubyte_pixels(struct gl_context *ctx,
GLint dstRowStride;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- GL_MAP_WRITE_BIT, &dst, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dst, &dstRowStride,
+ flip_y);
if (!dst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
@@ -102,7 +104,8 @@ fast_draw_rgba_ubyte_pixels(struct gl_context *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
+ const GLvoid *pixels,
+ bool flip_y)
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address2d(unpack, pixels, width,
@@ -114,7 +117,8 @@ fast_draw_rgba_ubyte_pixels(struct gl_context *ctx,
GLint dstRowStride;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- GL_MAP_WRITE_BIT, &dst, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dst, &dstRowStride,
+ flip_y);
if (!dst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
@@ -151,7 +155,8 @@ fast_draw_generic_pixels(struct gl_context *ctx,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
+ const GLvoid *pixels,
+ bool flip_y)
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address2d(unpack, pixels, width,
@@ -164,7 +169,8 @@ fast_draw_generic_pixels(struct gl_context *ctx,
GLint dstRowStride;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- GL_MAP_WRITE_BIT, &dst, &dstRowStride);
+ GL_MAP_WRITE_BIT, &dst, &dstRowStride,
+ flip_y);
if (!dst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
@@ -197,6 +203,7 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *userUnpack,
const GLvoid *pixels)
{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_pixelstore_attrib unpack;
@@ -228,7 +235,7 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
(rb->Format == MESA_FORMAT_B8G8R8X8_UNORM ||
rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) {
fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height,
- &unpack, pixels);
+ &unpack, pixels, fb->FlipY);
return GL_TRUE;
}
@@ -237,14 +244,15 @@ fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
(rb->Format == MESA_FORMAT_B8G8R8X8_UNORM ||
rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) {
fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height,
- &unpack, pixels);
+ &unpack, pixels, fb->FlipY);
return GL_TRUE;
}
if (_mesa_format_matches_format_and_type(rb->Format, format, type,
ctx->Unpack.SwapBytes, NULL)) {
fast_draw_generic_pixels(ctx, rb, x, y, width, height,
- format, type, &unpack, pixels);
+ format, type, &unpack, pixels,
+ fb->FlipY);
return GL_TRUE;
}
diff --git a/src/mesa/swrast/s_renderbuffer.c b/src/mesa/swrast/s_renderbuffer.c
index f76489c2005..8c97e4e11b4 100644
--- a/src/mesa/swrast/s_renderbuffer.c
+++ b/src/mesa/swrast/s_renderbuffer.c
@@ -180,7 +180,8 @@ _swrast_map_soft_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride)
+ GLint *out_stride,
+ bool flip_y)
{
struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
GLubyte *map = srb->Buffer;
@@ -578,7 +579,8 @@ map_attachment(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, rb,
0, 0, rb->Width, rb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
- &srb->Map, &srb->RowStride);
+ &srb->Map, &srb->RowStride,
+ fb->FlipY);
}
assert(srb->Map);
diff --git a/src/mesa/swrast/s_renderbuffer.h b/src/mesa/swrast/s_renderbuffer.h
index 2595d7c1775..9238d8afa49 100644
--- a/src/mesa/swrast/s_renderbuffer.h
+++ b/src/mesa/swrast/s_renderbuffer.h
@@ -43,7 +43,8 @@ _swrast_map_soft_renderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **out_map,
- GLint *out_stride);
+ GLint *out_stride,
+ bool flip_y);
extern void
_swrast_unmap_soft_renderbuffer(struct gl_context *ctx,
diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c
index 7a4dc45ae86..8ccd5a16442 100644
--- a/src/mesa/swrast/s_stencil.c
+++ b/src/mesa/swrast/s_stencil.c
@@ -579,7 +579,8 @@ _swrast_clear_stencil_buffer(struct gl_context *ctx)
}
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
- mapMode, &map, &rowStride);
+ mapMode, &map, &rowStride,
+ ctx->DrawBuffer->FlipY);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(stencil)");
return;