X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fpolygon.c;h=6eee6948336fceda008f78568c886ecca13fa76f;hb=0ca266025ab309d538ed8c804cb46d2945c6a547;hp=cf5a31d195e98cb474279f32841afa612e24bdee;hpb=96ff2edc73ccf11d4d198ba3665507f73ae4a9f7;p=mesa.git diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index cf5a31d195e..6eee6948336 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -5,7 +5,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -22,14 +21,15 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "glheader.h" -#include "imports.h" + #include "context.h" #include "image.h" #include "enums.h" @@ -50,32 +50,49 @@ * change, flushes the vertices and notifies the driver via * the dd_function_table::CullFace callback. */ -void GLAPIENTRY -_mesa_CullFace( GLenum mode ) +static ALWAYS_INLINE void +cull_face(struct gl_context *ctx, GLenum mode, bool no_error) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode)); - - if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) { - _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" ); + if (ctx->Polygon.CullFaceMode == mode) return; - } - if (ctx->Polygon.CullFaceMode == mode) + if (!no_error && + mode != GL_FRONT && mode != GL_BACK && mode != GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCullFace"); return; + } - FLUSH_VERTICES(ctx, _NEW_POLYGON); + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.CullFaceMode = mode; if (ctx->Driver.CullFace) - ctx->Driver.CullFace( ctx, mode ); + ctx->Driver.CullFace(ctx, mode); +} + + +void GLAPIENTRY +_mesa_CullFace_no_error(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + cull_face(ctx, mode, true); +} + + +void GLAPIENTRY +_mesa_CullFace(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glCullFace %s\n", _mesa_enum_to_string(mode)); + + cull_face(ctx, mode, false); } /** - * Define front- and back-facing + * Define front- and back-facing * * \param mode orientation of front-facing polygons. * @@ -85,29 +102,43 @@ _mesa_CullFace( GLenum mode ) * flushes the vertices and notifies the driver via * the dd_function_table::FrontFace callback. */ -void GLAPIENTRY -_mesa_FrontFace( GLenum mode ) +static ALWAYS_INLINE void +front_face(struct gl_context *ctx, GLenum mode, bool no_error) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode)); - - if (mode!=GL_CW && mode!=GL_CCW) { - _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" ); + if (ctx->Polygon.FrontFace == mode) return; - } - if (ctx->Polygon.FrontFace == mode) + if (!no_error && mode != GL_CW && mode != GL_CCW) { + _mesa_error(ctx, GL_INVALID_ENUM, "glFrontFace"); return; + } - FLUSH_VERTICES(ctx, _NEW_POLYGON); + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.FrontFace = mode; - ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW); - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace( ctx, mode ); + ctx->Driver.FrontFace(ctx, mode); +} + + +void GLAPIENTRY +_mesa_FrontFace_no_error(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + front_face(ctx, mode, true); +} + + +void GLAPIENTRY +_mesa_FrontFace(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glFrontFace %s\n", _mesa_enum_to_string(mode)); + + front_face(ctx, mode, false); } @@ -117,58 +148,70 @@ _mesa_FrontFace( GLenum mode ) * \param face the polygons which \p mode applies to. * \param mode how polygons should be rasterized. * - * \sa glPolygonMode(). - * + * \sa glPolygonMode(). + * * Verifies the parameters and updates gl_polygon_attrib::FrontMode and * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the * driver via the dd_function_table::PolygonMode callback. */ -void GLAPIENTRY -_mesa_PolygonMode( GLenum face, GLenum mode ) +static ALWAYS_INLINE void +polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glPolygonMode %s %s\n", - _mesa_lookup_enum_by_nr(face), - _mesa_lookup_enum_by_nr(mode)); - - if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) { - _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" ); - return; + _mesa_enum_to_string(face), + _mesa_enum_to_string(mode)); + + if (!no_error) { + switch (mode) { + case GL_POINT: + case GL_LINE: + case GL_FILL: + break; + case GL_FILL_RECTANGLE_NV: + if (ctx->Extensions.NV_fill_rectangle) + break; + /* fall-through */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glPolygonMode(mode)"); + return; + } } switch (face) { case GL_FRONT: - if (ctx->API == API_OPENGL_CORE) { + if (!no_error && ctx->API == API_OPENGL_CORE) { _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } if (ctx->Polygon.FrontMode == mode) - return; - FLUSH_VERTICES(ctx, _NEW_POLYGON); + return; + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.FrontMode = mode; break; case GL_FRONT_AND_BACK: - if (ctx->Polygon.FrontMode == mode && - ctx->Polygon.BackMode == mode) - return; - FLUSH_VERTICES(ctx, _NEW_POLYGON); + if (ctx->Polygon.FrontMode == mode && ctx->Polygon.BackMode == mode) + return; + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.FrontMode = mode; ctx->Polygon.BackMode = mode; break; case GL_BACK: - if (ctx->API == API_OPENGL_CORE) { + if (!no_error && ctx->API == API_OPENGL_CORE) { _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } if (ctx->Polygon.BackMode == mode) - return; - FLUSH_VERTICES(ctx, _NEW_POLYGON); + return; + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.BackMode = mode; break; default: - _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); + if (!no_error) + _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } @@ -177,31 +220,19 @@ _mesa_PolygonMode( GLenum face, GLenum mode ) } -/** - * This routine updates the ctx->Polygon.Stipple state. - * If we're getting the stipple data from a PBO, we map the buffer - * in order to access the data. - * In any case, we obey the current pixel unpacking parameters when fetching - * the stipple data. - * - * In the future, this routine should be used as a fallback, called via - * ctx->Driver.PolygonStipple(). We'll have to update all the DRI drivers - * too. - */ -void -_mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern) +void GLAPIENTRY +_mesa_PolygonMode_no_error(GLenum face, GLenum mode) { - pattern = _mesa_map_validate_pbo_source(ctx, 2, - &ctx->Unpack, 32, 32, 1, - GL_COLOR_INDEX, GL_BITMAP, - INT_MAX, pattern, - "glPolygonStipple"); - if (!pattern) - return; + GET_CURRENT_CONTEXT(ctx); + polygon_mode(ctx, face, mode, true); +} - _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack); - _mesa_unmap_pbo_source(ctx, &ctx->Unpack); +void GLAPIENTRY +_mesa_PolygonMode(GLenum face, GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + polygon_mode(ctx, face, mode, false); } @@ -209,16 +240,28 @@ _mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern) * Called by glPolygonStipple. */ void GLAPIENTRY -_mesa_PolygonStipple( const GLubyte *pattern ) +_mesa_PolygonStipple(const GLubyte *pattern) { GET_CURRENT_CONTEXT(ctx); - if (MESA_VERBOSE&VERBOSE_API) + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glPolygonStipple\n"); - FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE); + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonStipple ? 0 : + _NEW_POLYGONSTIPPLE); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonStipple; + + pattern = _mesa_map_validate_pbo_source(ctx, 2, + &ctx->Unpack, 32, 32, 1, + GL_COLOR_INDEX, GL_BITMAP, + INT_MAX, pattern, + "glPolygonStipple"); + if (!pattern) + return; + + _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack); - _mesa_polygon_stipple(ctx, pattern); + _mesa_unmap_pbo_source(ctx, &ctx->Unpack); if (ctx->Driver.PolygonStipple) ctx->Driver.PolygonStipple(ctx, pattern); @@ -255,37 +298,52 @@ _mesa_GetPolygonStipple( GLubyte *dest ) _mesa_GetnPolygonStippleARB(INT_MAX, dest); } - -void GLAPIENTRY -_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +void +_mesa_polygon_offset_clamp(struct gl_context *ctx, + GLfloat factor, GLfloat units, GLfloat clamp) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); - if (ctx->Polygon.OffsetFactor == factor && - ctx->Polygon.OffsetUnits == units) + ctx->Polygon.OffsetUnits == units && + ctx->Polygon.OffsetClamp == clamp) return; - FLUSH_VERTICES(ctx, _NEW_POLYGON); + FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON); + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; ctx->Polygon.OffsetFactor = factor; ctx->Polygon.OffsetUnits = units; + ctx->Polygon.OffsetClamp = clamp; if (ctx->Driver.PolygonOffset) - ctx->Driver.PolygonOffset( ctx, factor, units ); + ctx->Driver.PolygonOffset( ctx, factor, units, clamp ); } - void GLAPIENTRY -_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) +_mesa_PolygonOffset( GLfloat factor, GLfloat units ) { GET_CURRENT_CONTEXT(ctx); - /* XXX mult by DepthMaxF here??? */ - _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF ); + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); + + _mesa_polygon_offset_clamp(ctx, factor, units, 0.0); } +void GLAPIENTRY +_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.ARB_polygon_offset_clamp) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "unsupported function (%s) called", "glPolygonOffsetClamp"); + return; + } + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffsetClamp %f %f %f\n", factor, units, clamp); + + _mesa_polygon_offset_clamp(ctx, factor, units, clamp); +} /**********************************************************************/ /** \name Initialization */ @@ -305,13 +363,13 @@ void _mesa_init_polygon( struct gl_context * ctx ) ctx->Polygon.CullFlag = GL_FALSE; ctx->Polygon.CullFaceMode = GL_BACK; ctx->Polygon.FrontFace = GL_CCW; - ctx->Polygon._FrontBit = 0; ctx->Polygon.FrontMode = GL_FILL; ctx->Polygon.BackMode = GL_FILL; ctx->Polygon.SmoothFlag = GL_FALSE; ctx->Polygon.StippleFlag = GL_FALSE; ctx->Polygon.OffsetFactor = 0.0F; ctx->Polygon.OffsetUnits = 0.0F; + ctx->Polygon.OffsetClamp = 0.0F; ctx->Polygon.OffsetPoint = GL_FALSE; ctx->Polygon.OffsetLine = GL_FALSE; ctx->Polygon.OffsetFill = GL_FALSE;