1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "glheader.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "accum.h" 29bf215546Sopenharmony_ci#include "arrayobj.h" 30bf215546Sopenharmony_ci#include "attrib.h" 31bf215546Sopenharmony_ci#include "blend.h" 32bf215546Sopenharmony_ci#include "buffers.h" 33bf215546Sopenharmony_ci#include "bufferobj.h" 34bf215546Sopenharmony_ci#include "context.h" 35bf215546Sopenharmony_ci#include "depth.h" 36bf215546Sopenharmony_ci#include "enable.h" 37bf215546Sopenharmony_ci#include "enums.h" 38bf215546Sopenharmony_ci#include "fog.h" 39bf215546Sopenharmony_ci#include "hint.h" 40bf215546Sopenharmony_ci#include "light.h" 41bf215546Sopenharmony_ci#include "lines.h" 42bf215546Sopenharmony_ci#include "macros.h" 43bf215546Sopenharmony_ci#include "matrix.h" 44bf215546Sopenharmony_ci#include "multisample.h" 45bf215546Sopenharmony_ci#include "pixelstore.h" 46bf215546Sopenharmony_ci#include "points.h" 47bf215546Sopenharmony_ci#include "polygon.h" 48bf215546Sopenharmony_ci#include "shared.h" 49bf215546Sopenharmony_ci#include "scissor.h" 50bf215546Sopenharmony_ci#include "stencil.h" 51bf215546Sopenharmony_ci#include "texobj.h" 52bf215546Sopenharmony_ci#include "texparam.h" 53bf215546Sopenharmony_ci#include "texstate.h" 54bf215546Sopenharmony_ci#include "varray.h" 55bf215546Sopenharmony_ci#include "viewport.h" 56bf215546Sopenharmony_ci#include "mtypes.h" 57bf215546Sopenharmony_ci#include "state.h" 58bf215546Sopenharmony_ci#include "hash.h" 59bf215546Sopenharmony_ci#include <stdbool.h> 60bf215546Sopenharmony_ci#include "util/u_memory.h" 61bf215546Sopenharmony_ci#include "api_exec_decl.h" 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h" 64bf215546Sopenharmony_ci#include "state_tracker/st_manager.h" 65bf215546Sopenharmony_ci#include "state_tracker/st_sampler_view.h" 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_cistatic inline bool 68bf215546Sopenharmony_cicopy_texture_attribs(struct gl_texture_object *dst, 69bf215546Sopenharmony_ci const struct gl_texture_object *src, 70bf215546Sopenharmony_ci gl_texture_index tex) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci /* All pushed fields have no effect on texture buffers. */ 73bf215546Sopenharmony_ci if (tex == TEXTURE_BUFFER_INDEX) 74bf215546Sopenharmony_ci return false; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci /* Sampler fields have no effect on MSAA textures. */ 77bf215546Sopenharmony_ci if (tex != TEXTURE_2D_MULTISAMPLE_INDEX && 78bf215546Sopenharmony_ci tex != TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX) { 79bf215546Sopenharmony_ci memcpy(&dst->Sampler.Attrib, &src->Sampler.Attrib, 80bf215546Sopenharmony_ci sizeof(src->Sampler.Attrib)); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci memcpy(&dst->Attrib, &src->Attrib, sizeof(src->Attrib)); 83bf215546Sopenharmony_ci return true; 84bf215546Sopenharmony_ci} 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_civoid GLAPIENTRY 88bf215546Sopenharmony_ci_mesa_PushAttrib(GLbitfield mask) 89bf215546Sopenharmony_ci{ 90bf215546Sopenharmony_ci struct gl_attrib_node *head; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 95bf215546Sopenharmony_ci _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask); 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { 98bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushAttrib"); 99bf215546Sopenharmony_ci return; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci head = ctx->AttribStack[ctx->AttribStackDepth]; 103bf215546Sopenharmony_ci if (unlikely(!head)) { 104bf215546Sopenharmony_ci head = CALLOC_STRUCT(gl_attrib_node); 105bf215546Sopenharmony_ci if (unlikely(!head)) { 106bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 107bf215546Sopenharmony_ci return; 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci ctx->AttribStack[ctx->AttribStackDepth] = head; 110bf215546Sopenharmony_ci } 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci head->Mask = mask; 113bf215546Sopenharmony_ci head->OldPopAttribStateMask = ctx->PopAttribState; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci if (mask & GL_ACCUM_BUFFER_BIT) 116bf215546Sopenharmony_ci memcpy(&head->Accum, &ctx->Accum, sizeof(head->Accum)); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci if (mask & GL_COLOR_BUFFER_BIT) { 119bf215546Sopenharmony_ci memcpy(&head->Color, &ctx->Color, sizeof(struct gl_colorbuffer_attrib)); 120bf215546Sopenharmony_ci /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */ 121bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i ++) 122bf215546Sopenharmony_ci head->Color.DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci if (mask & GL_CURRENT_BIT) { 126bf215546Sopenharmony_ci FLUSH_CURRENT(ctx, 0); 127bf215546Sopenharmony_ci memcpy(&head->Current, &ctx->Current, sizeof(head->Current)); 128bf215546Sopenharmony_ci } 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci if (mask & GL_DEPTH_BUFFER_BIT) 131bf215546Sopenharmony_ci memcpy(&head->Depth, &ctx->Depth, sizeof(head->Depth)); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci if (mask & GL_ENABLE_BIT) { 134bf215546Sopenharmony_ci struct gl_enable_attrib_node *attr = &head->Enable; 135bf215546Sopenharmony_ci GLuint i; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci /* Copy enable flags from all other attributes into the enable struct. */ 138bf215546Sopenharmony_ci attr->AlphaTest = ctx->Color.AlphaEnabled; 139bf215546Sopenharmony_ci attr->AutoNormal = ctx->Eval.AutoNormal; 140bf215546Sopenharmony_ci attr->Blend = ctx->Color.BlendEnabled; 141bf215546Sopenharmony_ci attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; 142bf215546Sopenharmony_ci attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 143bf215546Sopenharmony_ci attr->CullFace = ctx->Polygon.CullFlag; 144bf215546Sopenharmony_ci attr->DepthClampNear = ctx->Transform.DepthClampNear; 145bf215546Sopenharmony_ci attr->DepthClampFar = ctx->Transform.DepthClampFar; 146bf215546Sopenharmony_ci attr->DepthTest = ctx->Depth.Test; 147bf215546Sopenharmony_ci attr->Dither = ctx->Color.DitherFlag; 148bf215546Sopenharmony_ci attr->Fog = ctx->Fog.Enabled; 149bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxLights; i++) { 150bf215546Sopenharmony_ci attr->Light[i] = ctx->Light.Light[i].Enabled; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci attr->Lighting = ctx->Light.Enabled; 153bf215546Sopenharmony_ci attr->LineSmooth = ctx->Line.SmoothFlag; 154bf215546Sopenharmony_ci attr->LineStipple = ctx->Line.StippleFlag; 155bf215546Sopenharmony_ci attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 156bf215546Sopenharmony_ci attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 157bf215546Sopenharmony_ci attr->Map1Color4 = ctx->Eval.Map1Color4; 158bf215546Sopenharmony_ci attr->Map1Index = ctx->Eval.Map1Index; 159bf215546Sopenharmony_ci attr->Map1Normal = ctx->Eval.Map1Normal; 160bf215546Sopenharmony_ci attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 161bf215546Sopenharmony_ci attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 162bf215546Sopenharmony_ci attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 163bf215546Sopenharmony_ci attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 164bf215546Sopenharmony_ci attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 165bf215546Sopenharmony_ci attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 166bf215546Sopenharmony_ci attr->Map2Color4 = ctx->Eval.Map2Color4; 167bf215546Sopenharmony_ci attr->Map2Index = ctx->Eval.Map2Index; 168bf215546Sopenharmony_ci attr->Map2Normal = ctx->Eval.Map2Normal; 169bf215546Sopenharmony_ci attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 170bf215546Sopenharmony_ci attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 171bf215546Sopenharmony_ci attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 172bf215546Sopenharmony_ci attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 173bf215546Sopenharmony_ci attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 174bf215546Sopenharmony_ci attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 175bf215546Sopenharmony_ci attr->Normalize = ctx->Transform.Normalize; 176bf215546Sopenharmony_ci attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped; 177bf215546Sopenharmony_ci attr->PointSmooth = ctx->Point.SmoothFlag; 178bf215546Sopenharmony_ci attr->PointSprite = ctx->Point.PointSprite; 179bf215546Sopenharmony_ci attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 180bf215546Sopenharmony_ci attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 181bf215546Sopenharmony_ci attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 182bf215546Sopenharmony_ci attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 183bf215546Sopenharmony_ci attr->PolygonStipple = ctx->Polygon.StippleFlag; 184bf215546Sopenharmony_ci attr->RescaleNormals = ctx->Transform.RescaleNormals; 185bf215546Sopenharmony_ci attr->Scissor = ctx->Scissor.EnableFlags; 186bf215546Sopenharmony_ci attr->Stencil = ctx->Stencil.Enabled; 187bf215546Sopenharmony_ci attr->StencilTwoSide = ctx->Stencil.TestTwoSide; 188bf215546Sopenharmony_ci attr->MultisampleEnabled = ctx->Multisample.Enabled; 189bf215546Sopenharmony_ci attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage; 190bf215546Sopenharmony_ci attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; 191bf215546Sopenharmony_ci attr->SampleCoverage = ctx->Multisample.SampleCoverage; 192bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 193bf215546Sopenharmony_ci attr->Texture[i] = ctx->Texture.FixedFuncUnit[i].Enabled; 194bf215546Sopenharmony_ci attr->TexGen[i] = ctx->Texture.FixedFuncUnit[i].TexGenEnabled; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci /* GL_ARB_vertex_program */ 197bf215546Sopenharmony_ci attr->VertexProgram = ctx->VertexProgram.Enabled; 198bf215546Sopenharmony_ci attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled; 199bf215546Sopenharmony_ci attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci /* GL_ARB_fragment_program */ 202bf215546Sopenharmony_ci attr->FragmentProgram = ctx->FragmentProgram.Enabled; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 205bf215546Sopenharmony_ci attr->sRGBEnabled = ctx->Color.sRGBEnabled; 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci /* GL_NV_conservative_raster */ 208bf215546Sopenharmony_ci attr->ConservativeRasterization = ctx->ConservativeRasterization; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (mask & GL_EVAL_BIT) 212bf215546Sopenharmony_ci memcpy(&head->Eval, &ctx->Eval, sizeof(head->Eval)); 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci if (mask & GL_FOG_BIT) 215bf215546Sopenharmony_ci memcpy(&head->Fog, &ctx->Fog, sizeof(head->Fog)); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci if (mask & GL_HINT_BIT) 218bf215546Sopenharmony_ci memcpy(&head->Hint, &ctx->Hint, sizeof(head->Hint)); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (mask & GL_LIGHTING_BIT) { 221bf215546Sopenharmony_ci FLUSH_CURRENT(ctx, 0); /* flush material changes */ 222bf215546Sopenharmony_ci memcpy(&head->Light, &ctx->Light, sizeof(head->Light)); 223bf215546Sopenharmony_ci } 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci if (mask & GL_LINE_BIT) 226bf215546Sopenharmony_ci memcpy(&head->Line, &ctx->Line, sizeof(head->Line)); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci if (mask & GL_LIST_BIT) 229bf215546Sopenharmony_ci memcpy(&head->List, &ctx->List, sizeof(head->List)); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (mask & GL_PIXEL_MODE_BIT) { 232bf215546Sopenharmony_ci memcpy(&head->Pixel, &ctx->Pixel, sizeof(struct gl_pixel_attrib)); 233bf215546Sopenharmony_ci /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ 234bf215546Sopenharmony_ci head->Pixel.ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci if (mask & GL_POINT_BIT) 238bf215546Sopenharmony_ci memcpy(&head->Point, &ctx->Point, sizeof(head->Point)); 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci if (mask & GL_POLYGON_BIT) 241bf215546Sopenharmony_ci memcpy(&head->Polygon, &ctx->Polygon, sizeof(head->Polygon)); 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci if (mask & GL_POLYGON_STIPPLE_BIT) { 244bf215546Sopenharmony_ci memcpy(&head->PolygonStipple, &ctx->PolygonStipple, 245bf215546Sopenharmony_ci sizeof(head->PolygonStipple)); 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (mask & GL_SCISSOR_BIT) 249bf215546Sopenharmony_ci memcpy(&head->Scissor, &ctx->Scissor, sizeof(head->Scissor)); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (mask & GL_STENCIL_BUFFER_BIT) 252bf215546Sopenharmony_ci memcpy(&head->Stencil, &ctx->Stencil, sizeof(head->Stencil)); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (mask & GL_TEXTURE_BIT) { 255bf215546Sopenharmony_ci GLuint u, tex; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci _mesa_lock_context_textures(ctx); 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci /* copy/save the bulk of texture state here */ 260bf215546Sopenharmony_ci head->Texture.CurrentUnit = ctx->Texture.CurrentUnit; 261bf215546Sopenharmony_ci memcpy(&head->Texture.FixedFuncUnit, &ctx->Texture.FixedFuncUnit, 262bf215546Sopenharmony_ci sizeof(ctx->Texture.FixedFuncUnit)); 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci /* Copy/save contents of default texture objects. They are almost 265bf215546Sopenharmony_ci * always bound, so this can be done unconditionally. 266bf215546Sopenharmony_ci * 267bf215546Sopenharmony_ci * We save them separately, so that we don't have to save them in every 268bf215546Sopenharmony_ci * texture unit where they are bound. This decreases CPU overhead. 269bf215546Sopenharmony_ci */ 270bf215546Sopenharmony_ci for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 271bf215546Sopenharmony_ci struct gl_texture_object *dst = &head->Texture.SavedDefaultObj[tex]; 272bf215546Sopenharmony_ci struct gl_texture_object *src = ctx->Shared->DefaultTex[tex]; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci copy_texture_attribs(dst, src, tex); 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci /* copy state/contents of the currently bound texture objects */ 278bf215546Sopenharmony_ci unsigned num_tex_used = ctx->Texture.NumCurrentTexUsed; 279bf215546Sopenharmony_ci for (u = 0; u < num_tex_used; u++) { 280bf215546Sopenharmony_ci head->Texture.LodBias[u] = ctx->Texture.Unit[u].LodBias; 281bf215546Sopenharmony_ci head->Texture.LodBiasQuantized[u] = ctx->Texture.Unit[u].LodBiasQuantized; 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 284bf215546Sopenharmony_ci struct gl_texture_object *dst = &head->Texture.SavedObj[u][tex]; 285bf215546Sopenharmony_ci struct gl_texture_object *src = ctx->Texture.Unit[u].CurrentTex[tex]; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci dst->Name = src->Name; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci /* Default texture targets are saved separately above. */ 290bf215546Sopenharmony_ci if (src->Name != 0) 291bf215546Sopenharmony_ci copy_texture_attribs(dst, src, tex); 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci head->Texture.NumTexSaved = num_tex_used; 295bf215546Sopenharmony_ci _mesa_unlock_context_textures(ctx); 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci if (mask & GL_TRANSFORM_BIT) 299bf215546Sopenharmony_ci memcpy(&head->Transform, &ctx->Transform, sizeof(head->Transform)); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci if (mask & GL_VIEWPORT_BIT) { 302bf215546Sopenharmony_ci memcpy(&head->Viewport.ViewportArray, &ctx->ViewportArray, 303bf215546Sopenharmony_ci sizeof(struct gl_viewport_attrib)*ctx->Const.MaxViewports); 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci head->Viewport.SubpixelPrecisionBias[0] = ctx->SubpixelPrecisionBias[0]; 306bf215546Sopenharmony_ci head->Viewport.SubpixelPrecisionBias[1] = ctx->SubpixelPrecisionBias[1]; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci /* GL_ARB_multisample */ 310bf215546Sopenharmony_ci if (mask & GL_MULTISAMPLE_BIT_ARB) 311bf215546Sopenharmony_ci memcpy(&head->Multisample, &ctx->Multisample, sizeof(head->Multisample)); 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci ctx->AttribStackDepth++; 314bf215546Sopenharmony_ci ctx->PopAttribState = 0; 315bf215546Sopenharmony_ci} 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) do { \ 319bf215546Sopenharmony_ci if ((VALUE) != (NEWVALUE)) \ 320bf215546Sopenharmony_ci _mesa_set_enable(ctx, ENUM, (NEWVALUE)); \ 321bf215546Sopenharmony_ci } while (0) 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci#define TEST_AND_UPDATE_BIT(VALUE, NEW_VALUE, BIT, ENUM) do { \ 324bf215546Sopenharmony_ci if (((VALUE) & BITFIELD_BIT(BIT)) != ((NEW_VALUE) & BITFIELD_BIT(BIT))) \ 325bf215546Sopenharmony_ci _mesa_set_enable(ctx, ENUM, ((NEW_VALUE) >> (BIT)) & 0x1); \ 326bf215546Sopenharmony_ci } while (0) 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci#define TEST_AND_UPDATE_INDEX(VALUE, NEW_VALUE, INDEX, ENUM) do { \ 329bf215546Sopenharmony_ci if (((VALUE) & BITFIELD_BIT(INDEX)) != ((NEW_VALUE) & BITFIELD_BIT(INDEX))) \ 330bf215546Sopenharmony_ci _mesa_set_enablei(ctx, ENUM, INDEX, ((NEW_VALUE) >> (INDEX)) & 0x1); \ 331bf215546Sopenharmony_ci } while (0) 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_cistatic void 335bf215546Sopenharmony_cipop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib_node *enable) 336bf215546Sopenharmony_ci{ 337bf215546Sopenharmony_ci GLuint i; 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 340bf215546Sopenharmony_ci if (ctx->Color.BlendEnabled != enable->Blend) { 341bf215546Sopenharmony_ci if (ctx->Extensions.EXT_draw_buffers2) { 342bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 343bf215546Sopenharmony_ci TEST_AND_UPDATE_INDEX(ctx->Color.BlendEnabled, enable->Blend, 344bf215546Sopenharmony_ci i, GL_BLEND); 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci } else { 347bf215546Sopenharmony_ci _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1)); 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (ctx->Transform.ClipPlanesEnabled != enable->ClipPlanes) { 352bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxClipPlanes; i++) { 353bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(ctx->Transform.ClipPlanesEnabled, 354bf215546Sopenharmony_ci enable->ClipPlanes, i, GL_CLIP_PLANE0 + i); 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 359bf215546Sopenharmony_ci GL_COLOR_MATERIAL); 360bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci if (!ctx->Extensions.AMD_depth_clamp_separate) { 363bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar, 364bf215546Sopenharmony_ci enable->DepthClampNear && enable->DepthClampFar, 365bf215546Sopenharmony_ci GL_DEPTH_CLAMP); 366bf215546Sopenharmony_ci } else { 367bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear, 368bf215546Sopenharmony_ci GL_DEPTH_CLAMP_NEAR_AMD); 369bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar, 370bf215546Sopenharmony_ci GL_DEPTH_CLAMP_FAR_AMD); 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 374bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 375bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 376bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 377bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 378bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 379bf215546Sopenharmony_ci GL_LINE_STIPPLE); 380bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 381bf215546Sopenharmony_ci GL_INDEX_LOGIC_OP); 382bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 383bf215546Sopenharmony_ci GL_COLOR_LOGIC_OP); 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 386bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 387bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 388bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 389bf215546Sopenharmony_ci GL_MAP1_TEXTURE_COORD_1); 390bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 391bf215546Sopenharmony_ci GL_MAP1_TEXTURE_COORD_2); 392bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 393bf215546Sopenharmony_ci GL_MAP1_TEXTURE_COORD_3); 394bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 395bf215546Sopenharmony_ci GL_MAP1_TEXTURE_COORD_4); 396bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 397bf215546Sopenharmony_ci GL_MAP1_VERTEX_3); 398bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 399bf215546Sopenharmony_ci GL_MAP1_VERTEX_4); 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 402bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 403bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 404bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 405bf215546Sopenharmony_ci GL_MAP2_TEXTURE_COORD_1); 406bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 407bf215546Sopenharmony_ci GL_MAP2_TEXTURE_COORD_2); 408bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 409bf215546Sopenharmony_ci GL_MAP2_TEXTURE_COORD_3); 410bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 411bf215546Sopenharmony_ci GL_MAP2_TEXTURE_COORD_4); 412bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 413bf215546Sopenharmony_ci GL_MAP2_VERTEX_3); 414bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 415bf215546Sopenharmony_ci GL_MAP2_VERTEX_4); 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL); 418bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 419bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 420bf215546Sopenharmony_ci GL_RESCALE_NORMAL_EXT); 421bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped, 422bf215546Sopenharmony_ci enable->RasterPositionUnclipped, 423bf215546Sopenharmony_ci GL_RASTER_POSITION_UNCLIPPED_IBM); 424bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 425bf215546Sopenharmony_ci GL_POINT_SMOOTH); 426bf215546Sopenharmony_ci if (ctx->Extensions.ARB_point_sprite) { 427bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, 428bf215546Sopenharmony_ci GL_POINT_SPRITE); 429bf215546Sopenharmony_ci } 430bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 431bf215546Sopenharmony_ci GL_POLYGON_OFFSET_POINT); 432bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 433bf215546Sopenharmony_ci GL_POLYGON_OFFSET_LINE); 434bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 435bf215546Sopenharmony_ci GL_POLYGON_OFFSET_FILL); 436bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 437bf215546Sopenharmony_ci GL_POLYGON_SMOOTH); 438bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 439bf215546Sopenharmony_ci GL_POLYGON_STIPPLE); 440bf215546Sopenharmony_ci if (ctx->Scissor.EnableFlags != enable->Scissor) { 441bf215546Sopenharmony_ci unsigned i; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxViewports; i++) { 444bf215546Sopenharmony_ci TEST_AND_UPDATE_INDEX(ctx->Scissor.EnableFlags, enable->Scissor, 445bf215546Sopenharmony_ci i, GL_SCISSOR_TEST); 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 449bf215546Sopenharmony_ci if (ctx->Extensions.EXT_stencil_two_side) { 450bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, 451bf215546Sopenharmony_ci GL_STENCIL_TEST_TWO_SIDE_EXT); 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, 454bf215546Sopenharmony_ci GL_MULTISAMPLE_ARB); 455bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 456bf215546Sopenharmony_ci enable->SampleAlphaToCoverage, 457bf215546Sopenharmony_ci GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 458bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 459bf215546Sopenharmony_ci enable->SampleAlphaToOne, 460bf215546Sopenharmony_ci GL_SAMPLE_ALPHA_TO_ONE_ARB); 461bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 462bf215546Sopenharmony_ci enable->SampleCoverage, 463bf215546Sopenharmony_ci GL_SAMPLE_COVERAGE_ARB); 464bf215546Sopenharmony_ci /* GL_ARB_vertex_program */ 465bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->VertexProgram.Enabled, 466bf215546Sopenharmony_ci enable->VertexProgram, 467bf215546Sopenharmony_ci GL_VERTEX_PROGRAM_ARB); 468bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled, 469bf215546Sopenharmony_ci enable->VertexProgramPointSize, 470bf215546Sopenharmony_ci GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 471bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled, 472bf215546Sopenharmony_ci enable->VertexProgramTwoSide, 473bf215546Sopenharmony_ci GL_VERTEX_PROGRAM_TWO_SIDE_ARB); 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci /* GL_ARB_fragment_program */ 476bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->FragmentProgram.Enabled, 477bf215546Sopenharmony_ci enable->FragmentProgram, 478bf215546Sopenharmony_ci GL_FRAGMENT_PROGRAM_ARB); 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 481bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled, 482bf215546Sopenharmony_ci GL_FRAMEBUFFER_SRGB); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci /* GL_NV_conservative_raster */ 485bf215546Sopenharmony_ci if (ctx->Extensions.NV_conservative_raster) { 486bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->ConservativeRasterization, 487bf215546Sopenharmony_ci enable->ConservativeRasterization, 488bf215546Sopenharmony_ci GL_CONSERVATIVE_RASTERIZATION_NV); 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci const unsigned curTexUnitSave = ctx->Texture.CurrentUnit; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci /* texture unit enables */ 494bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 495bf215546Sopenharmony_ci const GLbitfield enabled = enable->Texture[i]; 496bf215546Sopenharmony_ci const GLbitfield gen_enabled = enable->TexGen[i]; 497bf215546Sopenharmony_ci const struct gl_fixedfunc_texture_unit *unit = &ctx->Texture.FixedFuncUnit[i]; 498bf215546Sopenharmony_ci const GLbitfield old_enabled = unit->Enabled; 499bf215546Sopenharmony_ci const GLbitfield old_gen_enabled = unit->TexGenEnabled; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci if (old_enabled == enabled && old_gen_enabled == gen_enabled) 502bf215546Sopenharmony_ci continue; 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci ctx->Texture.CurrentUnit = i; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci if (old_enabled != enabled) { 507bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_1D_INDEX, GL_TEXTURE_1D); 508bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_2D_INDEX, GL_TEXTURE_2D); 509bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_3D_INDEX, GL_TEXTURE_3D); 510bf215546Sopenharmony_ci if (ctx->Extensions.NV_texture_rectangle) { 511bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_RECT_INDEX, 512bf215546Sopenharmony_ci GL_TEXTURE_RECTANGLE); 513bf215546Sopenharmony_ci } 514bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_CUBE_INDEX, 515bf215546Sopenharmony_ci GL_TEXTURE_CUBE_MAP); 516bf215546Sopenharmony_ci } 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci if (old_gen_enabled != gen_enabled) { 519bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 0, GL_TEXTURE_GEN_S); 520bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 1, GL_TEXTURE_GEN_T); 521bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 2, GL_TEXTURE_GEN_R); 522bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(old_gen_enabled, gen_enabled, 3, GL_TEXTURE_GEN_Q); 523bf215546Sopenharmony_ci } 524bf215546Sopenharmony_ci } 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci ctx->Texture.CurrentUnit = curTexUnitSave; 527bf215546Sopenharmony_ci} 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci/** 531bf215546Sopenharmony_ci * Pop/restore texture attribute/group state. 532bf215546Sopenharmony_ci */ 533bf215546Sopenharmony_cistatic void 534bf215546Sopenharmony_cipop_texture_group(struct gl_context *ctx, struct gl_texture_attrib_node *texstate) 535bf215546Sopenharmony_ci{ 536bf215546Sopenharmony_ci GLuint u; 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci _mesa_lock_context_textures(ctx); 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci /* Restore fixed-function texture unit states. */ 541bf215546Sopenharmony_ci for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 542bf215546Sopenharmony_ci const struct gl_fixedfunc_texture_unit *unit = 543bf215546Sopenharmony_ci &texstate->FixedFuncUnit[u]; 544bf215546Sopenharmony_ci struct gl_fixedfunc_texture_unit *destUnit = 545bf215546Sopenharmony_ci &ctx->Texture.FixedFuncUnit[u]; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci ctx->Texture.CurrentUnit = u; 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_ci /* Fast path for other drivers. */ 550bf215546Sopenharmony_ci memcpy(destUnit, unit, sizeof(*unit)); 551bf215546Sopenharmony_ci destUnit->_CurrentCombine = NULL; 552bf215546Sopenharmony_ci ctx->Texture.Unit[u].LodBias = texstate->LodBias[u]; 553bf215546Sopenharmony_ci ctx->Texture.Unit[u].LodBiasQuantized = texstate->LodBiasQuantized[u]; 554bf215546Sopenharmony_ci } 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci /* Restore saved textures. */ 557bf215546Sopenharmony_ci unsigned num_tex_saved = texstate->NumTexSaved; 558bf215546Sopenharmony_ci for (u = 0; u < num_tex_saved; u++) { 559bf215546Sopenharmony_ci gl_texture_index tgt; 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci ctx->Texture.CurrentUnit = u; 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci /* Restore texture object state for each target */ 564bf215546Sopenharmony_ci for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 565bf215546Sopenharmony_ci const struct gl_texture_object *savedObj = &texstate->SavedObj[u][tgt]; 566bf215546Sopenharmony_ci struct gl_texture_object *texObj = 567bf215546Sopenharmony_ci _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt]; 568bf215546Sopenharmony_ci bool is_msaa = tgt == TEXTURE_2D_MULTISAMPLE_INDEX || 569bf215546Sopenharmony_ci tgt == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci /* According to the OpenGL 4.6 Compatibility Profile specification, 572bf215546Sopenharmony_ci * table 23.17, GL_TEXTURE_BINDING_2D_MULTISAMPLE and 573bf215546Sopenharmony_ci * GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY do not belong in the 574bf215546Sopenharmony_ci * texture attrib group. 575bf215546Sopenharmony_ci */ 576bf215546Sopenharmony_ci if (!is_msaa && texObj->Name != savedObj->Name) { 577bf215546Sopenharmony_ci /* We don't need to check whether the texture target is supported, 578bf215546Sopenharmony_ci * because we wouldn't get in this conditional block if it wasn't. 579bf215546Sopenharmony_ci */ 580bf215546Sopenharmony_ci _mesa_BindTexture_no_error(texObj->Target, savedObj->Name); 581bf215546Sopenharmony_ci texObj = _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt]; 582bf215546Sopenharmony_ci } 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci /* Default texture object states are restored separately below. */ 585bf215546Sopenharmony_ci if (texObj->Name == 0) 586bf215546Sopenharmony_ci continue; 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci /* But in the MSAA case, where the currently-bound object is not the 589bf215546Sopenharmony_ci * default state, we should still restore the saved default object's 590bf215546Sopenharmony_ci * data when that's what was saved initially. 591bf215546Sopenharmony_ci */ 592bf215546Sopenharmony_ci if (savedObj->Name == 0) 593bf215546Sopenharmony_ci savedObj = &texstate->SavedDefaultObj[tgt]; 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci if (!copy_texture_attribs(texObj, savedObj, tgt)) 596bf215546Sopenharmony_ci continue; 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci st_texture_release_all_sampler_views(st_context(ctx), texObj); 599bf215546Sopenharmony_ci } 600bf215546Sopenharmony_ci } 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci /* Restore textures in units that were not used before glPushAttrib (thus 603bf215546Sopenharmony_ci * they were not saved) but were used after glPushAttrib. Revert 604bf215546Sopenharmony_ci * the bindings to Name = 0. 605bf215546Sopenharmony_ci */ 606bf215546Sopenharmony_ci unsigned num_tex_changed = ctx->Texture.NumCurrentTexUsed; 607bf215546Sopenharmony_ci for (u = num_tex_saved; u < num_tex_changed; u++) { 608bf215546Sopenharmony_ci ctx->Texture.CurrentUnit = u; 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci for (gl_texture_index tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 611bf215546Sopenharmony_ci struct gl_texture_object *texObj = 612bf215546Sopenharmony_ci _mesa_get_tex_unit(ctx, u)->CurrentTex[tgt]; 613bf215546Sopenharmony_ci bool is_msaa = tgt == TEXTURE_2D_MULTISAMPLE_INDEX || 614bf215546Sopenharmony_ci tgt == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci /* According to the OpenGL 4.6 Compatibility Profile specification, 617bf215546Sopenharmony_ci * table 23.17, GL_TEXTURE_BINDING_2D_MULTISAMPLE and 618bf215546Sopenharmony_ci * GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY do not belong in the 619bf215546Sopenharmony_ci * texture attrib group. 620bf215546Sopenharmony_ci */ 621bf215546Sopenharmony_ci if (!is_msaa && texObj->Name != 0) { 622bf215546Sopenharmony_ci /* We don't need to check whether the texture target is supported, 623bf215546Sopenharmony_ci * because we wouldn't get in this conditional block if it wasn't. 624bf215546Sopenharmony_ci */ 625bf215546Sopenharmony_ci _mesa_BindTexture_no_error(texObj->Target, 0); 626bf215546Sopenharmony_ci } 627bf215546Sopenharmony_ci } 628bf215546Sopenharmony_ci } 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci /* Restore default texture object states. */ 631bf215546Sopenharmony_ci for (gl_texture_index tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 632bf215546Sopenharmony_ci struct gl_texture_object *dst = ctx->Shared->DefaultTex[tex]; 633bf215546Sopenharmony_ci const struct gl_texture_object *src = &texstate->SavedDefaultObj[tex]; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci copy_texture_attribs(dst, src, tex); 636bf215546Sopenharmony_ci } 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci _mesa_ActiveTexture(GL_TEXTURE0_ARB + texstate->CurrentUnit); 639bf215546Sopenharmony_ci _mesa_unlock_context_textures(ctx); 640bf215546Sopenharmony_ci} 641bf215546Sopenharmony_ci 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci#define TEST_AND_CALL1(FIELD, CALL) do { \ 644bf215546Sopenharmony_ci if (ctx->FIELD != attr->FIELD) \ 645bf215546Sopenharmony_ci _mesa_##CALL(attr->FIELD); \ 646bf215546Sopenharmony_ci } while (0) 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci#define TEST_AND_CALL1_SEL(FIELD, CALL, SEL) do { \ 649bf215546Sopenharmony_ci if (ctx->FIELD != attr->FIELD) \ 650bf215546Sopenharmony_ci _mesa_##CALL(SEL, attr->FIELD); \ 651bf215546Sopenharmony_ci } while (0) 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci#define TEST_AND_CALL2(FIELD1, FIELD2, CALL) do { \ 654bf215546Sopenharmony_ci if (ctx->FIELD1 != attr->FIELD1 || ctx->FIELD2 != attr->FIELD2) \ 655bf215546Sopenharmony_ci _mesa_##CALL(attr->FIELD1, attr->FIELD2); \ 656bf215546Sopenharmony_ci } while (0) 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci/* 660bf215546Sopenharmony_ci * This function is kind of long just because we have to call a lot 661bf215546Sopenharmony_ci * of device driver functions to update device driver state. 662bf215546Sopenharmony_ci * 663bf215546Sopenharmony_ci * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions 664bf215546Sopenharmony_ci * in order to restore GL state. This isn't terribly efficient but it 665bf215546Sopenharmony_ci * ensures that dirty flags and any derived state gets updated correctly. 666bf215546Sopenharmony_ci * We could at least check if the value to restore equals the current value 667bf215546Sopenharmony_ci * and then skip the Mesa call. 668bf215546Sopenharmony_ci */ 669bf215546Sopenharmony_civoid GLAPIENTRY 670bf215546Sopenharmony_ci_mesa_PopAttrib(void) 671bf215546Sopenharmony_ci{ 672bf215546Sopenharmony_ci struct gl_attrib_node *attr; 673bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 674bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci if (ctx->AttribStackDepth == 0) { 677bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopAttrib"); 678bf215546Sopenharmony_ci return; 679bf215546Sopenharmony_ci } 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci ctx->AttribStackDepth--; 682bf215546Sopenharmony_ci attr = ctx->AttribStack[ctx->AttribStackDepth]; 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci unsigned mask = attr->Mask; 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci /* Flush current attribs. This must be done before PopAttribState is 687bf215546Sopenharmony_ci * applied. 688bf215546Sopenharmony_ci */ 689bf215546Sopenharmony_ci if (mask & GL_CURRENT_BIT) 690bf215546Sopenharmony_ci FLUSH_CURRENT(ctx, 0); 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci /* Only restore states that have been changed since glPushAttrib. */ 693bf215546Sopenharmony_ci mask &= ctx->PopAttribState; 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci if (mask & GL_ACCUM_BUFFER_BIT) { 696bf215546Sopenharmony_ci _mesa_ClearAccum(attr->Accum.ClearColor[0], 697bf215546Sopenharmony_ci attr->Accum.ClearColor[1], 698bf215546Sopenharmony_ci attr->Accum.ClearColor[2], 699bf215546Sopenharmony_ci attr->Accum.ClearColor[3]); 700bf215546Sopenharmony_ci } 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci if (mask & GL_COLOR_BUFFER_BIT) { 703bf215546Sopenharmony_ci TEST_AND_CALL1(Color.ClearIndex, ClearIndex); 704bf215546Sopenharmony_ci _mesa_ClearColor(attr->Color.ClearColor.f[0], 705bf215546Sopenharmony_ci attr->Color.ClearColor.f[1], 706bf215546Sopenharmony_ci attr->Color.ClearColor.f[2], 707bf215546Sopenharmony_ci attr->Color.ClearColor.f[3]); 708bf215546Sopenharmony_ci TEST_AND_CALL1(Color.IndexMask, IndexMask); 709bf215546Sopenharmony_ci if (ctx->Color.ColorMask != attr->Color.ColorMask) { 710bf215546Sopenharmony_ci if (!ctx->Extensions.EXT_draw_buffers2) { 711bf215546Sopenharmony_ci _mesa_ColorMask(GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 0), 712bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 1), 713bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 2), 714bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, 0, 3)); 715bf215546Sopenharmony_ci } else { 716bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 717bf215546Sopenharmony_ci _mesa_ColorMaski(i, 718bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, i, 0), 719bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, i, 1), 720bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, i, 2), 721bf215546Sopenharmony_ci GET_COLORMASK_BIT(attr->Color.ColorMask, i, 3)); 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci } 724bf215546Sopenharmony_ci } 725bf215546Sopenharmony_ci if (memcmp(ctx->Color.DrawBuffer, attr->Color.DrawBuffer, 726bf215546Sopenharmony_ci sizeof(attr->Color.DrawBuffer))) { 727bf215546Sopenharmony_ci /* Need to determine if more than one color output is 728bf215546Sopenharmony_ci * specified. If so, call glDrawBuffersARB, else call 729bf215546Sopenharmony_ci * glDrawBuffer(). This is a subtle, but essential point 730bf215546Sopenharmony_ci * since GL_FRONT (for example) is illegal for the former 731bf215546Sopenharmony_ci * function, but legal for the later. 732bf215546Sopenharmony_ci */ 733bf215546Sopenharmony_ci GLboolean multipleBuffers = GL_FALSE; 734bf215546Sopenharmony_ci GLuint i; 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { 737bf215546Sopenharmony_ci if (attr->Color.DrawBuffer[i] != GL_NONE) { 738bf215546Sopenharmony_ci multipleBuffers = GL_TRUE; 739bf215546Sopenharmony_ci break; 740bf215546Sopenharmony_ci } 741bf215546Sopenharmony_ci } 742bf215546Sopenharmony_ci /* Call the API_level functions, not _mesa_drawbuffers() 743bf215546Sopenharmony_ci * since we need to do error checking on the pop'd 744bf215546Sopenharmony_ci * GL_DRAW_BUFFER. 745bf215546Sopenharmony_ci * Ex: if GL_FRONT were pushed, but we're popping with a 746bf215546Sopenharmony_ci * user FBO bound, GL_FRONT will be illegal and we'll need 747bf215546Sopenharmony_ci * to record that error. Per OpenGL ARB decision. 748bf215546Sopenharmony_ci */ 749bf215546Sopenharmony_ci if (multipleBuffers) { 750bf215546Sopenharmony_ci GLenum buffers[MAX_DRAW_BUFFERS]; 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) 753bf215546Sopenharmony_ci buffers[i] = attr->Color.DrawBuffer[i]; 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, buffers); 756bf215546Sopenharmony_ci } else { 757bf215546Sopenharmony_ci _mesa_DrawBuffer(attr->Color.DrawBuffer[0]); 758bf215546Sopenharmony_ci } 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.AlphaEnabled, attr->Color.AlphaEnabled, 761bf215546Sopenharmony_ci GL_ALPHA_TEST); 762bf215546Sopenharmony_ci TEST_AND_CALL2(Color.AlphaFunc, Color.AlphaRefUnclamped, AlphaFunc); 763bf215546Sopenharmony_ci if (ctx->Color.BlendEnabled != attr->Color.BlendEnabled) { 764bf215546Sopenharmony_ci if (ctx->Extensions.EXT_draw_buffers2) { 765bf215546Sopenharmony_ci for (unsigned i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 766bf215546Sopenharmony_ci TEST_AND_UPDATE_INDEX(ctx->Color.BlendEnabled, 767bf215546Sopenharmony_ci attr->Color.BlendEnabled, i, GL_BLEND); 768bf215546Sopenharmony_ci } 769bf215546Sopenharmony_ci } 770bf215546Sopenharmony_ci else { 771bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.BlendEnabled & 0x1, 772bf215546Sopenharmony_ci attr->Color.BlendEnabled & 0x1, GL_BLEND); 773bf215546Sopenharmony_ci } 774bf215546Sopenharmony_ci } 775bf215546Sopenharmony_ci if (ctx->Color._BlendFuncPerBuffer || 776bf215546Sopenharmony_ci ctx->Color._BlendEquationPerBuffer) { 777bf215546Sopenharmony_ci /* set blend per buffer */ 778bf215546Sopenharmony_ci GLuint buf; 779bf215546Sopenharmony_ci for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 780bf215546Sopenharmony_ci _mesa_BlendFuncSeparateiARB(buf, attr->Color.Blend[buf].SrcRGB, 781bf215546Sopenharmony_ci attr->Color.Blend[buf].DstRGB, 782bf215546Sopenharmony_ci attr->Color.Blend[buf].SrcA, 783bf215546Sopenharmony_ci attr->Color.Blend[buf].DstA); 784bf215546Sopenharmony_ci _mesa_BlendEquationSeparateiARB(buf, 785bf215546Sopenharmony_ci attr->Color.Blend[buf].EquationRGB, 786bf215546Sopenharmony_ci attr->Color.Blend[buf].EquationA); 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci } 789bf215546Sopenharmony_ci else { 790bf215546Sopenharmony_ci /* set same blend modes for all buffers */ 791bf215546Sopenharmony_ci _mesa_BlendFuncSeparate(attr->Color.Blend[0].SrcRGB, 792bf215546Sopenharmony_ci attr->Color.Blend[0].DstRGB, 793bf215546Sopenharmony_ci attr->Color.Blend[0].SrcA, 794bf215546Sopenharmony_ci attr->Color.Blend[0].DstA); 795bf215546Sopenharmony_ci /* This special case is because glBlendEquationSeparateEXT 796bf215546Sopenharmony_ci * cannot take GL_LOGIC_OP as a parameter. 797bf215546Sopenharmony_ci */ 798bf215546Sopenharmony_ci if (attr->Color.Blend[0].EquationRGB == 799bf215546Sopenharmony_ci attr->Color.Blend[0].EquationA) { 800bf215546Sopenharmony_ci TEST_AND_CALL1(Color.Blend[0].EquationRGB, BlendEquation); 801bf215546Sopenharmony_ci } 802bf215546Sopenharmony_ci else { 803bf215546Sopenharmony_ci TEST_AND_CALL2(Color.Blend[0].EquationRGB, 804bf215546Sopenharmony_ci Color.Blend[0].EquationA, BlendEquationSeparate); 805bf215546Sopenharmony_ci } 806bf215546Sopenharmony_ci } 807bf215546Sopenharmony_ci _mesa_BlendColor(attr->Color.BlendColorUnclamped[0], 808bf215546Sopenharmony_ci attr->Color.BlendColorUnclamped[1], 809bf215546Sopenharmony_ci attr->Color.BlendColorUnclamped[2], 810bf215546Sopenharmony_ci attr->Color.BlendColorUnclamped[3]); 811bf215546Sopenharmony_ci TEST_AND_CALL1(Color.LogicOp, LogicOp); 812bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, 813bf215546Sopenharmony_ci attr->Color.ColorLogicOpEnabled, GL_COLOR_LOGIC_OP); 814bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, 815bf215546Sopenharmony_ci attr->Color.IndexLogicOpEnabled, GL_INDEX_LOGIC_OP); 816bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.DitherFlag, attr->Color.DitherFlag, 817bf215546Sopenharmony_ci GL_DITHER); 818bf215546Sopenharmony_ci if (ctx->Extensions.ARB_color_buffer_float) { 819bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Color.ClampFragmentColor, ClampColor, 820bf215546Sopenharmony_ci GL_CLAMP_FRAGMENT_COLOR); 821bf215546Sopenharmony_ci } 822bf215546Sopenharmony_ci if (ctx->Extensions.ARB_color_buffer_float || ctx->Version >= 30) { 823bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Color.ClampReadColor, ClampColor, 824bf215546Sopenharmony_ci GL_CLAMP_READ_COLOR); 825bf215546Sopenharmony_ci } 826bf215546Sopenharmony_ci /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 827bf215546Sopenharmony_ci if (ctx->Extensions.EXT_framebuffer_sRGB) { 828bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Color.sRGBEnabled, attr->Color.sRGBEnabled, 829bf215546Sopenharmony_ci GL_FRAMEBUFFER_SRGB); 830bf215546Sopenharmony_ci } 831bf215546Sopenharmony_ci } 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci if (mask & GL_CURRENT_BIT) { 834bf215546Sopenharmony_ci memcpy(&ctx->Current, &attr->Current, 835bf215546Sopenharmony_ci sizeof(struct gl_current_attrib)); 836bf215546Sopenharmony_ci ctx->NewState |= _NEW_CURRENT_ATTRIB; 837bf215546Sopenharmony_ci } 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci if (mask & GL_DEPTH_BUFFER_BIT) { 840bf215546Sopenharmony_ci TEST_AND_CALL1(Depth.Func, DepthFunc); 841bf215546Sopenharmony_ci TEST_AND_CALL1(Depth.Clear, ClearDepth); 842bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Depth.Test, attr->Depth.Test, GL_DEPTH_TEST); 843bf215546Sopenharmony_ci TEST_AND_CALL1(Depth.Mask, DepthMask); 844bf215546Sopenharmony_ci if (ctx->Extensions.EXT_depth_bounds_test) { 845bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Depth.BoundsTest, attr->Depth.BoundsTest, 846bf215546Sopenharmony_ci GL_DEPTH_BOUNDS_TEST_EXT); 847bf215546Sopenharmony_ci TEST_AND_CALL2(Depth.BoundsMin, Depth.BoundsMax, DepthBoundsEXT); 848bf215546Sopenharmony_ci } 849bf215546Sopenharmony_ci } 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci if (mask & GL_ENABLE_BIT) 852bf215546Sopenharmony_ci pop_enable_group(ctx, &attr->Enable); 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci if (mask & GL_EVAL_BIT) { 855bf215546Sopenharmony_ci memcpy(&ctx->Eval, &attr->Eval, sizeof(struct gl_eval_attrib)); 856bf215546Sopenharmony_ci vbo_exec_update_eval_maps(ctx); 857bf215546Sopenharmony_ci } 858bf215546Sopenharmony_ci 859bf215546Sopenharmony_ci if (mask & GL_FOG_BIT) { 860bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Fog.Enabled, attr->Fog.Enabled, GL_FOG); 861bf215546Sopenharmony_ci _mesa_Fogfv(GL_FOG_COLOR, attr->Fog.Color); 862bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Fog.Density, Fogf, GL_FOG_DENSITY); 863bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Fog.Start, Fogf, GL_FOG_START); 864bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Fog.End, Fogf, GL_FOG_END); 865bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Fog.Index, Fogf, GL_FOG_INDEX); 866bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Fog.Mode, Fogi, GL_FOG_MODE); 867bf215546Sopenharmony_ci } 868bf215546Sopenharmony_ci 869bf215546Sopenharmony_ci if (mask & GL_HINT_BIT) { 870bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.PerspectiveCorrection, Hint, GL_PERSPECTIVE_CORRECTION_HINT); 871bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.PointSmooth, Hint, GL_POINT_SMOOTH_HINT); 872bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.LineSmooth, Hint, GL_LINE_SMOOTH_HINT); 873bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.PolygonSmooth, Hint, GL_POLYGON_SMOOTH_HINT); 874bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.Fog, Hint, GL_FOG_HINT); 875bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Hint.TextureCompression, Hint, GL_TEXTURE_COMPRESSION_HINT_ARB); 876bf215546Sopenharmony_ci } 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci if (mask & GL_LIGHTING_BIT) { 879bf215546Sopenharmony_ci GLuint i; 880bf215546Sopenharmony_ci /* lighting enable */ 881bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Light.Enabled, attr->Light.Enabled, GL_LIGHTING); 882bf215546Sopenharmony_ci /* per-light state */ 883bf215546Sopenharmony_ci if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) 884bf215546Sopenharmony_ci _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_ci /* Fast path for other drivers. */ 887bf215546Sopenharmony_ci ctx->NewState |= _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM; 888bf215546Sopenharmony_ci 889bf215546Sopenharmony_ci memcpy(ctx->Light.LightSource, attr->Light.LightSource, 890bf215546Sopenharmony_ci sizeof(attr->Light.LightSource)); 891bf215546Sopenharmony_ci memcpy(&ctx->Light.Model, &attr->Light.Model, 892bf215546Sopenharmony_ci sizeof(attr->Light.Model)); 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxLights; i++) { 895bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Light.Light[i].Enabled, 896bf215546Sopenharmony_ci attr->Light.Light[i].Enabled, 897bf215546Sopenharmony_ci GL_LIGHT0 + i); 898bf215546Sopenharmony_ci memcpy(&ctx->Light.Light[i], &attr->Light.Light[i], 899bf215546Sopenharmony_ci sizeof(struct gl_light)); 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci /* shade model */ 902bf215546Sopenharmony_ci TEST_AND_CALL1(Light.ShadeModel, ShadeModel); 903bf215546Sopenharmony_ci /* color material */ 904bf215546Sopenharmony_ci TEST_AND_CALL2(Light.ColorMaterialFace, Light.ColorMaterialMode, 905bf215546Sopenharmony_ci ColorMaterial); 906bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, 907bf215546Sopenharmony_ci attr->Light.ColorMaterialEnabled, GL_COLOR_MATERIAL); 908bf215546Sopenharmony_ci /* Shininess material is used by the fixed-func vertex program. */ 909bf215546Sopenharmony_ci ctx->NewState |= _NEW_MATERIAL | _NEW_FF_VERT_PROGRAM; 910bf215546Sopenharmony_ci memcpy(&ctx->Light.Material, &attr->Light.Material, 911bf215546Sopenharmony_ci sizeof(struct gl_material)); 912bf215546Sopenharmony_ci if (ctx->Extensions.ARB_color_buffer_float) { 913bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Light.ClampVertexColor, ClampColor, GL_CLAMP_VERTEX_COLOR_ARB); 914bf215546Sopenharmony_ci } 915bf215546Sopenharmony_ci } 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci if (mask & GL_LINE_BIT) { 918bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Line.SmoothFlag, attr->Line.SmoothFlag, GL_LINE_SMOOTH); 919bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Line.StippleFlag, attr->Line.StippleFlag, GL_LINE_STIPPLE); 920bf215546Sopenharmony_ci TEST_AND_CALL2(Line.StippleFactor, Line.StipplePattern, LineStipple); 921bf215546Sopenharmony_ci TEST_AND_CALL1(Line.Width, LineWidth); 922bf215546Sopenharmony_ci } 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci if (mask & GL_LIST_BIT) 925bf215546Sopenharmony_ci memcpy(&ctx->List, &attr->List, sizeof(struct gl_list_attrib)); 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci if (mask & GL_PIXEL_MODE_BIT) { 928bf215546Sopenharmony_ci memcpy(&ctx->Pixel, &attr->Pixel, sizeof(struct gl_pixel_attrib)); 929bf215546Sopenharmony_ci /* XXX what other pixel state needs to be set by function calls? */ 930bf215546Sopenharmony_ci _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); 931bf215546Sopenharmony_ci ctx->NewState |= _NEW_PIXEL; 932bf215546Sopenharmony_ci } 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci if (mask & GL_POINT_BIT) { 935bf215546Sopenharmony_ci TEST_AND_CALL1(Point.Size, PointSize); 936bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Point.SmoothFlag, attr->Point.SmoothFlag, GL_POINT_SMOOTH); 937bf215546Sopenharmony_ci _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, attr->Point.Params); 938bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Point.MinSize, PointParameterf, GL_POINT_SIZE_MIN_EXT); 939bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Point.MaxSize, PointParameterf, GL_POINT_SIZE_MAX_EXT); 940bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Point.Threshold, PointParameterf, GL_POINT_FADE_THRESHOLD_SIZE_EXT); 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci if (ctx->Extensions.ARB_point_sprite) { 943bf215546Sopenharmony_ci if (ctx->Point.CoordReplace != attr->Point.CoordReplace) { 944bf215546Sopenharmony_ci ctx->NewState |= _NEW_POINT | _NEW_FF_VERT_PROGRAM; 945bf215546Sopenharmony_ci ctx->Point.CoordReplace = attr->Point.CoordReplace; 946bf215546Sopenharmony_ci } 947bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Point.PointSprite, attr->Point.PointSprite, 948bf215546Sopenharmony_ci GL_POINT_SPRITE); 949bf215546Sopenharmony_ci 950bf215546Sopenharmony_ci if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20) 951bf215546Sopenharmony_ci || ctx->API == API_OPENGL_CORE) 952bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Point.SpriteOrigin, PointParameterf, GL_POINT_SPRITE_COORD_ORIGIN); 953bf215546Sopenharmony_ci } 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci if (mask & GL_POLYGON_BIT) { 957bf215546Sopenharmony_ci TEST_AND_CALL1(Polygon.CullFaceMode, CullFace); 958bf215546Sopenharmony_ci TEST_AND_CALL1(Polygon.FrontFace, FrontFace); 959bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Polygon.FrontMode, PolygonMode, GL_FRONT); 960bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Polygon.BackMode, PolygonMode, GL_BACK); 961bf215546Sopenharmony_ci _mesa_polygon_offset_clamp(ctx, 962bf215546Sopenharmony_ci attr->Polygon.OffsetFactor, 963bf215546Sopenharmony_ci attr->Polygon.OffsetUnits, 964bf215546Sopenharmony_ci attr->Polygon.OffsetClamp); 965bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, attr->Polygon.SmoothFlag, GL_POLYGON_SMOOTH); 966bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.StippleFlag, attr->Polygon.StippleFlag, GL_POLYGON_STIPPLE); 967bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.CullFlag, attr->Polygon.CullFlag, GL_CULL_FACE); 968bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, attr->Polygon.OffsetPoint, 969bf215546Sopenharmony_ci GL_POLYGON_OFFSET_POINT); 970bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetLine, attr->Polygon.OffsetLine, 971bf215546Sopenharmony_ci GL_POLYGON_OFFSET_LINE); 972bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Polygon.OffsetFill, attr->Polygon.OffsetFill, 973bf215546Sopenharmony_ci GL_POLYGON_OFFSET_FILL); 974bf215546Sopenharmony_ci } 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci if (mask & GL_POLYGON_STIPPLE_BIT) { 977bf215546Sopenharmony_ci memcpy(ctx->PolygonStipple, attr->PolygonStipple, 32*sizeof(GLuint)); 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci ctx->NewDriverState |= ST_NEW_POLY_STIPPLE; 980bf215546Sopenharmony_ci } 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci if (mask & GL_SCISSOR_BIT) { 983bf215546Sopenharmony_ci unsigned i; 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxViewports; i++) { 986bf215546Sopenharmony_ci _mesa_set_scissor(ctx, i, 987bf215546Sopenharmony_ci attr->Scissor.ScissorArray[i].X, 988bf215546Sopenharmony_ci attr->Scissor.ScissorArray[i].Y, 989bf215546Sopenharmony_ci attr->Scissor.ScissorArray[i].Width, 990bf215546Sopenharmony_ci attr->Scissor.ScissorArray[i].Height); 991bf215546Sopenharmony_ci TEST_AND_UPDATE_INDEX(ctx->Scissor.EnableFlags, 992bf215546Sopenharmony_ci attr->Scissor.EnableFlags, i, GL_SCISSOR_TEST); 993bf215546Sopenharmony_ci } 994bf215546Sopenharmony_ci if (ctx->Extensions.EXT_window_rectangles) { 995bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(struct gl_scissor_rect) == 996bf215546Sopenharmony_ci 4 * sizeof(GLint)); 997bf215546Sopenharmony_ci _mesa_WindowRectanglesEXT( 998bf215546Sopenharmony_ci attr->Scissor.WindowRectMode, attr->Scissor.NumWindowRects, 999bf215546Sopenharmony_ci (const GLint *)attr->Scissor.WindowRects); 1000bf215546Sopenharmony_ci } 1001bf215546Sopenharmony_ci } 1002bf215546Sopenharmony_ci 1003bf215546Sopenharmony_ci if (mask & GL_STENCIL_BUFFER_BIT) { 1004bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Stencil.Enabled, attr->Stencil.Enabled, 1005bf215546Sopenharmony_ci GL_STENCIL_TEST); 1006bf215546Sopenharmony_ci TEST_AND_CALL1(Stencil.Clear, ClearStencil); 1007bf215546Sopenharmony_ci if (ctx->Extensions.EXT_stencil_two_side) { 1008bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, attr->Stencil.TestTwoSide, 1009bf215546Sopenharmony_ci GL_STENCIL_TEST_TWO_SIDE_EXT); 1010bf215546Sopenharmony_ci _mesa_ActiveStencilFaceEXT(attr->Stencil.ActiveFace 1011bf215546Sopenharmony_ci ? GL_BACK : GL_FRONT); 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci /* front state */ 1014bf215546Sopenharmony_ci _mesa_StencilFuncSeparate(GL_FRONT, 1015bf215546Sopenharmony_ci attr->Stencil.Function[0], 1016bf215546Sopenharmony_ci attr->Stencil.Ref[0], 1017bf215546Sopenharmony_ci attr->Stencil.ValueMask[0]); 1018bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Stencil.WriteMask[0], StencilMaskSeparate, GL_FRONT); 1019bf215546Sopenharmony_ci _mesa_StencilOpSeparate(GL_FRONT, attr->Stencil.FailFunc[0], 1020bf215546Sopenharmony_ci attr->Stencil.ZFailFunc[0], 1021bf215546Sopenharmony_ci attr->Stencil.ZPassFunc[0]); 1022bf215546Sopenharmony_ci /* back state */ 1023bf215546Sopenharmony_ci _mesa_StencilFuncSeparate(GL_BACK, 1024bf215546Sopenharmony_ci attr->Stencil.Function[1], 1025bf215546Sopenharmony_ci attr->Stencil.Ref[1], 1026bf215546Sopenharmony_ci attr->Stencil.ValueMask[1]); 1027bf215546Sopenharmony_ci TEST_AND_CALL1_SEL(Stencil.WriteMask[1], StencilMaskSeparate, GL_BACK); 1028bf215546Sopenharmony_ci _mesa_StencilOpSeparate(GL_BACK, attr->Stencil.FailFunc[1], 1029bf215546Sopenharmony_ci attr->Stencil.ZFailFunc[1], 1030bf215546Sopenharmony_ci attr->Stencil.ZPassFunc[1]); 1031bf215546Sopenharmony_ci } 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ci if (mask & GL_TRANSFORM_BIT) { 1034bf215546Sopenharmony_ci GLuint i; 1035bf215546Sopenharmony_ci TEST_AND_CALL1(Transform.MatrixMode, MatrixMode); 1036bf215546Sopenharmony_ci if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) 1037bf215546Sopenharmony_ci _math_matrix_analyse(ctx->ProjectionMatrixStack.Top); 1038bf215546Sopenharmony_ci 1039bf215546Sopenharmony_ci ctx->NewState |= _NEW_TRANSFORM; 1040bf215546Sopenharmony_ci ctx->NewDriverState |= ST_NEW_CLIP_STATE; 1041bf215546Sopenharmony_ci 1042bf215546Sopenharmony_ci /* restore clip planes */ 1043bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 1044bf215546Sopenharmony_ci const GLfloat *eyePlane = attr->Transform.EyeUserPlane[i]; 1045bf215546Sopenharmony_ci COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); 1046bf215546Sopenharmony_ci TEST_AND_UPDATE_BIT(ctx->Transform.ClipPlanesEnabled, 1047bf215546Sopenharmony_ci attr->Transform.ClipPlanesEnabled, i, 1048bf215546Sopenharmony_ci GL_CLIP_PLANE0 + i); 1049bf215546Sopenharmony_ci } 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci /* normalize/rescale */ 1052bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.Normalize, attr->Transform.Normalize, 1053bf215546Sopenharmony_ci GL_NORMALIZE); 1054bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.RescaleNormals, 1055bf215546Sopenharmony_ci attr->Transform.RescaleNormals, GL_RESCALE_NORMAL_EXT); 1056bf215546Sopenharmony_ci 1057bf215546Sopenharmony_ci if (!ctx->Extensions.AMD_depth_clamp_separate) { 1058bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampNear && 1059bf215546Sopenharmony_ci ctx->Transform.DepthClampFar, 1060bf215546Sopenharmony_ci attr->Transform.DepthClampNear && 1061bf215546Sopenharmony_ci attr->Transform.DepthClampFar, GL_DEPTH_CLAMP); 1062bf215546Sopenharmony_ci } else { 1063bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampNear, 1064bf215546Sopenharmony_ci attr->Transform.DepthClampNear, 1065bf215546Sopenharmony_ci GL_DEPTH_CLAMP_NEAR_AMD); 1066bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Transform.DepthClampFar, 1067bf215546Sopenharmony_ci attr->Transform.DepthClampFar, 1068bf215546Sopenharmony_ci GL_DEPTH_CLAMP_FAR_AMD); 1069bf215546Sopenharmony_ci } 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci if (ctx->Extensions.ARB_clip_control) { 1072bf215546Sopenharmony_ci TEST_AND_CALL2(Transform.ClipOrigin, Transform.ClipDepthMode, 1073bf215546Sopenharmony_ci ClipControl); 1074bf215546Sopenharmony_ci } 1075bf215546Sopenharmony_ci } 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci if (mask & GL_TEXTURE_BIT) { 1078bf215546Sopenharmony_ci pop_texture_group(ctx, &attr->Texture); 1079bf215546Sopenharmony_ci ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | 1080bf215546Sopenharmony_ci _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM; 1081bf215546Sopenharmony_ci } 1082bf215546Sopenharmony_ci 1083bf215546Sopenharmony_ci if (mask & GL_VIEWPORT_BIT) { 1084bf215546Sopenharmony_ci unsigned i; 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxViewports; i++) { 1087bf215546Sopenharmony_ci const struct gl_viewport_attrib *vp = &attr->Viewport.ViewportArray[i]; 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci if (memcmp(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6)) { 1090bf215546Sopenharmony_ci ctx->NewState |= _NEW_VIEWPORT; 1091bf215546Sopenharmony_ci ctx->NewDriverState |= ST_NEW_VIEWPORT; 1092bf215546Sopenharmony_ci 1093bf215546Sopenharmony_ci memcpy(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6); 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci if (ctx->invalidate_on_gl_viewport) 1096bf215546Sopenharmony_ci st_manager_invalidate_drawables(ctx); 1097bf215546Sopenharmony_ci } 1098bf215546Sopenharmony_ci } 1099bf215546Sopenharmony_ci 1100bf215546Sopenharmony_ci if (ctx->Extensions.NV_conservative_raster) { 1101bf215546Sopenharmony_ci GLuint biasx = attr->Viewport.SubpixelPrecisionBias[0]; 1102bf215546Sopenharmony_ci GLuint biasy = attr->Viewport.SubpixelPrecisionBias[1]; 1103bf215546Sopenharmony_ci _mesa_SubpixelPrecisionBiasNV(biasx, biasy); 1104bf215546Sopenharmony_ci } 1105bf215546Sopenharmony_ci } 1106bf215546Sopenharmony_ci 1107bf215546Sopenharmony_ci if (mask & GL_MULTISAMPLE_BIT_ARB) { 1108bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.Enabled, 1109bf215546Sopenharmony_ci attr->Multisample.Enabled, 1110bf215546Sopenharmony_ci GL_MULTISAMPLE); 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 1113bf215546Sopenharmony_ci attr->Multisample.SampleCoverage, 1114bf215546Sopenharmony_ci GL_SAMPLE_COVERAGE); 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 1117bf215546Sopenharmony_ci attr->Multisample.SampleAlphaToCoverage, 1118bf215546Sopenharmony_ci GL_SAMPLE_ALPHA_TO_COVERAGE); 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 1121bf215546Sopenharmony_ci attr->Multisample.SampleAlphaToOne, 1122bf215546Sopenharmony_ci GL_SAMPLE_ALPHA_TO_ONE); 1123bf215546Sopenharmony_ci 1124bf215546Sopenharmony_ci TEST_AND_CALL2(Multisample.SampleCoverageValue, 1125bf215546Sopenharmony_ci Multisample.SampleCoverageInvert, SampleCoverage); 1126bf215546Sopenharmony_ci 1127bf215546Sopenharmony_ci TEST_AND_CALL1(Multisample.SampleAlphaToCoverageDitherControl, 1128bf215546Sopenharmony_ci AlphaToCoverageDitherControlNV); 1129bf215546Sopenharmony_ci } 1130bf215546Sopenharmony_ci 1131bf215546Sopenharmony_ci ctx->PopAttribState = attr->OldPopAttribStateMask; 1132bf215546Sopenharmony_ci} 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci 1135bf215546Sopenharmony_ci/** 1136bf215546Sopenharmony_ci * Copy gl_pixelstore_attrib from src to dst, updating buffer 1137bf215546Sopenharmony_ci * object refcounts. 1138bf215546Sopenharmony_ci */ 1139bf215546Sopenharmony_cistatic void 1140bf215546Sopenharmony_cicopy_pixelstore(struct gl_context *ctx, 1141bf215546Sopenharmony_ci struct gl_pixelstore_attrib *dst, 1142bf215546Sopenharmony_ci const struct gl_pixelstore_attrib *src) 1143bf215546Sopenharmony_ci{ 1144bf215546Sopenharmony_ci dst->Alignment = src->Alignment; 1145bf215546Sopenharmony_ci dst->RowLength = src->RowLength; 1146bf215546Sopenharmony_ci dst->SkipPixels = src->SkipPixels; 1147bf215546Sopenharmony_ci dst->SkipRows = src->SkipRows; 1148bf215546Sopenharmony_ci dst->ImageHeight = src->ImageHeight; 1149bf215546Sopenharmony_ci dst->SkipImages = src->SkipImages; 1150bf215546Sopenharmony_ci dst->SwapBytes = src->SwapBytes; 1151bf215546Sopenharmony_ci dst->LsbFirst = src->LsbFirst; 1152bf215546Sopenharmony_ci dst->Invert = src->Invert; 1153bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1154bf215546Sopenharmony_ci} 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci#define GL_CLIENT_PACK_BIT (1<<20) 1158bf215546Sopenharmony_ci#define GL_CLIENT_UNPACK_BIT (1<<21) 1159bf215546Sopenharmony_ci 1160bf215546Sopenharmony_cistatic void 1161bf215546Sopenharmony_cicopy_vertex_attrib_array(struct gl_context *ctx, 1162bf215546Sopenharmony_ci struct gl_array_attributes *dst, 1163bf215546Sopenharmony_ci const struct gl_array_attributes *src) 1164bf215546Sopenharmony_ci{ 1165bf215546Sopenharmony_ci dst->Ptr = src->Ptr; 1166bf215546Sopenharmony_ci dst->RelativeOffset = src->RelativeOffset; 1167bf215546Sopenharmony_ci dst->Format = src->Format; 1168bf215546Sopenharmony_ci dst->Stride = src->Stride; 1169bf215546Sopenharmony_ci dst->BufferBindingIndex = src->BufferBindingIndex; 1170bf215546Sopenharmony_ci dst->_EffBufferBindingIndex = src->_EffBufferBindingIndex; 1171bf215546Sopenharmony_ci dst->_EffRelativeOffset = src->_EffRelativeOffset; 1172bf215546Sopenharmony_ci} 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_cistatic void 1175bf215546Sopenharmony_cicopy_vertex_buffer_binding(struct gl_context *ctx, 1176bf215546Sopenharmony_ci struct gl_vertex_buffer_binding *dst, 1177bf215546Sopenharmony_ci const struct gl_vertex_buffer_binding *src) 1178bf215546Sopenharmony_ci{ 1179bf215546Sopenharmony_ci dst->Offset = src->Offset; 1180bf215546Sopenharmony_ci dst->Stride = src->Stride; 1181bf215546Sopenharmony_ci dst->InstanceDivisor = src->InstanceDivisor; 1182bf215546Sopenharmony_ci dst->_BoundArrays = src->_BoundArrays; 1183bf215546Sopenharmony_ci dst->_EffBoundArrays = src->_EffBoundArrays; 1184bf215546Sopenharmony_ci dst->_EffOffset = src->_EffOffset; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1187bf215546Sopenharmony_ci} 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci/** 1190bf215546Sopenharmony_ci * Copy gl_vertex_array_object from src to dest. 1191bf215546Sopenharmony_ci * 'dest' must be in an initialized state. 1192bf215546Sopenharmony_ci */ 1193bf215546Sopenharmony_cistatic void 1194bf215546Sopenharmony_cicopy_array_object(struct gl_context *ctx, 1195bf215546Sopenharmony_ci struct gl_vertex_array_object *dest, 1196bf215546Sopenharmony_ci struct gl_vertex_array_object *src, 1197bf215546Sopenharmony_ci unsigned copy_attrib_mask) 1198bf215546Sopenharmony_ci{ 1199bf215546Sopenharmony_ci /* skip Name */ 1200bf215546Sopenharmony_ci /* skip RefCount */ 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_ci while (copy_attrib_mask) { 1203bf215546Sopenharmony_ci unsigned i = u_bit_scan(©_attrib_mask); 1204bf215546Sopenharmony_ci 1205bf215546Sopenharmony_ci copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]); 1206bf215546Sopenharmony_ci copy_vertex_buffer_binding(ctx, &dest->BufferBinding[i], &src->BufferBinding[i]); 1207bf215546Sopenharmony_ci } 1208bf215546Sopenharmony_ci 1209bf215546Sopenharmony_ci /* Enabled must be the same than on push */ 1210bf215546Sopenharmony_ci dest->Enabled = src->Enabled; 1211bf215546Sopenharmony_ci dest->_EnabledWithMapMode = src->_EnabledWithMapMode; 1212bf215546Sopenharmony_ci dest->_EffEnabledVBO = src->_EffEnabledVBO; 1213bf215546Sopenharmony_ci dest->_EffEnabledNonZeroDivisor = src->_EffEnabledNonZeroDivisor; 1214bf215546Sopenharmony_ci /* The bitmask of bound VBOs needs to match the VertexBinding array */ 1215bf215546Sopenharmony_ci dest->VertexAttribBufferMask = src->VertexAttribBufferMask; 1216bf215546Sopenharmony_ci dest->NonZeroDivisorMask = src->NonZeroDivisorMask; 1217bf215546Sopenharmony_ci dest->_AttributeMapMode = src->_AttributeMapMode; 1218bf215546Sopenharmony_ci dest->NewVertexBuffers = src->NewVertexBuffers; 1219bf215546Sopenharmony_ci dest->NewVertexElements = src->NewVertexElements; 1220bf215546Sopenharmony_ci /* skip NumUpdates and IsDynamic because they can only increase, not decrease */ 1221bf215546Sopenharmony_ci} 1222bf215546Sopenharmony_ci 1223bf215546Sopenharmony_ci/** 1224bf215546Sopenharmony_ci * Copy gl_array_attrib from src to dest. 1225bf215546Sopenharmony_ci * 'dest' must be in an initialized state. 1226bf215546Sopenharmony_ci */ 1227bf215546Sopenharmony_cistatic void 1228bf215546Sopenharmony_cicopy_array_attrib(struct gl_context *ctx, 1229bf215546Sopenharmony_ci struct gl_array_attrib *dest, 1230bf215546Sopenharmony_ci struct gl_array_attrib *src, 1231bf215546Sopenharmony_ci bool vbo_deleted, 1232bf215546Sopenharmony_ci unsigned copy_attrib_mask) 1233bf215546Sopenharmony_ci{ 1234bf215546Sopenharmony_ci /* skip ArrayObj */ 1235bf215546Sopenharmony_ci /* skip DefaultArrayObj, Objects */ 1236bf215546Sopenharmony_ci dest->ActiveTexture = src->ActiveTexture; 1237bf215546Sopenharmony_ci dest->LockFirst = src->LockFirst; 1238bf215546Sopenharmony_ci dest->LockCount = src->LockCount; 1239bf215546Sopenharmony_ci dest->PrimitiveRestart = src->PrimitiveRestart; 1240bf215546Sopenharmony_ci dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex; 1241bf215546Sopenharmony_ci dest->RestartIndex = src->RestartIndex; 1242bf215546Sopenharmony_ci memcpy(dest->_PrimitiveRestart, src->_PrimitiveRestart, 1243bf215546Sopenharmony_ci sizeof(src->_PrimitiveRestart)); 1244bf215546Sopenharmony_ci memcpy(dest->_RestartIndex, src->_RestartIndex, sizeof(src->_RestartIndex)); 1245bf215546Sopenharmony_ci /* skip NewState */ 1246bf215546Sopenharmony_ci /* skip RebindArrays */ 1247bf215546Sopenharmony_ci 1248bf215546Sopenharmony_ci if (!vbo_deleted) 1249bf215546Sopenharmony_ci copy_array_object(ctx, dest->VAO, src->VAO, copy_attrib_mask); 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci /* skip ArrayBufferObj */ 1252bf215546Sopenharmony_ci /* skip IndexBufferObj */ 1253bf215546Sopenharmony_ci} 1254bf215546Sopenharmony_ci 1255bf215546Sopenharmony_ci/** 1256bf215546Sopenharmony_ci * Save the content of src to dest. 1257bf215546Sopenharmony_ci */ 1258bf215546Sopenharmony_cistatic void 1259bf215546Sopenharmony_cisave_array_attrib(struct gl_context *ctx, 1260bf215546Sopenharmony_ci struct gl_array_attrib *dest, 1261bf215546Sopenharmony_ci struct gl_array_attrib *src) 1262bf215546Sopenharmony_ci{ 1263bf215546Sopenharmony_ci /* Set the Name, needed for restore, but do never overwrite. 1264bf215546Sopenharmony_ci * Needs to match value in the object hash. */ 1265bf215546Sopenharmony_ci dest->VAO->Name = src->VAO->Name; 1266bf215546Sopenharmony_ci dest->VAO->NonDefaultStateMask = src->VAO->NonDefaultStateMask; 1267bf215546Sopenharmony_ci /* And copy all of the rest. */ 1268bf215546Sopenharmony_ci copy_array_attrib(ctx, dest, src, false, src->VAO->NonDefaultStateMask); 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci /* Just reference them here */ 1271bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, 1272bf215546Sopenharmony_ci src->ArrayBufferObj); 1273bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj, 1274bf215546Sopenharmony_ci src->VAO->IndexBufferObj); 1275bf215546Sopenharmony_ci} 1276bf215546Sopenharmony_ci 1277bf215546Sopenharmony_ci/** 1278bf215546Sopenharmony_ci * Restore the content of src to dest. 1279bf215546Sopenharmony_ci */ 1280bf215546Sopenharmony_cistatic void 1281bf215546Sopenharmony_cirestore_array_attrib(struct gl_context *ctx, 1282bf215546Sopenharmony_ci struct gl_array_attrib *dest, 1283bf215546Sopenharmony_ci struct gl_array_attrib *src) 1284bf215546Sopenharmony_ci{ 1285bf215546Sopenharmony_ci bool is_vao_name_zero = src->VAO->Name == 0; 1286bf215546Sopenharmony_ci 1287bf215546Sopenharmony_ci /* The ARB_vertex_array_object spec says: 1288bf215546Sopenharmony_ci * 1289bf215546Sopenharmony_ci * "BindVertexArray fails and an INVALID_OPERATION error is generated 1290bf215546Sopenharmony_ci * if array is not a name returned from a previous call to 1291bf215546Sopenharmony_ci * GenVertexArrays, or if such a name has since been deleted with 1292bf215546Sopenharmony_ci * DeleteVertexArrays." 1293bf215546Sopenharmony_ci * 1294bf215546Sopenharmony_ci * Therefore popping a deleted VAO cannot magically recreate it. 1295bf215546Sopenharmony_ci */ 1296bf215546Sopenharmony_ci if (!is_vao_name_zero && !_mesa_IsVertexArray(src->VAO->Name)) 1297bf215546Sopenharmony_ci return; 1298bf215546Sopenharmony_ci 1299bf215546Sopenharmony_ci _mesa_BindVertexArray(src->VAO->Name); 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci /* Restore or recreate the buffer objects by the names ... */ 1302bf215546Sopenharmony_ci if (is_vao_name_zero || !src->ArrayBufferObj || 1303bf215546Sopenharmony_ci _mesa_IsBuffer(src->ArrayBufferObj->Name)) { 1304bf215546Sopenharmony_ci /* ... and restore its content */ 1305bf215546Sopenharmony_ci dest->VAO->NonDefaultStateMask |= src->VAO->NonDefaultStateMask; 1306bf215546Sopenharmony_ci copy_array_attrib(ctx, dest, src, false, 1307bf215546Sopenharmony_ci dest->VAO->NonDefaultStateMask); 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, 1310bf215546Sopenharmony_ci src->ArrayBufferObj ? 1311bf215546Sopenharmony_ci src->ArrayBufferObj->Name : 0); 1312bf215546Sopenharmony_ci } else { 1313bf215546Sopenharmony_ci copy_array_attrib(ctx, dest, src, true, 0); 1314bf215546Sopenharmony_ci } 1315bf215546Sopenharmony_ci 1316bf215546Sopenharmony_ci /* Invalidate array state. It will be updated during the next draw. */ 1317bf215546Sopenharmony_ci _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); 1318bf215546Sopenharmony_ci 1319bf215546Sopenharmony_ci if (is_vao_name_zero || !src->VAO->IndexBufferObj || 1320bf215546Sopenharmony_ci _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) { 1321bf215546Sopenharmony_ci _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 1322bf215546Sopenharmony_ci src->VAO->IndexBufferObj ? 1323bf215546Sopenharmony_ci src->VAO->IndexBufferObj->Name : 0); 1324bf215546Sopenharmony_ci } 1325bf215546Sopenharmony_ci} 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_ci 1328bf215546Sopenharmony_civoid GLAPIENTRY 1329bf215546Sopenharmony_ci_mesa_PushClientAttrib(GLbitfield mask) 1330bf215546Sopenharmony_ci{ 1331bf215546Sopenharmony_ci struct gl_client_attrib_node *head; 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1334bf215546Sopenharmony_ci 1335bf215546Sopenharmony_ci if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { 1336bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushClientAttrib"); 1337bf215546Sopenharmony_ci return; 1338bf215546Sopenharmony_ci } 1339bf215546Sopenharmony_ci 1340bf215546Sopenharmony_ci head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 1341bf215546Sopenharmony_ci head->Mask = mask; 1342bf215546Sopenharmony_ci 1343bf215546Sopenharmony_ci if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 1344bf215546Sopenharmony_ci copy_pixelstore(ctx, &head->Pack, &ctx->Pack); 1345bf215546Sopenharmony_ci copy_pixelstore(ctx, &head->Unpack, &ctx->Unpack); 1346bf215546Sopenharmony_ci } 1347bf215546Sopenharmony_ci 1348bf215546Sopenharmony_ci if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1349bf215546Sopenharmony_ci _mesa_initialize_vao(ctx, &head->VAO, 0); 1350bf215546Sopenharmony_ci /* Use the VAO declared within the node instead of allocating it. */ 1351bf215546Sopenharmony_ci head->Array.VAO = &head->VAO; 1352bf215546Sopenharmony_ci save_array_attrib(ctx, &head->Array, &ctx->Array); 1353bf215546Sopenharmony_ci } 1354bf215546Sopenharmony_ci 1355bf215546Sopenharmony_ci ctx->ClientAttribStackDepth++; 1356bf215546Sopenharmony_ci} 1357bf215546Sopenharmony_ci 1358bf215546Sopenharmony_ci 1359bf215546Sopenharmony_civoid GLAPIENTRY 1360bf215546Sopenharmony_ci_mesa_PopClientAttrib(void) 1361bf215546Sopenharmony_ci{ 1362bf215546Sopenharmony_ci struct gl_client_attrib_node *head; 1363bf215546Sopenharmony_ci 1364bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1365bf215546Sopenharmony_ci 1366bf215546Sopenharmony_ci if (ctx->ClientAttribStackDepth == 0) { 1367bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib"); 1368bf215546Sopenharmony_ci return; 1369bf215546Sopenharmony_ci } 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci ctx->ClientAttribStackDepth--; 1372bf215546Sopenharmony_ci head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_ci if (head->Mask & GL_CLIENT_PIXEL_STORE_BIT) { 1375bf215546Sopenharmony_ci copy_pixelstore(ctx, &ctx->Pack, &head->Pack); 1376bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &head->Pack.BufferObj, NULL); 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ci copy_pixelstore(ctx, &ctx->Unpack, &head->Unpack); 1379bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &head->Unpack.BufferObj, NULL); 1380bf215546Sopenharmony_ci } 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci if (head->Mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1383bf215546Sopenharmony_ci restore_array_attrib(ctx, &ctx->Array, &head->Array); 1384bf215546Sopenharmony_ci 1385bf215546Sopenharmony_ci /* _mesa_unbind_array_object_vbos can't use NonDefaultStateMask because 1386bf215546Sopenharmony_ci * it's used by internal VAOs which don't always update the mask, so do 1387bf215546Sopenharmony_ci * it manually here. 1388bf215546Sopenharmony_ci */ 1389bf215546Sopenharmony_ci GLbitfield mask = head->VAO.NonDefaultStateMask; 1390bf215546Sopenharmony_ci while (mask) { 1391bf215546Sopenharmony_ci unsigned i = u_bit_scan(&mask); 1392bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &head->VAO.BufferBinding[i].BufferObj, NULL); 1393bf215546Sopenharmony_ci } 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &head->VAO.IndexBufferObj, NULL); 1396bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, &head->Array.ArrayBufferObj, NULL); 1397bf215546Sopenharmony_ci } 1398bf215546Sopenharmony_ci} 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_civoid GLAPIENTRY 1401bf215546Sopenharmony_ci_mesa_ClientAttribDefaultEXT( GLbitfield mask ) 1402bf215546Sopenharmony_ci{ 1403bf215546Sopenharmony_ci if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 1404bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); 1405bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); 1406bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); 1407bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_SKIP_IMAGES, 0); 1408bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_ROW_LENGTH, 0); 1409bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_SKIP_ROWS, 0); 1410bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 1411bf215546Sopenharmony_ci _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, 4); 1412bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); 1413bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); 1414bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_IMAGE_HEIGHT, 0); 1415bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_SKIP_IMAGES, 0); 1416bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_ROW_LENGTH, 0); 1417bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_SKIP_ROWS, 0); 1418bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_SKIP_PIXELS, 0); 1419bf215546Sopenharmony_ci _mesa_PixelStorei(GL_PACK_ALIGNMENT, 4); 1420bf215546Sopenharmony_ci 1421bf215546Sopenharmony_ci _mesa_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 1422bf215546Sopenharmony_ci _mesa_BindBuffer(GL_PIXEL_PACK_BUFFER, 0); 1423bf215546Sopenharmony_ci } 1424bf215546Sopenharmony_ci if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1425bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 1426bf215546Sopenharmony_ci int i; 1427bf215546Sopenharmony_ci 1428bf215546Sopenharmony_ci _mesa_BindBuffer(GL_ARRAY_BUFFER, 0); 1429bf215546Sopenharmony_ci _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_ci _mesa_DisableClientState(GL_EDGE_FLAG_ARRAY); 1432bf215546Sopenharmony_ci _mesa_EdgeFlagPointer(0, 0); 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ci _mesa_DisableClientState(GL_INDEX_ARRAY); 1435bf215546Sopenharmony_ci _mesa_IndexPointer(GL_FLOAT, 0, 0); 1436bf215546Sopenharmony_ci 1437bf215546Sopenharmony_ci _mesa_DisableClientState(GL_SECONDARY_COLOR_ARRAY); 1438bf215546Sopenharmony_ci _mesa_SecondaryColorPointer(4, GL_FLOAT, 0, 0); 1439bf215546Sopenharmony_ci 1440bf215546Sopenharmony_ci _mesa_DisableClientState(GL_FOG_COORD_ARRAY); 1441bf215546Sopenharmony_ci _mesa_FogCoordPointer(GL_FLOAT, 0, 0); 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 1444bf215546Sopenharmony_ci _mesa_ClientActiveTexture(GL_TEXTURE0 + i); 1445bf215546Sopenharmony_ci _mesa_DisableClientState(GL_TEXTURE_COORD_ARRAY); 1446bf215546Sopenharmony_ci _mesa_TexCoordPointer(4, GL_FLOAT, 0, 0); 1447bf215546Sopenharmony_ci } 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci _mesa_DisableClientState(GL_COLOR_ARRAY); 1450bf215546Sopenharmony_ci _mesa_ColorPointer(4, GL_FLOAT, 0, 0); 1451bf215546Sopenharmony_ci 1452bf215546Sopenharmony_ci _mesa_DisableClientState(GL_NORMAL_ARRAY); 1453bf215546Sopenharmony_ci _mesa_NormalPointer(GL_FLOAT, 0, 0); 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci _mesa_DisableClientState(GL_VERTEX_ARRAY); 1456bf215546Sopenharmony_ci _mesa_VertexPointer(4, GL_FLOAT, 0, 0); 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci for (i = 0; i < ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs; i++) { 1459bf215546Sopenharmony_ci _mesa_DisableVertexAttribArray(i); 1460bf215546Sopenharmony_ci _mesa_VertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); 1461bf215546Sopenharmony_ci } 1462bf215546Sopenharmony_ci 1463bf215546Sopenharmony_ci _mesa_ClientActiveTexture(GL_TEXTURE0); 1464bf215546Sopenharmony_ci 1465bf215546Sopenharmony_ci _mesa_PrimitiveRestartIndex_no_error(0); 1466bf215546Sopenharmony_ci if (ctx->Version >= 31) 1467bf215546Sopenharmony_ci _mesa_Disable(GL_PRIMITIVE_RESTART); 1468bf215546Sopenharmony_ci else if (_mesa_has_NV_primitive_restart(ctx)) 1469bf215546Sopenharmony_ci _mesa_DisableClientState(GL_PRIMITIVE_RESTART_NV); 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci if (_mesa_has_ARB_ES3_compatibility(ctx)) 1472bf215546Sopenharmony_ci _mesa_Disable(GL_PRIMITIVE_RESTART_FIXED_INDEX); 1473bf215546Sopenharmony_ci } 1474bf215546Sopenharmony_ci} 1475bf215546Sopenharmony_ci 1476bf215546Sopenharmony_civoid GLAPIENTRY 1477bf215546Sopenharmony_ci_mesa_PushClientAttribDefaultEXT( GLbitfield mask ) 1478bf215546Sopenharmony_ci{ 1479bf215546Sopenharmony_ci _mesa_PushClientAttrib(mask); 1480bf215546Sopenharmony_ci _mesa_ClientAttribDefaultEXT(mask); 1481bf215546Sopenharmony_ci} 1482bf215546Sopenharmony_ci 1483bf215546Sopenharmony_ci 1484bf215546Sopenharmony_ci/** 1485bf215546Sopenharmony_ci * Free any attribute state data that might be attached to the context. 1486bf215546Sopenharmony_ci */ 1487bf215546Sopenharmony_civoid 1488bf215546Sopenharmony_ci_mesa_free_attrib_data(struct gl_context *ctx) 1489bf215546Sopenharmony_ci{ 1490bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(ctx->AttribStack); i++) 1491bf215546Sopenharmony_ci FREE(ctx->AttribStack[i]); 1492bf215546Sopenharmony_ci} 1493bf215546Sopenharmony_ci 1494bf215546Sopenharmony_ci 1495bf215546Sopenharmony_civoid 1496bf215546Sopenharmony_ci_mesa_init_attrib(struct gl_context *ctx) 1497bf215546Sopenharmony_ci{ 1498bf215546Sopenharmony_ci /* Renderer and client attribute stacks */ 1499bf215546Sopenharmony_ci ctx->AttribStackDepth = 0; 1500bf215546Sopenharmony_ci ctx->ClientAttribStackDepth = 0; 1501bf215546Sopenharmony_ci} 1502