From 34a3c97fe6d273d68d2ee80386791832824f3211 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathias=20Fr=C3=B6hlich?= Date: Sun, 21 Sep 2014 18:09:22 +0200 Subject: [PATCH] mesa: Implement ARB_clip_control. Implement the mesa parts of ARB_clip_control. So far no driver enables this. v3: Restrict getting clip control state to the availability of ARB_clip_control. Move to transformation state. Handle clip control state with the GL_TRANSFORM_BIT. Move _FrontBit update into state.c. Reviewed-by: Brian Paul Signed-off-by: Mathias Froehlich --- src/mapi/glapi/gen/ARB_clip_control.xml | 25 ++++++++ src/mapi/glapi/gen/gl_API.xml | 4 +- src/mesa/main/attrib.c | 1 + src/mesa/main/dlist.c | 26 +++++++++ src/mesa/main/extensions.c | 1 + src/mesa/main/get.c | 1 + src/mesa/main/get_hash_params.py | 2 + src/mesa/main/mtypes.h | 4 ++ src/mesa/main/polygon.c | 2 - src/mesa/main/state.c | 16 +++++ src/mesa/main/tests/dispatch_sanity.cpp | 3 + src/mesa/main/viewport.c | 78 +++++++++++++++++++++++-- src/mesa/main/viewport.h | 3 + 13 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 src/mapi/glapi/gen/ARB_clip_control.xml diff --git a/src/mapi/glapi/gen/ARB_clip_control.xml b/src/mapi/glapi/gen/ARB_clip_control.xml new file mode 100644 index 00000000000..2973a319424 --- /dev/null +++ b/src/mapi/glapi/gen/ARB_clip_control.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml index 73f2f75085e..534e6a0b403 100644 --- a/src/mapi/glapi/gen/gl_API.xml +++ b/src/mapi/glapi/gen/gl_API.xml @@ -8364,7 +8364,9 @@ - + + + diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index d90e6627f43..5345339f6ad 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1345,6 +1345,7 @@ _mesa_PopAttrib(void) if (xform->DepthClamp != ctx->Transform.DepthClamp) _mesa_set_enable(ctx, GL_DEPTH_CLAMP, ctx->Transform.DepthClamp); + _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode); } break; case GL_TEXTURE_BIT: diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 5c7160d0540..4b7b0604bb2 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -398,6 +398,9 @@ typedef enum OPCODE_PROGRAM_UNIFORM_MATRIX34F, OPCODE_PROGRAM_UNIFORM_MATRIX43F, + /* GL_ARB_clip_control */ + OPCODE_CLIP_CONTROL, + /* GL_ARB_color_buffer_float */ OPCODE_CLAMP_COLOR, @@ -7207,6 +7210,22 @@ save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, } } +static void GLAPIENTRY +save_ClipControl(GLenum origin, GLenum depth) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_CLIP_CONTROL, 2); + if (n) { + n[1].e = origin; + n[2].e = depth; + } + if (ctx->ExecuteFlag) { + CALL_ClipControl(ctx->Exec, (origin, depth)); + } +} + static void GLAPIENTRY save_ClampColorARB(GLenum target, GLenum clamp) { @@ -8617,6 +8636,10 @@ execute_list(struct gl_context *ctx, GLuint list) get_pointer(&n[5]))); break; + case OPCODE_CLIP_CONTROL: + CALL_ClipControl(ctx->Exec, (n[1].e, n[2].e)); + break; + case OPCODE_CLAMP_COLOR: CALL_ClampColor(ctx->Exec, (n[1].e, n[2].e)); break; @@ -9551,6 +9574,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_TexParameterIiv(table, save_TexParameterIiv); SET_TexParameterIuiv(table, save_TexParameterIuiv); + /* GL_ARB_clip_control */ + SET_ClipControl(table, save_ClipControl); + /* GL_ARB_color_buffer_float */ SET_ClampColor(table, save_ClampColorARB); diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index f0e2f89e494..15d66a74425 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -91,6 +91,7 @@ static const struct extension extension_table[] = { { "GL_ARB_buffer_storage", o(ARB_buffer_storage), GL, 2013 }, { "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 }, { "GL_ARB_clear_texture", o(ARB_clear_texture), GL, 2013 }, + { "GL_ARB_clip_control", o(ARB_clip_control), GL, 2014 }, { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 }, { "GL_ARB_compressed_texture_pixel_storage", o(dummy_true), GL, 2011 }, { "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 }, diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 0e2d8f687b3..6091efc7fb8 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -391,6 +391,7 @@ EXTRA_EXT(ARB_gpu_shader5); EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5); EXTRA_EXT(INTEL_performance_query); EXTRA_EXT(ARB_explicit_uniform_location); +EXTRA_EXT(ARB_clip_control); static const int extra_ARB_color_buffer_float_or_glcore[] = { diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index da3568469d7..aa9f282d821 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -414,6 +414,8 @@ descriptor=[ [ "AUX_BUFFERS", "BUFFER_INT(Visual.numAuxBuffers), NO_EXTRA" ], [ "BLUE_BIAS", "CONTEXT_FLOAT(Pixel.BlueBias), NO_EXTRA" ], [ "BLUE_SCALE", "CONTEXT_FLOAT(Pixel.BlueScale), NO_EXTRA" ], + [ "CLIP_DEPTH_MODE", "CONTEXT_ENUM(Transform.ClipDepthMode), extra_ARB_clip_control" ], + [ "CLIP_ORIGIN", "CONTEXT_ENUM(Transform.ClipOrigin), extra_ARB_clip_control" ], [ "CLIENT_ATTRIB_STACK_DEPTH", "CONTEXT_INT(ClientAttribStackDepth), NO_EXTRA" ], [ "COLOR_MATERIAL_FACE", "CONTEXT_ENUM(Light.ColorMaterialFace), NO_EXTRA" ], [ "COLOR_MATERIAL_PARAMETER", "CONTEXT_ENUM(Light.ColorMaterialMode), NO_EXTRA" ], diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 415d302fcc6..e1f1f1dde44 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1430,6 +1430,9 @@ struct gl_transform_attrib GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ GLboolean DepthClamp; /**< GL_ARB_depth_clamp */ + /** GL_ARB_clip_control */ + GLenum ClipOrigin; /**< GL_LOWER_LEFT or GL_UPPER_LEFT */ + GLenum ClipDepthMode; /**< GL_NEGATIVE_ONE_TO_ONE or GL_ZERO_TO_ONE */ }; @@ -3698,6 +3701,7 @@ struct gl_extensions GLboolean ARB_blend_func_extended; GLboolean ARB_buffer_storage; GLboolean ARB_clear_texture; + GLboolean ARB_clip_control; GLboolean ARB_color_buffer_float; GLboolean ARB_compute_shader; GLboolean ARB_conditional_render_inverted; diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index 611cef65353..76d601977b1 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -104,8 +104,6 @@ _mesa_FrontFace( GLenum mode ) FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.FrontFace = mode; - ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW); - if (ctx->Driver.FrontFace) ctx->Driver.FrontFace( ctx, mode ); } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 3dbbfaac76c..45bce78fd4a 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -291,6 +291,19 @@ update_viewport_matrix(struct gl_context *ctx) } +/** + * Update the ctx->Polygon._FrontBit flag. + */ +static void +update_frontbit(struct gl_context *ctx) +{ + if (ctx->Transform.ClipOrigin == GL_LOWER_LEFT) + ctx->Polygon._FrontBit = (ctx->Polygon.FrontFace == GL_CW); + else + ctx->Polygon._FrontBit = (ctx->Polygon.FrontFace == GL_CCW); +} + + /** * Update derived multisample state. */ @@ -373,6 +386,9 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) _mesa_update_texture( ctx, new_state ); + if (new_state & _NEW_POLYGON) + update_frontbit( ctx ); + if (new_state & _NEW_BUFFERS) _mesa_update_framebuffer(ctx); diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp index 04fa86b72db..03428dd7281 100644 --- a/src/mesa/main/tests/dispatch_sanity.cpp +++ b/src/mesa/main/tests/dispatch_sanity.cpp @@ -951,6 +951,9 @@ const struct function gl_core_functions_possible[] = { { "glClearTexImage", 13, -1 }, { "glClearTexSubImage", 13, -1 }, + /* GL_ARB_clip_control */ + { "glClipControl", 45, -1 }, + { NULL, 0, -1 } }; diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index afc813dceb7..d6a9e290a4a 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -30,6 +30,7 @@ #include "context.h" +#include "enums.h" #include "macros.h" #include "mtypes.h" #include "viewport.h" @@ -390,6 +391,9 @@ void _mesa_init_viewport(struct gl_context *ctx) GLfloat depthMax = 65535.0F; /* sorf of arbitrary */ unsigned i; + ctx->Transform.ClipOrigin = GL_LOWER_LEFT; + ctx->Transform.ClipDepthMode = GL_NEGATIVE_ONE_TO_ONE; + /* Note: ctx->Const.MaxViewports may not have been set by the driver yet, * so just initialize all of them. */ @@ -424,6 +428,62 @@ void _mesa_free_viewport_data(struct gl_context *ctx) _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap); } +extern void GLAPIENTRY +_mesa_ClipControl(GLenum origin, GLenum depth) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glClipControl(%s, %s)\n", + _mesa_lookup_enum_by_nr(origin), + _mesa_lookup_enum_by_nr(depth)); + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.ARB_clip_control) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glClipControl"); + return; + } + + if (origin != GL_LOWER_LEFT && origin != GL_UPPER_LEFT) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl"); + return; + } + + if (depth != GL_NEGATIVE_ONE_TO_ONE && depth != GL_ZERO_TO_ONE) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl"); + return; + } + + if (ctx->Transform.ClipOrigin == origin && + ctx->Transform.ClipDepthMode == depth) + return; + + FLUSH_VERTICES(ctx, 0); + + if (ctx->Transform.ClipOrigin != origin) { + ctx->Transform.ClipOrigin = origin; + + /* Affects the winding order of the front face. */ + ctx->NewState |= _NEW_POLYGON; + /* Affects the y component of the viewport transform. */ + ctx->NewState |= _NEW_VIEWPORT; + + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + } + + if (ctx->Transform.ClipDepthMode != depth) { + ctx->Transform.ClipDepthMode = depth; + + /* Affects the z part of the viewpoint transform. */ + ctx->NewState |= _NEW_VIEWPORT; + + if (ctx->Driver.DepthRange) + ctx->Driver.DepthRange(ctx); + } +} + /** * Computes the scaling and the translation part of the * viewport transform matrix of the \param i-th viewport @@ -442,8 +502,18 @@ _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i, scale[0] = half_width; translate[0] = half_width + x; - scale[1] = half_height; - translate[1] = half_height + y; - scale[2] = 0.5*(f - n); - translate[2] = 0.5*(n + f); + if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT) { + scale[1] = -half_height; + translate[1] = half_height - y; + } else { + scale[1] = half_height; + translate[1] = half_height + y; + } + if (ctx->Transform.ClipDepthMode == GL_NEGATIVE_ONE_TO_ONE) { + scale[2] = 0.5*(f - n); + translate[2] = 0.5*(n + f); + } else { + scale[2] = f - n; + translate[2] = n; + } } diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h index 514ff1067ff..426e194bd9b 100644 --- a/src/mesa/main/viewport.h +++ b/src/mesa/main/viewport.h @@ -71,6 +71,9 @@ _mesa_init_viewport(struct gl_context *ctx); extern void _mesa_free_viewport_data(struct gl_context *ctx); +extern void GLAPIENTRY +_mesa_ClipControl(GLenum origin, GLenum depth); + extern void _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i, double scale[3], double translate[3]); -- 2.30.2