X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fattrib.c;h=c39412e9fe0ab3cb1140718fab0808e28619d0d3;hb=e5339fe4a47c242693962c9f90bbab8b74935cba;hp=30c815d67f0261a27e29b3aa5bb6f9f624f33c2f;hpb=56c5ba8f92d372f6c36d1746e875bbba09b6b00f;p=mesa.git diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 30c815d67f0..c39412e9fe0 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -24,7 +24,7 @@ */ #include "glheader.h" -#include "imports.h" +#include "util/imports.h" #include "accum.h" #include "arrayobj.h" #include "attrib.h" @@ -32,7 +32,6 @@ #include "buffers.h" #include "bufferobj.h" #include "clear.h" -#include "colormac.h" #include "context.h" #include "depth.h" #include "enable.h" @@ -44,6 +43,7 @@ #include "macros.h" #include "matrix.h" #include "multisample.h" +#include "pixelstore.h" #include "points.h" #include "polygon.h" #include "shared.h" @@ -57,7 +57,7 @@ #include "varray.h" #include "viewport.h" #include "mtypes.h" -#include "main/dispatch.h" +#include "state.h" #include "hash.h" #include @@ -73,7 +73,8 @@ struct gl_enable_attrib GLbitfield ClipPlanes; GLboolean ColorMaterial; GLboolean CullFace; - GLboolean DepthClamp; + GLboolean DepthClampNear; + GLboolean DepthClampFar; GLboolean DepthTest; GLboolean Dither; GLboolean Fog; @@ -112,7 +113,7 @@ struct gl_enable_attrib GLboolean PolygonSmooth; GLboolean PolygonStipple; GLboolean RescaleNormals; - GLboolean Scissor; + GLbitfield Scissor; GLboolean Stencil; GLboolean StencilTwoSide; /* GL_EXT_stencil_two_side */ GLboolean MultisampleEnabled; /* GL_ARB_multisample */ @@ -138,6 +139,9 @@ struct gl_enable_attrib /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ GLboolean sRGBEnabled; + + /* GL_NV_conservative_raster */ + GLboolean ConservativeRasterization; }; @@ -178,6 +182,17 @@ struct texture_state }; +struct viewport_state +{ + struct gl_viewport_attrib ViewportArray[MAX_VIEWPORTS]; + GLuint SubpixelPrecisionBias[2]; +}; + + +/** An unused GL_*_BIT value */ +#define DUMMY_BIT 0x10000000 + + /** * Allocate new attribute node of given type/kind. Attach payload data. * Insert it into the linked list named by 'head'. @@ -217,7 +232,7 @@ push_attrib(struct gl_context *ctx, struct gl_attrib_node **head, { void *attribute; - attribute = MALLOC(attr_size); + attribute = malloc(attr_size); if (attribute == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); return false; @@ -227,7 +242,7 @@ push_attrib(struct gl_context *ctx, struct gl_attrib_node **head, memcpy(attribute, attr_data, attr_size); } else { - FREE(attribute); + free(attribute); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); return false; } @@ -246,7 +261,7 @@ _mesa_PushAttrib(GLbitfield mask) _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask); if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { - _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); + _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushAttrib"); return; } @@ -254,6 +269,15 @@ _mesa_PushAttrib(GLbitfield mask) /* groups specified by the mask. */ head = NULL; + if (mask == 0) { + /* if mask is zero we still need to push something so that we + * don't get a GL_STACK_UNDERFLOW error in glPopAttrib(). + */ + GLuint dummy = 0; + if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy)) + goto end; + } + if (mask & GL_ACCUM_BUFFER_BIT) { if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT, sizeof(struct gl_accum_attrib), @@ -264,7 +288,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_COLOR_BUFFER_BIT) { GLuint i; struct gl_colorbuffer_attrib *attr; - attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); + attr = MALLOC_STRUCT(gl_colorbuffer_attrib); if (attr == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; @@ -277,7 +301,7 @@ _mesa_PushAttrib(GLbitfield mask) attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; } else { - FREE(attr); + free(attr); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; } @@ -301,7 +325,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_ENABLE_BIT) { struct gl_enable_attrib *attr; GLuint i; - attr = MALLOC_STRUCT( gl_enable_attrib ); + attr = MALLOC_STRUCT(gl_enable_attrib); if (attr == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; @@ -314,7 +338,8 @@ _mesa_PushAttrib(GLbitfield mask) attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; attr->CullFace = ctx->Polygon.CullFlag; - attr->DepthClamp = ctx->Transform.DepthClamp; + attr->DepthClampNear = ctx->Transform.DepthClampNear; + attr->DepthClampFar = ctx->Transform.DepthClampFar; attr->DepthTest = ctx->Depth.Test; attr->Dither = ctx->Color.DitherFlag; attr->Fog = ctx->Fog.Enabled; @@ -354,7 +379,7 @@ _mesa_PushAttrib(GLbitfield mask) attr->PolygonSmooth = ctx->Polygon.SmoothFlag; attr->PolygonStipple = ctx->Polygon.StippleFlag; attr->RescaleNormals = ctx->Transform.RescaleNormals; - attr->Scissor = ctx->Scissor.Enabled; + attr->Scissor = ctx->Scissor.EnableFlags; attr->Stencil = ctx->Stencil.Enabled; attr->StencilTwoSide = ctx->Stencil.TestTwoSide; attr->MultisampleEnabled = ctx->Multisample.Enabled; @@ -362,8 +387,8 @@ _mesa_PushAttrib(GLbitfield mask) attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; attr->SampleCoverage = ctx->Multisample.SampleCoverage; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - attr->Texture[i] = ctx->Texture.Unit[i].Enabled; - attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; + attr->Texture[i] = ctx->Texture.FixedFuncUnit[i].Enabled; + attr->TexGen[i] = ctx->Texture.FixedFuncUnit[i].TexGenEnabled; } /* GL_ARB_vertex_program */ attr->VertexProgram = ctx->VertexProgram.Enabled; @@ -374,13 +399,16 @@ _mesa_PushAttrib(GLbitfield mask) attr->FragmentProgram = ctx->FragmentProgram.Enabled; if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) { - FREE(attr); + free(attr); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; } /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ attr->sRGBEnabled = ctx->Color.sRGBEnabled; + + /* GL_NV_conservative_raster */ + attr->ConservativeRasterization = ctx->ConservativeRasterization; } if (mask & GL_EVAL_BIT) { @@ -428,7 +456,7 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_PIXEL_MODE_BIT) { struct gl_pixel_attrib *attr; - attr = MALLOC_STRUCT( gl_pixel_attrib ); + attr = MALLOC_STRUCT(gl_pixel_attrib); if (attr == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; @@ -440,7 +468,7 @@ _mesa_PushAttrib(GLbitfield mask) attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; } else { - FREE(attr); + free(attr); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); goto end; } @@ -491,7 +519,7 @@ _mesa_PushAttrib(GLbitfield mask) } if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) { - FREE(texstate); + free(texstate); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); goto end; } @@ -532,10 +560,23 @@ _mesa_PushAttrib(GLbitfield mask) } if (mask & GL_VIEWPORT_BIT) { - if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT, - sizeof(struct gl_viewport_attrib), - (void*)&ctx->Viewport)) + struct viewport_state *viewstate = CALLOC_STRUCT(viewport_state); + if (!viewstate) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)"); + goto end; + } + + if (!save_attrib_data(&head, GL_VIEWPORT_BIT, viewstate)) { + free(viewstate); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)"); goto end; + } + + memcpy(&viewstate->ViewportArray, &ctx->ViewportArray, + sizeof(struct gl_viewport_attrib)*ctx->Const.MaxViewports); + + viewstate->SubpixelPrecisionBias[0] = ctx->SubpixelPrecisionBias[0]; + viewstate->SubpixelPrecisionBias[1] = ctx->SubpixelPrecisionBias[1]; } /* GL_ARB_multisample */ @@ -561,10 +602,10 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) const GLuint curTexUnitSave = ctx->Texture.CurrentUnit; GLuint i; -#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ - if ((VALUE) != (NEWVALUE)) { \ - _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ - } +#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ + if ((VALUE) != (NEWVALUE)) { \ + _mesa_set_enable(ctx, ENUM, (NEWVALUE)); \ + } TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); if (ctx->Color.BlendEnabled != enable->Blend) { @@ -582,15 +623,25 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) for (i=0;iConst.MaxClipPlanes;i++) { const GLuint mask = 1 << i; if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask)) - _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), - !!(enable->ClipPlanes & mask)); + _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), + !!(enable->ClipPlanes & mask)); } TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, GL_COLOR_MATERIAL); TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); - TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp, - GL_DEPTH_CLAMP); + + if (!ctx->Extensions.AMD_depth_clamp_separate) { + TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar, + enable->DepthClampNear && enable->DepthClampFar, + GL_DEPTH_CLAMP); + } else { + TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear, + GL_DEPTH_CLAMP_NEAR_AMD); + TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar, + GL_DEPTH_CLAMP_FAR_AMD); + } + TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); @@ -658,7 +709,13 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) GL_POLYGON_SMOOTH); TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, GL_POLYGON_STIPPLE); - TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); + if (ctx->Scissor.EnableFlags != enable->Scissor) { + unsigned i; + + for (i = 0; i < ctx->Const.MaxViewports; i++) { + _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (enable->Scissor >> i) & 1); + } + } TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); if (ctx->Extensions.EXT_stencil_two_side) { TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT); @@ -694,12 +751,19 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled, GL_FRAMEBUFFER_SRGB); + /* GL_NV_conservative_raster */ + if (ctx->Extensions.NV_conservative_raster) { + TEST_AND_UPDATE(ctx->ConservativeRasterization, + enable->ConservativeRasterization, + GL_CONSERVATIVE_RASTERIZATION_NV); + } + /* texture unit enables */ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { const GLbitfield enabled = enable->Texture[i]; const GLbitfield genEnabled = enable->TexGen[i]; - if (ctx->Texture.Unit[i].Enabled != enabled) { + if (ctx->Texture.FixedFuncUnit[i].Enabled != enabled) { _mesa_ActiveTexture(GL_TEXTURE0 + i); _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(enabled & TEXTURE_1D_BIT)); @@ -715,7 +779,7 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) } } - if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) { + if (ctx->Texture.FixedFuncUnit[i].TexGenEnabled != genEnabled) { _mesa_ActiveTexture(GL_TEXTURE0 + i); _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(genEnabled & S_BIT)); _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(genEnabled & T_BIT)); @@ -739,7 +803,8 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_lock_context_textures(ctx); for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - const struct gl_texture_unit *unit = &texstate->Texture.Unit[u]; + const struct gl_fixedfunc_texture_unit *unit = + &texstate->Texture.FixedFuncUnit[u]; GLuint tgt; _mesa_ActiveTexture(GL_TEXTURE0_ARB + u); @@ -747,7 +812,7 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(unit->Enabled & TEXTURE_2D_BIT)); _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(unit->Enabled & TEXTURE_3D_BIT)); if (ctx->Extensions.ARB_texture_cube_map) { - _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB, + _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, !!(unit->Enabled & TEXTURE_CUBE_BIT)); } if (ctx->Extensions.NV_texture_rectangle) { @@ -766,7 +831,9 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->GenQ.ObjectPlane); /* Eye plane done differently to avoid re-transformation */ { - struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u]; + struct gl_fixedfunc_texture_unit *destUnit = + &ctx->Texture.FixedFuncUnit[u]; + COPY_4FV(destUnit->GenS.EyePlane, unit->GenS.EyePlane); COPY_4FV(destUnit->GenT.EyePlane, unit->GenT.EyePlane); COPY_4FV(destUnit->GenR.EyePlane, unit->GenR.EyePlane); @@ -783,11 +850,11 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(unit->TexGenEnabled & R_BIT)); _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(unit->TexGenEnabled & Q_BIT)); _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, - unit->LodBias); + texstate->Texture.Unit[u].LodBias); _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, - unit->Combine.ModeRGB); + unit->Combine.ModeRGB); _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, - unit->Combine.ModeA); + unit->Combine.ModeA); { const GLuint n = ctx->Extensions.NV_texture_env_combine4 ? 4 : 3; GLuint i; @@ -803,9 +870,9 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) } } _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, - 1 << unit->Combine.ScaleShiftRGB); + 1 << unit->Combine.ScaleShiftRGB); _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, - 1 << unit->Combine.ScaleShiftA); + 1 << unit->Combine.ScaleShiftA); /* Restore texture object state for each target */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { @@ -818,7 +885,7 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) /* don't restore state for unsupported targets to prevent * raising GL errors. */ - if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB && + if (obj->Target == GL_TEXTURE_CUBE_MAP && !ctx->Extensions.ARB_texture_cube_map) { continue; } @@ -907,7 +974,7 @@ _mesa_PopAttrib(void) FLUSH_VERTICES(ctx, 0); if (ctx->AttribStackDepth == 0) { - _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopAttrib"); return; } @@ -918,10 +985,14 @@ _mesa_PopAttrib(void) if (MESA_VERBOSE & VERBOSE_API) { _mesa_debug(ctx, "glPopAttrib %s\n", - _mesa_lookup_enum_by_nr(attr->kind)); + _mesa_enum_to_string(attr->kind)); } switch (attr->kind) { + case DUMMY_BIT: + /* do nothing */ + break; + case GL_ACCUM_BUFFER_BIT: { const struct gl_accum_attrib *accum; @@ -944,19 +1015,19 @@ _mesa_PopAttrib(void) color->ClearColor.f[3]); _mesa_IndexMask(color->IndexMask); if (!ctx->Extensions.EXT_draw_buffers2) { - _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0), - (GLboolean) (color->ColorMask[0][1] != 0), - (GLboolean) (color->ColorMask[0][2] != 0), - (GLboolean) (color->ColorMask[0][3] != 0)); + _mesa_ColorMask(GET_COLORMASK_BIT(color->ColorMask, 0, 0), + GET_COLORMASK_BIT(color->ColorMask, 0, 1), + GET_COLORMASK_BIT(color->ColorMask, 0, 2), + GET_COLORMASK_BIT(color->ColorMask, 0, 3)); } else { GLuint i; for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - _mesa_ColorMaski(i, - (GLboolean) (color->ColorMask[i][0] != 0), - (GLboolean) (color->ColorMask[i][1] != 0), - (GLboolean) (color->ColorMask[i][2] != 0), - (GLboolean) (color->ColorMask[i][3] != 0)); + _mesa_ColorMaski(i, + GET_COLORMASK_BIT(color->ColorMask, i, 0), + GET_COLORMASK_BIT(color->ColorMask, i, 1), + GET_COLORMASK_BIT(color->ColorMask, i, 2), + GET_COLORMASK_BIT(color->ColorMask, i, 3)); } } { @@ -967,13 +1038,13 @@ _mesa_PopAttrib(void) * function, but legal for the later. */ GLboolean multipleBuffers = GL_FALSE; - GLuint i; + GLuint i; - for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { - if (color->DrawBuffer[i] != GL_NONE) { - multipleBuffers = GL_TRUE; - break; - } + for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { + if (color->DrawBuffer[i] != GL_NONE) { + multipleBuffers = GL_TRUE; + break; + } } /* Call the API_level functions, not _mesa_drawbuffers() * since we need to do error checking on the pop'd @@ -982,11 +1053,16 @@ _mesa_PopAttrib(void) * user FBO bound, GL_FRONT will be illegal and we'll need * to record that error. Per OpenGL ARB decision. */ - if (multipleBuffers) - _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, - color->DrawBuffer); - else + if (multipleBuffers) { + GLenum buffers[MAX_DRAW_BUFFERS]; + + for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) + buffers[i] = color->DrawBuffer[i]; + + _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, buffers); + } else { _mesa_DrawBuffer(color->DrawBuffer[0]); + } } _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped); @@ -1048,7 +1124,8 @@ _mesa_PopAttrib(void) if (ctx->Extensions.ARB_color_buffer_float) _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor); - _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor); + if (ctx->Extensions.ARB_color_buffer_float || ctx->Version >= 30) + _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor); /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ if (ctx->Extensions.EXT_framebuffer_sRGB) @@ -1056,9 +1133,9 @@ _mesa_PopAttrib(void) } break; case GL_CURRENT_BIT: - FLUSH_CURRENT( ctx, 0 ); - memcpy( &ctx->Current, attr->data, - sizeof(struct gl_current_attrib) ); + FLUSH_CURRENT(ctx, 0); + memcpy(&ctx->Current, attr->data, + sizeof(struct gl_current_attrib)); break; case GL_DEPTH_BUFFER_BIT: { @@ -1068,6 +1145,11 @@ _mesa_PopAttrib(void) _mesa_ClearDepth(depth->Clear); _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); _mesa_DepthMask(depth->Mask); + if (ctx->Extensions.EXT_depth_bounds_test) { + _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT, + depth->BoundsTest); + _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax); + } } break; case GL_ENABLE_BIT: @@ -1075,12 +1157,27 @@ _mesa_PopAttrib(void) const struct gl_enable_attrib *enable; enable = (const struct gl_enable_attrib *) attr->data; pop_enable_group(ctx, enable); - ctx->NewState |= _NEW_ALL; + ctx->NewState |= _NEW_ALL; + ctx->NewDriverState |= ctx->DriverFlags.NewAlphaTest | + ctx->DriverFlags.NewBlend | + ctx->DriverFlags.NewClipPlaneEnable | + ctx->DriverFlags.NewDepth | + ctx->DriverFlags.NewDepthClamp | + ctx->DriverFlags.NewFramebufferSRGB | + ctx->DriverFlags.NewLineState | + ctx->DriverFlags.NewLogicOp | + ctx->DriverFlags.NewMultisampleEnable | + ctx->DriverFlags.NewPolygonState | + ctx->DriverFlags.NewSampleAlphaToXEnable | + ctx->DriverFlags.NewSampleMask | + ctx->DriverFlags.NewScissorTest | + ctx->DriverFlags.NewStencil | + ctx->DriverFlags.NewNvConservativeRasterization; } break; case GL_EVAL_BIT: - memcpy( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); - ctx->NewState |= _NEW_EVAL; + memcpy(&ctx->Eval, attr->data, sizeof(struct gl_eval_attrib)); + ctx->NewState |= _NEW_EVAL; break; case GL_FOG_BIT: { @@ -1100,13 +1197,13 @@ _mesa_PopAttrib(void) const struct gl_hint_attrib *hint; hint = (const struct gl_hint_attrib *) attr->data; _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, - hint->PerspectiveCorrection ); + hint->PerspectiveCorrection); _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); _mesa_Hint(GL_FOG_HINT, hint->Fog); - _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, - hint->TextureCompression); + _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, + hint->TextureCompression); } break; case GL_LIGHTING_BIT: @@ -1118,14 +1215,14 @@ _mesa_PopAttrib(void) _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); /* per-light state */ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) - _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); - + _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); + for (i = 0; i < ctx->Const.MaxLights; i++) { const struct gl_light *l = &light->Light[i]; _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled); _mesa_light(ctx, i, GL_AMBIENT, l->Ambient); _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse); - _mesa_light(ctx, i, GL_SPECULAR, l->Specular ); + _mesa_light(ctx, i, GL_SPECULAR, l->Specular); _mesa_light(ctx, i, GL_POSITION, l->EyePosition); _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection); { @@ -1190,13 +1287,13 @@ _mesa_PopAttrib(void) } break; case GL_LIST_BIT: - memcpy( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); + memcpy(&ctx->List, attr->data, sizeof(struct gl_list_attrib)); break; case GL_PIXEL_MODE_BIT: - memcpy( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); + memcpy(&ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib)); /* XXX what other pixel state needs to be set by function calls? */ _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); - ctx->NewState |= _NEW_PIXEL; + ctx->NewState |= _NEW_PIXEL; break; case GL_POINT_BIT: { @@ -1215,11 +1312,11 @@ _mesa_PopAttrib(void) point->Threshold); } if (ctx->Extensions.NV_point_sprite - || ctx->Extensions.ARB_point_sprite) { + || ctx->Extensions.ARB_point_sprite) { GLuint u; for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, - (GLint) point->CoordReplace[u]); + !!(point->CoordReplace & (1u << u))); } _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite); if (ctx->Extensions.NV_point_sprite) @@ -1241,8 +1338,10 @@ _mesa_PopAttrib(void) _mesa_FrontFace(polygon->FrontFace); _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); _mesa_PolygonMode(GL_BACK, polygon->BackMode); - _mesa_PolygonOffset(polygon->OffsetFactor, - polygon->OffsetUnits); + _mesa_polygon_offset_clamp(ctx, + polygon->OffsetFactor, + polygon->OffsetUnits, + polygon->OffsetClamp); _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); @@ -1254,19 +1353,39 @@ _mesa_PopAttrib(void) polygon->OffsetFill); } break; - case GL_POLYGON_STIPPLE_BIT: - memcpy( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); - ctx->NewState |= _NEW_POLYGONSTIPPLE; - if (ctx->Driver.PolygonStipple) - ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); - break; + case GL_POLYGON_STIPPLE_BIT: + memcpy(ctx->PolygonStipple, attr->data, 32*sizeof(GLuint)); + + if (ctx->DriverFlags.NewPolygonStipple) + ctx->NewDriverState |= ctx->DriverFlags.NewPolygonStipple; + else + ctx->NewState |= _NEW_POLYGONSTIPPLE; + + if (ctx->Driver.PolygonStipple) + ctx->Driver.PolygonStipple(ctx, (const GLubyte *) attr->data); + break; case GL_SCISSOR_BIT: { + unsigned i; const struct gl_scissor_attrib *scissor; scissor = (const struct gl_scissor_attrib *) attr->data; - _mesa_Scissor(scissor->X, scissor->Y, - scissor->Width, scissor->Height); - _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); + + for (i = 0; i < ctx->Const.MaxViewports; i++) { + _mesa_set_scissor(ctx, i, + scissor->ScissorArray[i].X, + scissor->ScissorArray[i].Y, + scissor->ScissorArray[i].Width, + scissor->ScissorArray[i].Height); + _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, + (scissor->EnableFlags >> i) & 1); + } + if (ctx->Extensions.EXT_window_rectangles) { + STATIC_ASSERT(sizeof(struct gl_scissor_rect) == + 4 * sizeof(GLint)); + _mesa_WindowRectanglesEXT( + scissor->WindowRectMode, scissor->NumWindowRects, + (const GLint *)scissor->WindowRects); + } } break; case GL_STENCIL_BUFFER_BIT: @@ -1308,7 +1427,7 @@ _mesa_PopAttrib(void) xform = (const struct gl_transform_attrib *) attr->data; _mesa_MatrixMode(xform->MatrixMode); if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) - _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); + _math_matrix_analyse(ctx->ProjectionMatrixStack.Top); /* restore clip planes */ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { @@ -1318,7 +1437,7 @@ _mesa_PopAttrib(void) _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, !!(xform->ClipPlanesEnabled & mask)); if (ctx->Driver.ClipPlane) - ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane ); + ctx->Driver.ClipPlane(ctx, GL_CLIP_PLANE0 + i, eyePlane); } /* normalize/rescale */ @@ -1327,9 +1446,25 @@ _mesa_PopAttrib(void) if (xform->RescaleNormals != ctx->Transform.RescaleNormals) _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals); - if (xform->DepthClamp != ctx->Transform.DepthClamp) - _mesa_set_enable(ctx, GL_DEPTH_CLAMP, - ctx->Transform.DepthClamp); + + if (!ctx->Extensions.AMD_depth_clamp_separate) { + if (xform->DepthClampNear != ctx->Transform.DepthClampNear && + xform->DepthClampFar != ctx->Transform.DepthClampFar) { + _mesa_set_enable(ctx, GL_DEPTH_CLAMP, + ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); + } + } else { + if (xform->DepthClampNear != ctx->Transform.DepthClampNear) + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_NEAR_AMD, + ctx->Transform.DepthClampNear); + if (xform->DepthClampFar != ctx->Transform.DepthClampFar) + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_FAR_AMD, + ctx->Transform.DepthClampFar); + } + + if (ctx->Extensions.ARB_clip_control) + _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode); } break; case GL_TEXTURE_BIT: @@ -1337,15 +1472,27 @@ _mesa_PopAttrib(void) struct texture_state *texstate = (struct texture_state *) attr->data; pop_texture_group(ctx, texstate); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE; } break; case GL_VIEWPORT_BIT: { - const struct gl_viewport_attrib *vp; - vp = (const struct gl_viewport_attrib *) attr->data; - _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); - _mesa_DepthRange(vp->Near, vp->Far); + unsigned i; + const struct viewport_state *viewstate; + viewstate = (const struct viewport_state *) attr->data; + + for (i = 0; i < ctx->Const.MaxViewports; i++) { + const struct gl_viewport_attrib *vp = &viewstate->ViewportArray[i]; + _mesa_set_viewport(ctx, i, vp->X, vp->Y, vp->Width, + vp->Height); + _mesa_set_depth_range(ctx, i, vp->Near, vp->Far); + } + + if (ctx->Extensions.NV_conservative_raster) { + GLuint biasx = viewstate->SubpixelPrecisionBias[0]; + GLuint biasy = viewstate->SubpixelPrecisionBias[1]; + _mesa_SubpixelPrecisionBiasNV(biasx, biasy); + } } break; case GL_MULTISAMPLE_BIT_ARB: @@ -1353,21 +1500,21 @@ _mesa_PopAttrib(void) const struct gl_multisample_attrib *ms; ms = (const struct gl_multisample_attrib *) attr->data; - TEST_AND_UPDATE(ctx->Multisample.Enabled, - ms->Enabled, - GL_MULTISAMPLE); + TEST_AND_UPDATE(ctx->Multisample.Enabled, + ms->Enabled, + GL_MULTISAMPLE); - TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, - ms->SampleCoverage, - GL_SAMPLE_COVERAGE); + TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, + ms->SampleCoverage, + GL_SAMPLE_COVERAGE); - TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, - ms->SampleAlphaToCoverage, - GL_SAMPLE_ALPHA_TO_COVERAGE); + TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, + ms->SampleAlphaToCoverage, + GL_SAMPLE_ALPHA_TO_COVERAGE); - TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, - ms->SampleAlphaToOne, - GL_SAMPLE_ALPHA_TO_ONE); + TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, + ms->SampleAlphaToOne, + GL_SAMPLE_ALPHA_TO_ONE); _mesa_SampleCoverage(ms->SampleCoverageValue, ms->SampleCoverageInvert); @@ -1375,8 +1522,7 @@ _mesa_PopAttrib(void) break; default: - _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); - break; + unreachable("Bad attrib flag in PopAttrib"); } next = attr->next; @@ -1413,31 +1559,33 @@ copy_pixelstore(struct gl_context *ctx, #define GL_CLIENT_UNPACK_BIT (1<<21) /** - * Copy gl_array_object from src to dest. + * Copy gl_vertex_array_object from src to dest. * 'dest' must be in an initialized state. */ static void copy_array_object(struct gl_context *ctx, - struct gl_array_object *dest, - struct gl_array_object *src) + struct gl_vertex_array_object *dest, + struct gl_vertex_array_object *src) { GLuint i; /* skip Name */ /* skip RefCount */ - /* In theory must be the same anyway, but on recreate make sure it matches */ - dest->ARBsemantics = src->ARBsemantics; - - for (i = 0; i < Elements(src->_VertexAttrib); i++) { - _mesa_copy_client_array(ctx, &dest->_VertexAttrib[i], &src->_VertexAttrib[i]); + for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) { _mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]); - _mesa_copy_vertex_buffer_binding(ctx, &dest->VertexBinding[i], &src->VertexBinding[i]); + _mesa_copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]); } - /* _Enabled must be the same than on push */ - dest->_Enabled = src->_Enabled; - dest->_MaxElement = src->_MaxElement; + /* Enabled must be the same than on push */ + dest->Enabled = src->Enabled; + dest->_EffEnabledVBO = src->_EffEnabledVBO; + dest->_EffEnabledNonZeroDivisor = src->_EffEnabledNonZeroDivisor; + /* The bitmask of bound VBOs needs to match the VertexBinding array */ + dest->VertexAttribBufferMask = src->VertexAttribBufferMask; + dest->NonZeroDivisorMask = src->NonZeroDivisorMask; + dest->_AttributeMapMode = src->_AttributeMapMode; + dest->NewArrays = src->NewArrays; } /** @@ -1463,10 +1611,13 @@ copy_array_attrib(struct gl_context *ctx, /* skip RebindArrays */ if (!vbo_deleted) - copy_array_object(ctx, dest->ArrayObj, src->ArrayObj); + copy_array_object(ctx, dest->VAO, src->VAO); /* skip ArrayBufferObj */ - /* skip ElementArrayBufferObj */ + /* skip IndexBufferObj */ + + /* Invalidate array state. It will be updated during the next draw. */ + _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); } /** @@ -1479,15 +1630,15 @@ save_array_attrib(struct gl_context *ctx, { /* Set the Name, needed for restore, but do never overwrite. * Needs to match value in the object hash. */ - dest->ArrayObj->Name = src->ArrayObj->Name; + dest->VAO->Name = src->VAO->Name; /* And copy all of the rest. */ copy_array_attrib(ctx, dest, src, false); /* Just reference them here */ _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, src->ArrayBufferObj); - _mesa_reference_buffer_object(ctx, &dest->ArrayObj->ElementArrayBufferObj, - src->ArrayObj->ElementArrayBufferObj); + _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj, + src->VAO->IndexBufferObj); } /** @@ -1498,6 +1649,8 @@ restore_array_attrib(struct gl_context *ctx, struct gl_array_attrib *dest, struct gl_array_attrib *src) { + bool is_vao_name_zero = src->VAO->Name == 0; + /* The ARB_vertex_array_object spec says: * * "BindVertexArray fails and an INVALID_OPERATION error is generated @@ -1506,36 +1659,28 @@ restore_array_attrib(struct gl_context *ctx, * DeleteVertexArrays." * * Therefore popping a deleted VAO cannot magically recreate it. - * - * The semantics of objects created using APPLE_vertex_array_objects behave - * differently. These objects expect to be recreated by pop. Alas. */ - const bool arb_vao = (src->ArrayObj->Name != 0 - && src->ArrayObj->ARBsemantics); - - if (arb_vao && !_mesa_IsVertexArray(src->ArrayObj->Name)) + if (!is_vao_name_zero && !_mesa_IsVertexArray(src->VAO->Name)) return; - _mesa_BindVertexArrayAPPLE(src->ArrayObj->Name); + _mesa_BindVertexArray(src->VAO->Name); /* Restore or recreate the buffer objects by the names ... */ - if (!arb_vao - || src->ArrayBufferObj->Name == 0 - || _mesa_IsBuffer(src->ArrayBufferObj->Name)) { + if (is_vao_name_zero || src->ArrayBufferObj->Name == 0 || + _mesa_IsBuffer(src->ArrayBufferObj->Name)) { /* ... and restore its content */ copy_array_attrib(ctx, dest, src, false); _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, - src->ArrayBufferObj->Name); + src->ArrayBufferObj->Name); } else { copy_array_attrib(ctx, dest, src, true); } - if (!arb_vao - || src->ArrayObj->ElementArrayBufferObj->Name == 0 - || _mesa_IsBuffer(src->ArrayObj->ElementArrayBufferObj->Name)) + if (is_vao_name_zero || src->VAO->IndexBufferObj->Name == 0 || + _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, - src->ArrayObj->ElementArrayBufferObj->Name); + src->VAO->IndexBufferObj->Name); } /** @@ -1546,15 +1691,15 @@ static bool init_array_attrib_data(struct gl_context *ctx, struct gl_array_attrib *attrib) { - /* Get a non driver gl_array_object. */ - attrib->ArrayObj = CALLOC_STRUCT( gl_array_object ); + /* Get a non driver gl_vertex_array_object. */ + attrib->VAO = CALLOC_STRUCT(gl_vertex_array_object); - if (attrib->ArrayObj == NULL) { + if (attrib->VAO == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); return false; } - _mesa_initialize_array_object(ctx, attrib->ArrayObj, 0); + _mesa_initialize_vao(ctx, attrib->VAO, 0); return true; } @@ -1569,8 +1714,8 @@ free_array_attrib_data(struct gl_context *ctx, { /* We use a non driver array object, so don't just unref since we would * end up using the drivers DeleteArrayObject function for deletion. */ - _mesa_delete_array_object(ctx, attrib->ArrayObj); - attrib->ArrayObj = 0; + _mesa_delete_vao(ctx, attrib->VAO); + attrib->VAO = 0; _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL); } @@ -1583,7 +1728,7 @@ _mesa_PushClientAttrib(GLbitfield mask) GET_CURRENT_CONTEXT(ctx); if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { - _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); + _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushClientAttrib"); return; } @@ -1595,22 +1740,22 @@ _mesa_PushClientAttrib(GLbitfield mask) if (mask & GL_CLIENT_PIXEL_STORE_BIT) { struct gl_pixelstore_attrib *attr; /* packing attribs */ - attr = CALLOC_STRUCT( gl_pixelstore_attrib ); + attr = CALLOC_STRUCT(gl_pixelstore_attrib); if (attr == NULL) { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); goto end; } if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) { copy_pixelstore(ctx, attr, &ctx->Pack); } else { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); - FREE(attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + free(attr); goto end; } /* unpacking attribs */ - attr = CALLOC_STRUCT( gl_pixelstore_attrib ); + attr = CALLOC_STRUCT(gl_pixelstore_attrib); if (attr == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); goto end; @@ -1620,22 +1765,22 @@ _mesa_PushClientAttrib(GLbitfield mask) copy_pixelstore(ctx, attr, &ctx->Unpack); } else { - _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); - FREE(attr); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); + free(attr); goto end; } } if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { struct gl_array_attrib *attr; - attr = CALLOC_STRUCT( gl_array_attrib ); + attr = CALLOC_STRUCT(gl_array_attrib); if (attr == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); goto end; } if (!init_array_attrib_data(ctx, attr)) { - FREE(attr); + free(attr); goto end; } @@ -1645,7 +1790,7 @@ _mesa_PushClientAttrib(GLbitfield mask) else { free_array_attrib_data(ctx, attr); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - FREE(attr); + free(attr); /* goto to keep safe from possible later changes */ goto end; } @@ -1658,8 +1803,6 @@ end: } - - void GLAPIENTRY _mesa_PopClientAttrib(void) { @@ -1669,7 +1812,7 @@ _mesa_PopClientAttrib(void) FLUSH_VERTICES(ctx, 0); if (ctx->ClientAttribStackDepth == 0) { - _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib"); return; } @@ -1695,16 +1838,14 @@ _mesa_PopClientAttrib(void) } break; case GL_CLIENT_VERTEX_ARRAY_BIT: { - struct gl_array_attrib * attr = - (struct gl_array_attrib *) node->data; + struct gl_array_attrib * attr = + (struct gl_array_attrib *) node->data; restore_array_attrib(ctx, &ctx->Array, attr); free_array_attrib_data(ctx, attr); - ctx->NewState |= _NEW_ARRAY; break; - } + } default: - _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); - break; + unreachable("Bad attrib flag in PopClientAttrib"); } next = node->next; @@ -1714,6 +1855,80 @@ _mesa_PopClientAttrib(void) } } +void GLAPIENTRY +_mesa_ClientAttribDefaultEXT( GLbitfield mask ) +{ + if (mask & GL_CLIENT_PIXEL_STORE_BIT) { + _mesa_PixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + _mesa_PixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + _mesa_PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); + _mesa_PixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + _mesa_PixelStorei(GL_UNPACK_ROW_LENGTH, 0); + _mesa_PixelStorei(GL_UNPACK_SKIP_ROWS, 0); + _mesa_PixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, 4); + _mesa_PixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); + _mesa_PixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); + _mesa_PixelStorei(GL_PACK_IMAGE_HEIGHT, 0); + _mesa_PixelStorei(GL_PACK_SKIP_IMAGES, 0); + _mesa_PixelStorei(GL_PACK_ROW_LENGTH, 0); + _mesa_PixelStorei(GL_PACK_SKIP_ROWS, 0); + _mesa_PixelStorei(GL_PACK_SKIP_PIXELS, 0); + _mesa_PixelStorei(GL_PACK_ALIGNMENT, 4); + + _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + _mesa_BindBuffer(GL_PIXEL_PACK_BUFFER, 0); + } + if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { + GET_CURRENT_CONTEXT(ctx); + int i; + + _mesa_BindBuffer(GL_ARRAY_BUFFER, 0); + _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + _mesa_DisableClientState(GL_EDGE_FLAG_ARRAY); + _mesa_EdgeFlagPointer(0, 0); + + _mesa_DisableClientState(GL_INDEX_ARRAY); + _mesa_IndexPointer(GL_FLOAT, 0, 0); + + _mesa_DisableClientState(GL_SECONDARY_COLOR_ARRAY); + _mesa_SecondaryColorPointer(4, GL_FLOAT, 0, 0); + + _mesa_DisableClientState(GL_FOG_COORD_ARRAY); + _mesa_FogCoordPointer(GL_FLOAT, 0, 0); + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + _mesa_ClientActiveTexture(GL_TEXTURE0 + i); + _mesa_DisableClientState(GL_TEXTURE_COORD_ARRAY); + _mesa_TexCoordPointer(4, GL_FLOAT, 0, 0); + } + + _mesa_DisableClientState(GL_COLOR_ARRAY); + _mesa_ColorPointer(4, GL_FLOAT, 0, 0); + + _mesa_DisableClientState(GL_NORMAL_ARRAY); + _mesa_NormalPointer(GL_FLOAT, 0, 0); + + _mesa_DisableClientState(GL_VERTEX_ARRAY); + _mesa_VertexPointer(4, GL_FLOAT, 0, 0); + + for (i = 0; i < ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs; i++) { + _mesa_DisableVertexAttribArray(i); + _mesa_VertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); + } + + _mesa_ClientActiveTexture(GL_TEXTURE0); + } +} + +void GLAPIENTRY +_mesa_PushClientAttribDefaultEXT( GLbitfield mask ) +{ + _mesa_PushClientAttrib(mask); + _mesa_ClientAttribDefaultEXT(mask); +} + /** * Free any attribute state data that might be attached to the context. @@ -1752,7 +1967,8 @@ _mesa_free_attrib_data(struct gl_context *ctx) } -void _mesa_init_attrib( struct gl_context *ctx ) +void +_mesa_init_attrib(struct gl_context *ctx) { /* Renderer and client attribute stacks */ ctx->AttribStackDepth = 0;