mesa: Use SATURATE
[mesa.git] / src / mesa / main / glthread_varray.c
index ac83c7a93cd773c18a90327a8b21e68f28fe79a1..8fae4af3123c39353c1cee8248434eca81a48c7f 100644 (file)
@@ -50,6 +50,7 @@ _mesa_glthread_reset_vao(struct glthread_vao *vao)
    };
 
    vao->CurrentElementBufferName = 0;
+   vao->UserEnabled = 0;
    vao->Enabled = 0;
    vao->UserPointerMask = 0;
    vao->NonZeroDivisorMask = 0;
@@ -230,9 +231,14 @@ _mesa_glthread_ClientState(struct gl_context *ctx, GLuint *vaobj,
       return;
 
    if (enable)
-      vao->Enabled |= 1u << attrib;
+      vao->UserEnabled |= 1u << attrib;
    else
-      vao->Enabled &= ~(1u << attrib);
+      vao->UserEnabled &= ~(1u << attrib);
+
+   /* The generic0 attribute superseeds the position attribute */
+   vao->Enabled = vao->UserEnabled;
+   if (vao->Enabled & VERT_BIT_GENERIC0)
+      vao->Enabled &= ~VERT_BIT_POS;
 }
 
 void _mesa_glthread_AttribDivisor(struct gl_context *ctx, const GLuint *vaobj,
@@ -302,3 +308,89 @@ _mesa_glthread_DSAAttribPointer(struct gl_context *ctx, GLuint vaobj,
    attrib_pointer(glthread, vao, buffer, attrib, size, type, stride,
                   (const void*)offset);
 }
+
+void
+_mesa_glthread_PushClientAttrib(struct gl_context *ctx, GLbitfield mask,
+                                bool set_default)
+{
+   struct glthread_state *glthread = &ctx->GLThread;
+
+   if (glthread->ClientAttribStackTop >= MAX_CLIENT_ATTRIB_STACK_DEPTH)
+      return;
+
+   struct glthread_client_attrib *top =
+      &glthread->ClientAttribStack[glthread->ClientAttribStackTop];
+
+   if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
+      top->VAO = *glthread->CurrentVAO;
+      top->CurrentArrayBufferName = glthread->CurrentArrayBufferName;
+      top->ClientActiveTexture = glthread->ClientActiveTexture;
+      top->RestartIndex = glthread->RestartIndex;
+      top->PrimitiveRestart = glthread->PrimitiveRestart;
+      top->PrimitiveRestartFixedIndex = glthread->PrimitiveRestartFixedIndex;
+      top->Valid = true;
+   } else {
+      top->Valid = false;
+   }
+
+   glthread->ClientAttribStackTop++;
+
+   if (set_default)
+      _mesa_glthread_ClientAttribDefault(ctx, mask);
+}
+
+void
+_mesa_glthread_PopClientAttrib(struct gl_context *ctx)
+{
+   struct glthread_state *glthread = &ctx->GLThread;
+
+   if (glthread->ClientAttribStackTop == 0)
+      return;
+
+   glthread->ClientAttribStackTop--;
+
+   struct glthread_client_attrib *top =
+      &glthread->ClientAttribStack[glthread->ClientAttribStackTop];
+
+   if (!top->Valid)
+      return;
+
+   /* Popping a delete VAO is an error. */
+   struct glthread_vao *vao = NULL;
+   if (top->VAO.Name) {
+      vao = lookup_vao(ctx, top->VAO.Name);
+      if (!vao)
+         return;
+   }
+
+   /* Restore states. */
+   glthread->CurrentArrayBufferName = top->CurrentArrayBufferName;
+   glthread->ClientActiveTexture = top->ClientActiveTexture;
+   glthread->RestartIndex = top->RestartIndex;
+   glthread->PrimitiveRestart = top->PrimitiveRestart;
+   glthread->PrimitiveRestartFixedIndex = top->PrimitiveRestartFixedIndex;
+
+   if (!vao)
+      vao = &glthread->DefaultVAO;
+
+   assert(top->VAO.Name == vao->Name);
+   *vao = top->VAO; /* Copy all fields. */
+   glthread->CurrentVAO = vao;
+}
+
+void
+_mesa_glthread_ClientAttribDefault(struct gl_context *ctx, GLbitfield mask)
+{
+   struct glthread_state *glthread = &ctx->GLThread;
+
+   if (!(mask & GL_CLIENT_VERTEX_ARRAY_BIT))
+      return;
+
+   glthread->CurrentArrayBufferName = 0;
+   glthread->ClientActiveTexture = 0;
+   glthread->RestartIndex = 0;
+   glthread->PrimitiveRestart = false;
+   glthread->PrimitiveRestartFixedIndex = false;
+   glthread->CurrentVAO = &glthread->DefaultVAO;
+   _mesa_glthread_reset_vao(glthread->CurrentVAO);
+}