Commit 318c2651 authored by Fritz Koenig's avatar Fritz Koenig Committed by chadversary

mesa: GL_MESA_framebuffer_flip_y extension [v4]

Adds an extension to glFramebufferParameteri
that will specify if the framebuffer is vertically
flipped. Historically system framebuffers are
vertically flipped and user framebuffers are not.
Checking to see the state was done by looking at
the name field.  This adds an explicit field.

v2:
  * updated spec language [for chadv]
  * correctly specifying ES 3.1 [for chadv]
  * refactor access to rb->Name [for jason]
  * handle GetFramebufferParameteriv [for chadv]
v3:
  * correct _mesa_GetMultisamplefv [for kusmabite]
v4:
  * update spec language [for chadv]
  * s/GLboolean/bool/g [for chadv]
  * s/InvertedY/FlipY/g [for chadv]
  * s/inverted_y/flip_y/g [for chadv]
  * assert changes [for chadv]
Reviewed-by: chadversary's avatarChad Versace <chadversary@chromium.org>
parent 7953399e
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)
......@@ -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
......
......@@ -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
......
......@@ -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"/>
......@@ -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);
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
}
}
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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");
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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);