mesa: add KHR_no_error support for glViewportArrayv()
[mesa.git] / src / mesa / main / viewport.c
index 681e46bfcf71562d82d3cb40d1f5e2030ffdcfbe..af453fd259edc6feaecc7fdd47013ea9637fb7f0 100644 (file)
@@ -40,6 +40,9 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
                        GLfloat x, GLfloat y,
                        GLfloat width, GLfloat height)
 {
+   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT);
+   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;
+
    /* clamp width and height to the implementation dependent range */
    width  = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth);
    height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight);
@@ -52,7 +55,9 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
     *     determined by calling GetFloatv with the symbolic constant
     *     VIEWPORT_BOUNDS_RANGE (see section 6.1)."
     */
-   if (ctx->Extensions.ARB_viewport_array) {
+   if (ctx->Extensions.ARB_viewport_array ||
+       (ctx->Extensions.OES_viewport_array &&
+        _mesa_is_gles31(ctx))) {
       x = CLAMP(x,
                 ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
       y = CLAMP(y,
@@ -69,7 +74,6 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
    ctx->ViewportArray[idx].Width = width;
    ctx->ViewportArray[idx].Y = y;
    ctx->ViewportArray[idx].Height = height;
-   ctx->NewState |= _NEW_VIEWPORT;
 }
 
 struct gl_viewport_inputs {
@@ -151,6 +155,28 @@ _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y,
    }
 }
 
+static void
+viewport_array(struct gl_context *ctx, GLuint first, GLsizei count,
+               const struct gl_viewport_inputs *inputs)
+{
+   for (GLsizei i = 0; i < count; i++) {
+      set_viewport_no_notify(ctx, i + first, inputs[i].X, inputs[i].Y,
+                             inputs[i].Width, inputs[i].Height);
+   }
+
+   if (ctx->Driver.Viewport)
+      ctx->Driver.Viewport(ctx);
+}
+
+void GLAPIENTRY
+_mesa_ViewportArrayv_no_error(GLuint first, GLsizei count, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   const struct gl_viewport_inputs *const p = (struct gl_viewport_inputs *)v;
+   viewport_array(ctx, first, count, p);
+}
+
 void GLAPIENTRY
 _mesa_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
 {
@@ -180,21 +206,13 @@ _mesa_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
       }
    }
 
-   for (i = 0; i < count; i++)
-      set_viewport_no_notify(ctx, i + first,
-                             p[i].X, p[i].Y,
-                             p[i].Width, p[i].Height);
-
-   if (ctx->Driver.Viewport)
-      ctx->Driver.Viewport(ctx);
+   viewport_array(ctx, first, count, p);
 }
 
 static void
-ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
-                 GLfloat w, GLfloat h, const char *function)
+viewport_indexed_err(struct gl_context *ctx, GLuint index, GLfloat x, GLfloat y,
+                     GLfloat w, GLfloat h, const char *function)
 {
-   GET_CURRENT_CONTEXT(ctx);
-
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "%s(%d, %f, %f, %f, %f)\n",
                   function, index, x, y, w, h);
@@ -217,17 +235,35 @@ ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
    _mesa_set_viewport(ctx, index, x, y, w, h);
 }
 
+void GLAPIENTRY
+_mesa_ViewportIndexedf_no_error(GLuint index, GLfloat x, GLfloat y,
+                                GLfloat w, GLfloat h)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_set_viewport(ctx, index, x, y, w, h);
+}
+
 void GLAPIENTRY
 _mesa_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y,
                        GLfloat w, GLfloat h)
 {
-   ViewportIndexedf(index, x, y, w, h, "glViewportIndexedf");
+   GET_CURRENT_CONTEXT(ctx);
+   viewport_indexed_err(ctx, index, x, y, w, h, "glViewportIndexedf");
+}
+
+void GLAPIENTRY
+_mesa_ViewportIndexedfv_no_error(GLuint index, const GLfloat *v)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_set_viewport(ctx, index, v[0], v[1], v[2], v[3]);
 }
 
 void GLAPIENTRY
 _mesa_ViewportIndexedfv(GLuint index, const GLfloat *v)
 {
-   ViewportIndexedf(index, v[0], v[1], v[2], v[3], "glViewportIndexedfv");
+   GET_CURRENT_CONTEXT(ctx);
+   viewport_indexed_err(ctx, index, v[0], v[1], v[2], v[3],
+                        "glViewportIndexedfv");
 }
 
 static void
@@ -238,9 +274,12 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
        ctx->ViewportArray[idx].Far == farval)
       return;
 
