glsl: lower mediump partial derivatives
[mesa.git] / src / mesa / main / viewport.c
index 90c92eadbf639bfa7a3b927df6a0941b00bbc1f0..d8b80aa469f68d4a55dc0f187add48156b30e37a 100644 (file)
@@ -51,9 +51,8 @@ clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y,
     *     determined by calling GetFloatv with the symbolic constant
     *     VIEWPORT_BOUNDS_RANGE (see section 6.1)."
     */
-   if (ctx->Extensions.ARB_viewport_array ||
-       (ctx->Extensions.OES_viewport_array &&
-        _mesa_is_gles31(ctx))) {
+   if (_mesa_has_ARB_viewport_array(ctx) ||
+       _mesa_has_OES_viewport_array(ctx)) {
       *x = CLAMP(*x,
                  ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
       *y = CLAMP(*y,
@@ -94,9 +93,10 @@ static void
 viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width,
          GLsizei height)
 {
+   struct gl_viewport_inputs input = { x, y, width, height };
+
    /* Clamp the viewport to the implementation dependent values. */
-   clamp_viewport(ctx, (GLfloat *)&x, (GLfloat *)&y,
-                  (GLfloat *)&width, (GLfloat *)&height);
+   clamp_viewport(ctx, &input.X, &input.Y, &input.Width, &input.Height);
 
    /* The GL_ARB_viewport_array spec says:
     *
@@ -110,7 +110,7 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width,
     * signal the driver once at the end.
     */
    for (unsigned i = 0; i < ctx->Const.MaxViewports; i++)
-      set_viewport_no_notify(ctx, i, x, y, width, height);
+      set_viewport_no_notify(ctx, i, input.X, input.Y, input.Width, input.Height);
 
    if (ctx->Driver.Viewport)
       ctx->Driver.Viewport(ctx);
@@ -295,8 +295,8 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx,
    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->ViewportArray[idx].Near = SATURATE(nearval);
+   ctx->ViewportArray[idx].Far = SATURATE(farval);
 }
 
 void
@@ -488,17 +488,36 @@ void _mesa_init_viewport(struct gl_context *ctx)
       ctx->ViewportArray[i].Height = 0;
       ctx->ViewportArray[i].Near = 0.0;
       ctx->ViewportArray[i].Far = 1.0;
+      ctx->ViewportArray[i].SwizzleX = GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV;
+      ctx->ViewportArray[i].SwizzleY = GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV;
+      ctx->ViewportArray[i].SwizzleZ = GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV;
+      ctx->ViewportArray[i].SwizzleW = GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV;
    }
+
+   ctx->SubpixelPrecisionBias[0] = 0;
+   ctx->SubpixelPrecisionBias[1] = 0;
 }
 
 
-static void
-clip_control(struct gl_context *ctx, GLenum origin, GLenum depth)
+static ALWAYS_INLINE void
+clip_control(struct gl_context *ctx, GLenum origin, GLenum depth, bool no_error)
 {
    if (ctx->Transform.ClipOrigin == origin &&
        ctx->Transform.ClipDepthMode == depth)
       return;
 
+   if (!no_error &&
+       origin != GL_LOWER_LEFT && origin != GL_UPPER_LEFT) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
+      return;
+   }
+
+   if (!no_error &&
+       depth != GL_NEGATIVE_ONE_TO_ONE && depth != GL_ZERO_TO_ONE) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
+      return;
+   }
+
    /* Affects transform state and the viewport transform */
    FLUSH_VERTICES(ctx, ctx->DriverFlags.NewClipControl ? 0 :
                   _NEW_TRANSFORM | _NEW_VIEWPORT);
@@ -530,7 +549,7 @@ void GLAPIENTRY
 _mesa_ClipControl_no_error(GLenum origin, GLenum depth)
 {
    GET_CURRENT_CONTEXT(ctx);
-   clip_control(ctx, origin, depth);
+   clip_control(ctx, origin, depth, true);
 }
 
 
@@ -551,17 +570,7 @@ _mesa_ClipControl(GLenum origin, GLenum depth)
       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;
