Commit f3a305b8 authored by Cici Ruan's avatar Cici Ruan

mesa: GL_MESA_framebuffer_prerotate extension

Add an extension to specify the framebuffer rotation value. This is
going to support Android prerotation.
parent 41691ac0
Pipeline #87429 failed with stages
in 44 minutes and 40 seconds
Name
MESA_framebuffer_prerotate
Name Strings
GL_MESA_framebuffer_prerotate
Contact
Cici Ruan <ruanc@chromium.org>
Contributors
Cici Ruan, Google
Fritz Koenig, Google
Rob Clark, Google
Status
Proposal
Version
Version 1, December, 2019
Number
OpenGL ES Extension #??
Dependencies
Requires OpenGL ES 3.2.
Overview
This extension defines a new framebuffer parameter,
GL_FRAMEBUFFER_ROTATION_MESA, that changes the behavior of the reads and
writes to the framebuffer attachment points.
When GL_FRAMEBUFFER_PREROTATE_MESA equals to:
GL_FRAMEBUFFER_PREROTATE_90_MESA
GL_FRAMEBUFFER_PREROTATE_180_MESA
GL_FRAMEBUFFER_PREROTATE_270_MESA
which represents the buffer is in a clockwise rotation, render commands
and pixel transfer operations access the backing store of each attachment
point with a swapped and/or inverted coordinate system. Viewports and
scissors also need to be updated from user coordinates to framebuffer
coordinates.
When GL_FRAMEBUFFER_PREROTATE_MESA equals to
GL_FRAMEBUFFER_PREROTATE_NONE_MESA which means there is no rotation,
the coordinate system may depend on other parameter, such as
GL_FRAMEBUFFER_FLIP_Y_MESA.
Access through TexSubImage2D and similar calls will notice the effect of
the rotation when they are not attached to framebuffer objects because
GL_FRAMEBUFFER_PREROTATE_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_PREROTATE_MESA 0x96B0
Accepted by the <param> argument of FramebufferParameteri and
GetFramebufferParameteriv:
GL_FRAMEBUFFER_PREROTATE_NONE_MESA 0x96B1
GL_FRAMEBUFFER_PREROTATE_90_MESA 0x96B2
GL_FRAMEBUFFER_PREROTATE_180_MESA 0x96B3
GL_FRAMEBUFFER_PREROTATE_270_MESA 0x96B4
Errors
An INVALID_OPERATION error is generated by GetFramebufferParameteriv if
the default framebuffer is bound to <target> and <pname> is
GL_FRAMEBUFFER_PREROTATE_MESA as it only supports OpenGL ES currently.
Revision History
Version 1, December, 2019
Initial draft (Cici Ruan)
......@@ -74,6 +74,13 @@ GL_MESA_tile_raster_order
GL_MESA_framebuffer_flip_y
GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
GL_MESA_framebuffer_prerotate
GL_FRAMEBUFFER_PREROTATE_MESA 0x96B0
GL_FRAMEBUFFER_PREROTATE_NONE_MESA 0x96B1
GL_FRAMEBUFFER_PREROTATE_90_MESA 0x96B2
GL_FRAMEBUFFER_PREROTATE_180_MESA 0x96B3
GL_FRAMEBUFFER_PREROTATE_270_MESA 0x96B4
EGL_MESA_drm_image
EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
EGL_DRM_BUFFER_USE_MESA 0x31D1
......
......@@ -2463,6 +2463,15 @@ GL_APICALL void GL_APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLen
#endif
#endif /* GL_MESA_framebuffer_flip_y */
#ifndef GL_MESA_framebuffer_prerotate
#define GL_MESA_framebuffer_prerotate 1
#define GL_FRAMEBUFFER_PREROTATE_MESA 0x96B0
#define GL_FRAMEBUFFER_PREROTATE_NONE_MESA 0x96B1
#define GL_FRAMEBUFFER_PREROTATE_90_MESA 0x96B2
#define GL_FRAMEBUFFER_PREROTATE_180_MESA 0x96B3
#define GL_FRAMEBUFFER_PREROTATE_270_MESA 0x96B4
#endif /*GL_MESA_framebuffer_prerotate */
#ifndef GL_MESA_program_binary_formats
#define GL_MESA_program_binary_formats 1
#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F
......
......@@ -11376,6 +11376,14 @@ typedef unsigned int GLhandleARB;
<unused start="0x96A4" end="0x96AF" vendor="Qualcomm"/>
</enums>
<enums namespace="GL" start="0x96B0" end="0x96BF" vendor="MESA" comment="framebuffer rotation">
<enum value="0x96B0" name="GL_FRAMEBUFFER_PREROTATE_MESA"/>
<enum value="0x96B1" name="GL_FRAMEBUFFER_PREROTATE_NONE_MESA"/>
<enum value="0x96B2" name="GL_FRAMEBUFFER_PREROTATE_90_MESA"/>
<enum value="0x96B3" name="GL_FRAMEBUFFER_PREROTATE_180_MESA"/>
<enum value="0x96B4" name="GL_FRAMEBUFFER_PREROTATE_270_MESA"/>
</enums>
<!-- Enums reservable for future use. To reserve a new range, allocate one
or more multiples of 16 starting at the lowest available point in this
block and note it in a new <enums> block immediately above.
......@@ -11385,7 +11393,7 @@ typedef unsigned int GLhandleARB;
file) File requests in the Khronos Bugzilla, OpenGL project, Registry
component. -->
<enums namespace="GL" start="0x96B0" end="99999" vendor="ARB" comment="RESERVED FOR FUTURE ALLOCATIONS BY KHRONOS">
<enums namespace="GL" start="0x96C0" end="99999" vendor="ARB" comment="RESERVED FOR FUTURE ALLOCATIONS BY KHRONOS">
<unused start="0x96B0" end="99999" comment="RESERVED"/>
</enums>
......@@ -47433,6 +47441,15 @@ typedef unsigned int GLhandleARB;
<command name="glGetFramebufferParameterivMESA"/>
</require>
</extension>
<extension name="GL_MESA_framebuffer_prerotate" supported="gles2">
<require>
<enum name="GL_FRAMEBUFFER_PREROTATE_MESA"/>
<enum name="GL_FRAMEBUFFER_PREROTATE_NONE_MESA"/>
<enum name="GL_FRAMEBUFFER_PREROTATE_90_MESA"/>
<enum name="GL_FRAMEBUFFER_PREROTATE_180_MESA"/>
<enum name="GL_FRAMEBUFFER_PREROTATE_270_MESA"/>
</require>
</extension>
<extension name="GL_MESA_pack_invert" supported="gl">
<require>
<enum name="GL_PACK_INVERT_MESA"/>
......@@ -87,7 +87,8 @@ intel_map_renderbuffer(struct gl_context *ctx,
GLbitfield mode,
GLubyte **out_map,
GLint *out_stride,
bool flip_y)
bool flip_y,
enum gl_framebuffer_prerotation rotation)
{
struct intel_context *intel = intel_context(ctx);
struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
......@@ -98,6 +99,9 @@ intel_map_renderbuffer(struct gl_context *ctx,
/* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
assert((rb->Name == 0) == flip_y);
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(rotation == GL_FRAMEBUFFER_PREROTATE_NONE);
if (srb->Buffer) {
/* this is a malloc'd renderbuffer (accum buffer), not an irb */
GLint bpp = _mesa_get_format_bytes(rb->Format);
......
......@@ -698,6 +698,10 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
int width, int height)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb);
struct intel_texture_image *intel_image = intel_texture_image(dst_image);
......@@ -1187,6 +1191,9 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
bool partial_clear, bool encode_srgb)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(fb->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
uint32_t x0, x1, y0, y1;
......@@ -1368,6 +1375,10 @@ brw_blorp_clear_depth_stencil(struct brw_context *brw,
GLbitfield mask, bool partial_clear)
{
const struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(fb->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct gl_renderbuffer *depth_rb =
fb->Attachment[BUFFER_DEPTH].Renderbuffer;
struct gl_renderbuffer *stencil_rb =
......
......@@ -1106,6 +1106,9 @@ brw_draw_prims(struct gl_context *ctx,
unsigned stream,
struct gl_buffer_object *indirect)
{
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
unsigned i;
struct brw_context *brw = brw_context(ctx);
int predicate_state = brw->predicate.state;
......
......@@ -103,6 +103,9 @@ genX(upload_polygon_stipple)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
/* _NEW_POLYGON */
if (!ctx->Polygon.StippleFlag)
return;
......@@ -142,6 +145,9 @@ genX(upload_polygon_stipple_offset)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
/* _NEW_POLYGON */
if (!ctx->Polygon.StippleFlag)
return;
......@@ -1512,6 +1518,10 @@ static void
genX(upload_sf)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
float point_size;
#if GEN_GEN <= 7
......@@ -2363,6 +2373,10 @@ static void
genX(upload_scissor_state)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
const bool flip_y = ctx->DrawBuffer->FlipY;
struct GENX(SCISSOR_RECT) scissor;
uint32_t scissor_state_offset;
......@@ -2416,6 +2430,10 @@ static void
genX(upload_sf_clip_viewport)(struct brw_context *brw)
{
struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
float y_scale, y_bias;
/* BRW_NEW_VIEWPORT_COUNT */
......@@ -3484,6 +3502,9 @@ genX(upload_sbe)(struct brw_context *brw)
sbe.AttributeSwizzleEnable = true;
sbe.NumberofSFOutputAttributes = wm_prog_data->num_varying_inputs;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
/* _NEW_BUFFERS */
bool flip_y = ctx->DrawBuffer->FlipY;
......@@ -4532,6 +4553,9 @@ static void
genX(upload_raster)(struct brw_context *brw)
{
const struct gl_context *ctx = &brw->ctx;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
/* _NEW_BUFFERS */
const bool flip_y = ctx->DrawBuffer->FlipY;
......
......@@ -106,7 +106,8 @@ intel_map_renderbuffer(struct gl_context *ctx,
GLbitfield mode,
GLubyte **out_map,
GLint *out_stride,
bool flip_y)
bool flip_y,
enum gl_framebuffer_prerotation rotation)
{
struct brw_context *brw = brw_context(ctx);
struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
......@@ -115,6 +116,9 @@ intel_map_renderbuffer(struct gl_context *ctx,
void *map;
ptrdiff_t stride;
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(rotation == GL_FRAMEBUFFER_PREROTATE_NONE);
if (srb->Buffer) {
/* this is a malloc'd renderbuffer (accum buffer), not an irb */
GLint bpp = _mesa_get_format_bytes(rb->Format);
......@@ -896,6 +900,10 @@ intel_blit_framebuffer(struct gl_context *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(readFb->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE
&& drawFb->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct brw_context *brw = brw_context(ctx);
const struct gen_device_info *devinfo = &brw->screen->devinfo;
......
......@@ -348,6 +348,8 @@ intelBitmap(struct gl_context * ctx,
const struct gl_pixelstore_attrib *unpack,
const GLubyte * pixels)
{
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct brw_context *brw = brw_context(ctx);
if (!_mesa_check_conditional_render(ctx))
......
......@@ -196,6 +196,10 @@ intelCopyPixels(struct gl_context * ctx,
GLsizei width, GLsizei height,
GLint destx, GLint desty, GLenum type)
{
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->ReadBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE
&& ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
struct brw_context *brw = brw_context(ctx);
DBG("%s\n", __func__);
......
......@@ -153,7 +153,8 @@ intelDrawPixels(struct gl_context * ctx,
const GLvoid * pixels)
{
struct brw_context *brw = brw_context(ctx);
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->DrawBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
if (!_mesa_check_conditional_render(ctx))
return;
......
......@@ -258,6 +258,9 @@ intelReadPixels(struct gl_context * ctx,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(ctx->ReadBuffer->PreRotation == GL_FRAMEBUFFER_PREROTATE_NONE);
bool ok;
struct brw_context *brw = brw_context(ctx);
......
......@@ -134,7 +134,8 @@ nouveau_renderbuffer_map(struct gl_context *ctx,
GLbitfield mode,
GLubyte **out_map,
GLint *out_stride,
bool flip_y)
bool flip_y,
enum gl_framebuffer_prerotation rotation)
{
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
GLubyte *map;
......@@ -144,6 +145,9 @@ nouveau_renderbuffer_map(struct gl_context *ctx,
/* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
assert((rb->Name == 0) == flip_y);
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(rotation == GL_FRAMEBUFFER_PREROTATE_NONE);
if (mode & GL_MAP_READ_BIT)
flags |= NOUVEAU_BO_RD;
if (mode & GL_MAP_WRITE_BIT)
......
......@@ -55,7 +55,8 @@ 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,
bool flip_y)
bool flip_y,
enum gl_framebuffer_prerotation rotation)
{
struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
GLubyte *map;
......@@ -66,7 +67,7 @@ radeon_renderbuffer_map(struct gl_context *ctx,
ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
&map, &stride, flip_y);
&map, &stride, flip_y, rotation);
rrb->base.Map = map;
rrb->base.RowStride = stride;
......@@ -99,7 +100,7 @@ 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,
fb->FlipY);
fb->FlipY, fb->PreRotation);
if (_mesa_is_front_buffer_drawing(fb))
RADEON_CONTEXT(ctx)->front_buffer_dirty = true;
......
......@@ -472,7 +472,7 @@ swrast_map_renderbuffer(struct gl_context *ctx,
GLbitfield mode,
GLubyte **out_map,
GLint *out_stride,
bool flip_y)
bool flip_y, enum gl_framebuffer_prerotation rotation)
{
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
GLubyte *map = xrb->Base.Buffer;
......@@ -482,6 +482,9 @@ swrast_map_renderbuffer(struct gl_context *ctx,
/* driver does not support GL_FRAMEBUFFER_FLIP_Y_MESA */
assert((rb->Name == 0) == flip_y);
/* driver does not support GL_FRAMEBUFFER_PREROTATE_MESA */
assert(rotation == GL_FRAMEBUFFER_PREROTATE_NONE);
if (rb->AllocStorage == swrast_alloc_front_storage) {
__DRIdrawable *dPriv = xrb->dPriv;
__DRIscreen *sPriv = dPriv->driScreenPriv;
......
......@@ -577,7 +577,8 @@ osmesa_MapRenderbuffer(struct gl_context *ctx,
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **mapOut, GLint *rowStrideOut,
bool flip_y)
bool flip_y,
enum gl_framebuffer_prerotation rotation)
{
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
......@@ -605,7 +606,7 @@ osmesa_MapRenderbuffer(struct gl_context *ctx,
}
else {
_swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
mapOut, rowStrideOut, flip_y);
mapOut, rowStrideOut, flip_y, rotation);
}
}
......
......@@ -83,7 +83,8 @@ _mesa_clear_accum_buffer(struct gl_context *ctx)
ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height,
GL_MAP_WRITE_BIT, &accMap, &accRowStride,
ctx->DrawBuffer->FlipY);
ctx->DrawBuffer->FlipY,
ctx->DrawBuffer->PreRotation);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
......@@ -139,7 +140,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,
ctx->DrawBuffer->FlipY);
ctx->DrawBuffer->FlipY,
ctx->DrawBuffer->PreRotation);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
......@@ -209,7 +211,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,
ctx->DrawBuffer->FlipY);
ctx->DrawBuffer->FlipY,
ctx->DrawBuffer->PreRotation);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
return;
......@@ -219,7 +222,8 @@ accum_or_load(struct gl_context *ctx, GLfloat value,
ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
GL_MAP_READ_BIT,
&colorMap, &colorRowStride,
ctx->DrawBuffer->FlipY);
ctx->DrawBuffer->FlipY,
ctx->DrawBuffer->PreRotation);
if (!colorMap) {
ctx->Driver.UnmapRenderbuffer(ctx, accRb);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
......@@ -292,7 +296,8 @@ 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, fb->FlipY);
&accMap, &accRowStride, fb->FlipY,
fb->PreRotation);
if (!accMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
return;
......@@ -313,7 +318,7 @@ accum_return(struct gl_context *ctx, GLfloat value,
/* Map color buffer */
ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height,
mappingFlags, &colorMap, &colorRowStride,
fb->FlipY);
fb->FlipY, fb->PreRotation);
if (!colorMap) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum");
continue;
......
......@@ -430,7 +430,7 @@ struct dd_function_table {
GLuint x, GLuint y, GLuint w, GLuint h,
GLbitfield mode,
GLubyte **mapOut, GLint *rowStrideOut,
bool flip_y);
bool flip_y, enum gl_framebuffer_prerotation Rotation);
void (*UnmapRenderbuffer)(struct gl_context *ctx,
struct gl_renderbuffer *rb);
......
......@@ -359,6 +359,9 @@ EXT(KHR_texture_compression_astc_ldr , KHR_texture_compression_astc_ldr
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 , 43, 43, x , 30, 2018)
EXT(MESA_framebuffer_prerotate , MESA_framebuffer_prerotate , x, x, x , 32, 2019)
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)
......
......@@ -1552,6 +1552,11 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
goto invalid_pname_enum;
cannot_be_winsys_fbo = true;
break;
case GL_FRAMEBUFFER_PREROTATE_MESA:
if (!_mesa_is_gles32(ctx) || !ctx->Extensions.MESA_framebuffer_prerotate)
goto invalid_pname_enum;
cannot_be_winsys_fbo = true;
break;
default:
goto invalid_pname_enum;
}
......@@ -1607,6 +1612,22 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_FRAMEBUFFER_FLIP_Y_MESA:
fb->FlipY = param;
break;
case GL_FRAMEBUFFER_PREROTATE_MESA:
switch (param) {
case GL_FRAMEBUFFER_PREROTATE_NONE_MESA:
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_NONE;
case GL_FRAMEBUFFER_PREROTATE_90_MESA:
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_90;
case GL_FRAMEBUFFER_PREROTATE_180_MESA:
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_180;
case GL_FRAMEBUFFER_PREROTATE_270_MESA:
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_270;
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE, "%s", func);
break;
}
break;
}
switch (pname) {
......@@ -1739,6 +1760,10 @@ validate_get_framebuffer_parameteriv_pname(struct gl_context *ctx,
return false;
}
break;
case GL_FRAMEBUFFER_PREROTATE_MESA:
if (!_mesa_is_gles32(ctx) || !ctx->Extensions.MESA_framebuffer_prerotate)
goto invalid_pname_enum;
break;
default:
goto invalid_pname_enum;
}
......@@ -1806,6 +1831,9 @@ get_framebuffer_parameteriv(struct gl_context *ctx, struct gl_framebuffer *fb,
case GL_FRAMEBUFFER_FLIP_Y_MESA:
*params = fb->FlipY;
break;
case GL_FRAMEBUFFER_PREROTATE_MESA:
*params = fb->PreRotation;
break;
}
}
......
......@@ -160,6 +160,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
fb->_HasSNormOrFloatColorBuffer = visual->floatMode;
fb->_HasAttachments = true;
fb->FlipY = true;
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_NONE;
fb->SampleLocationTable = NULL;
fb->ProgrammableSampleLocations = 0;
......@@ -191,6 +192,7 @@ _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
fb->SampleLocationTable = NULL;
fb->ProgrammableSampleLocations = 0;
fb->SampleLocationPixelGrid = 0;
fb->PreRotation = GL_FRAMEBUFFER_PREROTATE_NONE;
fb->Delete = _mesa_destroy_framebuffer;
simple_mtx_init(&fb->Mutex, mtx_plain);
}
......
......@@ -128,6 +128,14 @@ typedef int GLclampx;
#define GL_HALF_FLOAT_OES 0x8D61
#endif
#ifndef GL_MESA_framebuffer_prerotate
#define GL_FRAMEBUFFER_PREROTATE_MESA 0x96B0
#define GL_FRAMEBUFFER_PREROTATE_NONE_MESA 0x96B1
#define GL_FRAMEBUFFER_PREROTATE_90_MESA 0x96B2
#define GL_FRAMEBUFFER_PREROTATE_180_MESA 0x96B3
#define GL_FRAMEBUFFER_PREROTATE_270_MESA 0x96B4
#endif /*GL_MESA_framebuffer_prerotate */
/* There is no formal spec for the following extension. */
#ifndef GL_ATI_texture_compression_3dc
#define GL_ATI_texture_compression_3dc 1
......
......@@ -3441,6 +3441,14 @@ struct gl_renderbuffer_attachment
GLboolean Layered;
};
/* clockwise degree */
enum gl_framebuffer_prerotation
{
GL_FRAMEBUFFER_PREROTATE_NONE = 0,
GL_FRAMEBUFFER_PREROTATE_90,
GL_FRAMEBUFFER_PREROTATE_180,
GL_FRAMEBUFFER_PREROTATE_270
};
/**
* A framebuffer is a collection of renderbuffers (color, depth, stencil, etc).
......@@ -3565,6 +3573,9 @@ struct gl_framebuffer
/* GL_MESA_framebuffer_flip_y */
bool FlipY;
/* GL_MESA_framebuffer_prerotate */
enum gl_framebuffer_prerotation PreRotation;
/** Delete this framebuffer */
void (*Delete)(struct gl_framebuffer *fb);
......@@ -4367,6 +4378,7 @@ struct gl_extensions
GLboolean KHR_texture_compression_astc_ldr;
GLboolean KHR_texture_compression_astc_sliced_3d;
GLboolean MESA_framebuffer_flip_y;
GLboolean MESA_framebuffer_prerotate;
GLboolean MESA_tile_raster_order;
GLboolean MESA_pack_invert;
GLboolean EXT_shader_framebuffer_fetch;
......
......@@ -234,7 +234,8 @@ 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, ctx->ReadBuffer->FlipY);
&map, &stride, ctx->ReadBuffer->FlipY,
ctx->DrawBuffer->PreRotation);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return GL_TRUE; /* don't bother trying the slow path */
......@@ -285,7 +286,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, fb->FlipY);