+   /* The depth range is needed by program state constants. */
+   FLUSH_VERTICES(ctx, _NEW_VIEWPORT);
+   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;
+
    ctx->ViewportArray[idx].Near = CLAMP(nearval, 0.0, 1.0);
    ctx->ViewportArray[idx].Far = CLAMP(farval, 0.0, 1.0);
-   ctx->NewState |= _NEW_VIEWPORT;
 }
 
 void
@@ -330,6 +369,29 @@ _mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v)
       ctx->Driver.DepthRange(ctx);
 }
 
+void GLAPIENTRY
+_mesa_DepthRangeArrayfvOES(GLuint first, GLsizei count, const GLfloat *v)
+{
+   int i;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glDepthRangeArrayfv %d %d\n", first, count);
+
+   if ((first + count) > ctx->Const.MaxViewports) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glDepthRangeArrayfv: first (%d) + count (%d) >= MaxViewports (%d)",
+                  first, count, ctx->Const.MaxViewports);
+      return;
+   }
+
+   for (i = 0; i < count; i++)
+      set_depth_range_no_notify(ctx, i + first, v[i * 2], v[i * 2 + 1]);
+
+   if (ctx->Driver.DepthRange)
+      ctx->Driver.DepthRange(ctx);
+}
+
 /**
  * Update a single DepthRange
  *
@@ -358,6 +420,12 @@ _mesa_DepthRangeIndexed(GLuint index, GLclampd nearval, GLclampd farval)
    _mesa_set_depth_range(ctx, index, nearval, farval);
 }
 
+void GLAPIENTRY
+_mesa_DepthRangeIndexedfOES(GLuint index, GLfloat nearval, GLfloat farval)
+{
+   _mesa_DepthRangeIndexed(index, nearval, farval);
+}
+
 /** 
  * Initialize the context viewport attribute group.
  * \param ctx  the GL context.
@@ -384,12 +452,54 @@ void _mesa_init_viewport(struct gl_context *ctx)
 }
 
 
-extern void GLAPIENTRY
+static void
+clip_control(struct gl_context *ctx, GLenum origin, GLenum depth)
+{
+   if (ctx->Transform.ClipOrigin == origin &&
+       ctx->Transform.ClipDepthMode == depth)
+      return;
+
+   /* Affects transform state and the viewport transform */
+   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewClipControl ? 0 :
+                  _NEW_TRANSFORM | _NEW_VIEWPORT);
+   ctx->NewDriverState |= ctx->DriverFlags.NewClipControl;
+
+   if (ctx->Transform.ClipOrigin != origin) {
+      ctx->Transform.ClipOrigin = origin;
+
+      /* Affects the winding order of the front face. */
+      if (ctx->DriverFlags.NewPolygonState)
+         ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState;
+      else
+         ctx->NewState |= _NEW_POLYGON;
+
+      if (ctx->Driver.FrontFace)
+         ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
+   }
+
+   if (ctx->Transform.ClipDepthMode != depth) {
+      ctx->Transform.ClipDepthMode = depth;
+
+      if (ctx->Driver.DepthRange)
+         ctx->Driver.DepthRange(ctx);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_ClipControl_no_error(GLenum origin, GLenum depth)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   clip_control(ctx, origin, depth);
+}
+
+
+void GLAPIENTRY
 _mesa_ClipControl(GLenum origin, GLenum depth)
 {
    GET_CURRENT_CONTEXT(ctx);
 
-   if (MESA_VERBOSE&VERBOSE_API)
+   if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glClipControl(%s, %s)\n",
                  _mesa_enum_to_string(origin),
                   _mesa_enum_to_string(depth));
@@ -411,29 +521,7 @@ _mesa_ClipControl(GLenum origin, GLenum depth)
       return;
    }
 
-   if (ctx->Transform.ClipOrigin == origin &&
-       ctx->Transform.ClipDepthMode == depth)
-      return;
-
-   /* Affects transform state and the viewport transform */
-   FLUSH_VERTICES(ctx, _NEW_TRANSFORM | _NEW_VIEWPORT);
-
-   if (ctx->Transform.ClipOrigin != origin) {
-      ctx->Transform.ClipOrigin = origin;
-
-      /* Affects the winding order of the front face. */
-      ctx->NewState |= _NEW_POLYGON;
-
-      if (ctx->Driver.FrontFace)
-         ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
-   }
-
-   if (ctx->Transform.ClipDepthMode != depth) {
-      ctx->Transform.ClipDepthMode = depth;
-
-      if (ctx->Driver.DepthRange)
-         ctx->Driver.DepthRange(ctx);
-   }
+   clip_control(ctx, origin, depth);
 }
 
 /**