-   }
-
-   clip_control(ctx, origin, depth);
+   clip_control(ctx, origin, depth, false);
 }
 
 /**
@@ -597,3 +606,152 @@ _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
       translate[2] = n;
    }
 }
+
+
+static void
+subpixel_precision_bias(struct gl_context *ctx, GLuint xbits, GLuint ybits)
+{
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   FLUSH_VERTICES(ctx, 0);
+
+   ctx->SubpixelPrecisionBias[0] = xbits;
+   ctx->SubpixelPrecisionBias[1] = ybits;
+
+   ctx->NewDriverState |=
+      ctx->DriverFlags.NewNvConservativeRasterizationParams;
+}
+
+void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   subpixel_precision_bias(ctx, xbits, ybits);
+}
+
+void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!ctx->Extensions.NV_conservative_raster) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glSubpixelPrecisionBiasNV not supported");
+      return;
+   }
+
+   if (xbits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
+      return;
+   }
+
+   if (ybits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
+      return;
+   }
+
+   subpixel_precision_bias(ctx, xbits, ybits);
+}
+
+static void
+set_viewport_swizzle(struct gl_context *ctx, GLuint index,
+                     GLenum swizzlex, GLenum swizzley,
+                     GLenum swizzlez, GLenum swizzlew)
+{
+   struct gl_viewport_attrib *viewport = &ctx->ViewportArray[index];
+   if (viewport->SwizzleX == swizzlex &&
+       viewport->SwizzleY == swizzley &&
+       viewport->SwizzleZ == swizzlez &&
+       viewport->SwizzleW == swizzlew)
+      return;
+
+   FLUSH_VERTICES(ctx, _NEW_VIEWPORT);
+   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;
+
+   viewport->SwizzleX = swizzlex;
+   viewport->SwizzleY = swizzley;
+   viewport->SwizzleZ = swizzlez;
+   viewport->SwizzleW = swizzlew;
+}
+
+void GLAPIENTRY
+_mesa_ViewportSwizzleNV_no_error(GLuint index,
+                                 GLenum swizzlex, GLenum swizzley,
+                                 GLenum swizzlez, GLenum swizzlew)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glViewportSwizzleNV(%x, %x, %x, %x)\n",
+                  swizzlex, swizzley, swizzlez, swizzlew);
+
+   set_viewport_swizzle(ctx, index, swizzlex, swizzley, swizzlez, swizzlew);
+}
+
+static bool
+verify_viewport_swizzle(GLenum swizzle)
+{
+   return swizzle >= GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV &&
+      swizzle <= GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV;
+}
+
+void GLAPIENTRY
+_mesa_ViewportSwizzleNV(GLuint index,
+                        GLenum swizzlex, GLenum swizzley,
+                        GLenum swizzlez, GLenum swizzlew)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glViewportSwizzleNV(%x, %x, %x, %x)\n",
+                  swizzlex, swizzley, swizzlez, swizzlew);
+
+   if (!ctx->Extensions.NV_viewport_swizzle) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glViewportSwizzleNV not supported");
+      return;
+   }
+
+   if (index >= ctx->Const.MaxViewports) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glViewportSwizzleNV: index (%d) >= MaxViewports (%d)",
+                  index, ctx->Const.MaxViewports);
+      return;
+   }
+
+   if (!verify_viewport_swizzle(swizzlex)) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glViewportSwizzleNV(swizzlex=%x)", swizzlex);
+      return;
+   }
+
+   if (!verify_viewport_swizzle(swizzley)) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glViewportSwizzleNV(swizzley=%x)", swizzley);
+      return;
+   }
+
+   if (!verify_viewport_swizzle(swizzlez)) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glViewportSwizzleNV(swizzlez=%x)", swizzlez);
+      return;
+   }
+
+   if (!verify_viewport_swizzle(swizzlew)) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glViewportSwizzleNV(swizzlew=%x)", swizzlew);
+      return;
+   }
+
+   set_viewport_swizzle(ctx, index, swizzlex, swizzley, swizzlez, swizzlew);
+}