X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fviewport.c;h=d8b80aa469f68d4a55dc0f187add48156b30e37a;hb=11929895332213363628d632f7f9f6d79b5124d1;hp=cf2ace0b497b7d24a77cde3a70f3e2d68cdb7f23;hpb=ddc32537d6db69198e88ef0dfe19770bf9daa536;p=mesa.git diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index cf2ace0b497..d8b80aa469f 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -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 @@ -359,10 +359,30 @@ _mesa_DepthRangef(GLclampf nearval, GLclampf farval) * \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); @@ -377,11 +397,7 @@ _mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v) 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 @@ -472,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); @@ -514,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); } @@ -535,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); } /** @@ -581,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); +}