#include "buffers.h"
#include "bufferobj.h"
#include "clear.h"
-#include "colormac.h"
#include "context.h"
#include "depth.h"
#include "enable.h"
};
+/** An unused GL_*_BIT value */
+#define DUMMY_BIT 0x10000000
+
+
/**
* Allocate new attribute node of given type/kind. Attach payload data.
* Insert it into the linked list named by 'head'.
{
void *attribute;
- attribute = MALLOC(attr_size);
+ attribute = malloc(attr_size);
if (attribute == NULL) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
return false;
memcpy(attribute, attr_data, attr_size);
}
else {
- FREE(attribute);
+ free(attribute);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
return false;
}
/* groups specified by the mask. */
head = NULL;
+ if (mask == 0) {
+ /* if mask is zero we still need to push something so that we
+ * don't get a GL_STACK_UNDERFLOW error in glPopAttrib().
+ */
+ GLuint dummy = 0;
+ if (!push_attrib(ctx, &head, DUMMY_BIT, sizeof(dummy), &dummy))
+ goto end;
+ }
+
if (mask & GL_ACCUM_BUFFER_BIT) {
if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
sizeof(struct gl_accum_attrib),
attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
}
else {
- FREE(attr);
+ free(attr);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
goto end;
}
attr->FragmentProgram = ctx->FragmentProgram.Enabled;
if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) {
- FREE(attr);
+ free(attr);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
goto end;
}
attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
}
else {
- FREE(attr);
+ free(attr);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
goto end;
}
}
if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) {
- FREE(texstate);
+ free(texstate);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
goto end;
}
_mesa_set_enable(ctx, GL_TEXTURE_2D, !!(unit->Enabled & TEXTURE_2D_BIT));
_mesa_set_enable(ctx, GL_TEXTURE_3D, !!(unit->Enabled & TEXTURE_3D_BIT));
if (ctx->Extensions.ARB_texture_cube_map) {
- _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
!!(unit->Enabled & TEXTURE_CUBE_BIT));
}
if (ctx->Extensions.NV_texture_rectangle) {
/* don't restore state for unsupported targets to prevent
* raising GL errors.
*/
- if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
+ if (obj->Target == GL_TEXTURE_CUBE_MAP &&
!ctx->Extensions.ARB_texture_cube_map) {
continue;
}
if (MESA_VERBOSE & VERBOSE_API) {
_mesa_debug(ctx, "glPopAttrib %s\n",
- _mesa_lookup_enum_by_nr(attr->kind));
+ _mesa_enum_to_string(attr->kind));
}
switch (attr->kind) {
+ case DUMMY_BIT:
+ /* do nothing */
+ break;
+
case GL_ACCUM_BUFFER_BIT:
{
const struct gl_accum_attrib *accum;
_mesa_ClearDepth(depth->Clear);
_mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
_mesa_DepthMask(depth->Mask);
+ if (ctx->Extensions.EXT_depth_bounds_test) {
+ _mesa_set_enable(ctx, GL_DEPTH_BOUNDS_TEST_EXT,
+ depth->BoundsTest);
+ _mesa_DepthBoundsEXT(depth->BoundsMin, depth->BoundsMax);
+ }
}
break;
case GL_ENABLE_BIT:
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
_mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
- (GLint) point->CoordReplace[u]);
+ !!(point->CoordReplace & (1u << u)));
}
_mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
if (ctx->Extensions.NV_point_sprite)
_mesa_FrontFace(polygon->FrontFace);
_mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
_mesa_PolygonMode(GL_BACK, polygon->BackMode);
- _mesa_PolygonOffset(polygon->OffsetFactor,
- polygon->OffsetUnits);
+ _mesa_polygon_offset_clamp(ctx,
+ polygon->OffsetFactor,
+ polygon->OffsetUnits,
+ polygon->OffsetClamp);
_mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
_mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
_mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
_mesa_set_enablei(ctx, GL_SCISSOR_TEST, i,
(scissor->EnableFlags >> i) & 1);
}
+ if (ctx->Extensions.EXT_window_rectangles) {
+ STATIC_ASSERT(sizeof(struct gl_scissor_rect) ==
+ 4 * sizeof(GLint));
+ _mesa_WindowRectanglesEXT(
+ scissor->WindowRectMode, scissor->NumWindowRects,
+ (const GLint *)scissor->WindowRects);
+ }
}
break;
case GL_STENCIL_BUFFER_BIT:
if (xform->DepthClamp != ctx->Transform.DepthClamp)
_mesa_set_enable(ctx, GL_DEPTH_CLAMP,
ctx->Transform.DepthClamp);
+ if (ctx->Extensions.ARB_clip_control)
+ _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode);
}
break;
case GL_TEXTURE_BIT:
#define GL_CLIENT_UNPACK_BIT (1<<21)
/**
- * Copy gl_array_object from src to dest.
+ * Copy gl_vertex_array_object from src to dest.
* 'dest' must be in an initialized state.
*/
static void
copy_array_object(struct gl_context *ctx,
- struct gl_array_object *dest,
- struct gl_array_object *src)
+ struct gl_vertex_array_object *dest,
+ struct gl_vertex_array_object *src)
{
GLuint i;
/* In theory must be the same anyway, but on recreate make sure it matches */
dest->ARBsemantics = src->ARBsemantics;
- for (i = 0; i < Elements(src->_VertexAttrib); i++) {
+ for (i = 0; i < ARRAY_SIZE(src->VertexAttrib); i++) {
_mesa_copy_client_array(ctx, &dest->_VertexAttrib[i], &src->_VertexAttrib[i]);
_mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]);
_mesa_copy_vertex_buffer_binding(ctx, &dest->VertexBinding[i], &src->VertexBinding[i]);
/* _Enabled must be the same than on push */
dest->_Enabled = src->_Enabled;
- dest->_MaxElement = src->_MaxElement;
+ /* The bitmask of bound VBOs needs to match the VertexBinding array */
+ dest->VertexAttribBufferMask = src->VertexAttribBufferMask;
+ dest->NewArrays = src->NewArrays;
}
/**
copy_array_object(ctx, dest->VAO, src->VAO);
/* skip ArrayBufferObj */
- /* skip ElementArrayBufferObj */
+ /* skip IndexBufferObj */
+
+ /* Invalidate draw state. It will be updated during the next draw. */
+ dest->DrawMethod = DRAW_NONE;
+ dest->_DrawArrays = NULL;
}
/**
/* Just reference them here */
_mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj,
src->ArrayBufferObj);
- _mesa_reference_buffer_object(ctx, &dest->VAO->ElementArrayBufferObj,
- src->VAO->ElementArrayBufferObj);
+ _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj,
+ src->VAO->IndexBufferObj);
}
/**
}
if (!arb_vao
- || src->VAO->ElementArrayBufferObj->Name == 0
- || _mesa_IsBuffer(src->VAO->ElementArrayBufferObj->Name))
+ || src->VAO->IndexBufferObj->Name == 0
+ || _mesa_IsBuffer(src->VAO->IndexBufferObj->Name))
_mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,
- src->VAO->ElementArrayBufferObj->Name);
+ src->VAO->IndexBufferObj->Name);
}
/**
init_array_attrib_data(struct gl_context *ctx,
struct gl_array_attrib *attrib)
{
- /* Get a non driver gl_array_object. */
- attrib->VAO = CALLOC_STRUCT( gl_array_object );
+ /* Get a non driver gl_vertex_array_object. */
+ attrib->VAO = CALLOC_STRUCT( gl_vertex_array_object );
if (attrib->VAO == NULL) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
return false;
}
- _mesa_initialize_array_object(ctx, attrib->VAO, 0);
+ _mesa_initialize_vao(ctx, attrib->VAO, 0);
return true;
}
{
/* We use a non driver array object, so don't just unref since we would
* end up using the drivers DeleteArrayObject function for deletion. */
- _mesa_delete_array_object(ctx, attrib->VAO);
+ _mesa_delete_vao(ctx, attrib->VAO);
attrib->VAO = 0;
_mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL);
}
}
else {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
- FREE(attr);
+ free(attr);
goto end;
}
}
else {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
- FREE(attr);
+ free(attr);
goto end;
}
}
}
if (!init_array_attrib_data(ctx, attr)) {
- FREE(attr);
+ free(attr);
goto end;
}
else {
free_array_attrib_data(ctx, attr);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
- FREE(attr);
+ free(attr);
/* goto to keep safe from possible later changes */
goto end;
}