* 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,
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:
*
* 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);
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
* \param v pointer to memory containing
* GLclampd near and far clip-plane values
*/
+static ALWAYS_INLINE void
+depth_range_arrayv(struct gl_context *ctx, GLuint first, GLsizei count,
+ const struct gl_depthrange_inputs *const inputs)
+{
+ for (GLsizei i = 0; i < count; i++)
+ set_depth_range_no_notify(ctx, i + first, inputs[i].Near, inputs[i].Far);
+
+ if (ctx->Driver.DepthRange)
+ ctx->Driver.DepthRange(ctx);
+}
+
+void GLAPIENTRY
+_mesa_DepthRangeArrayv_no_error(GLuint first, GLsizei count, const GLclampd *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ const struct gl_depthrange_inputs *const p =
+ (struct gl_depthrange_inputs *)v;
+ depth_range_arrayv(ctx, first, count, p);
+}
+
void GLAPIENTRY
_mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v)
{
- int i;
const struct gl_depthrange_inputs *const p =
(struct gl_depthrange_inputs *) v;
GET_CURRENT_CONTEXT(ctx);
return;
}
- for (i = 0; i < count; i++)
- set_depth_range_no_notify(ctx, i + first, p[i].Near, p[i].Far);
-
- if (ctx->Driver.DepthRange)
- ctx->Driver.DepthRange(ctx);
+ depth_range_arrayv(ctx, first, count, p);
}
void GLAPIENTRY
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);
_mesa_ClipControl_no_error(GLenum origin, GLenum depth)
{
GET_CURRENT_CONTEXT(ctx);
- clip_control(ctx, origin, depth);
+ clip_control(ctx, origin, depth, true);
}
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);
}
/**
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);
+}