#include "api_arrayelt.h"
#include "api_exec.h"
#include "api_loopback.h"
-#include "api_validate.h"
+#include "draw_validate.h"
#include "atifragshader.h"
#include "config.h"
#include "bufferobj.h"
OPCODE_STENCIL_FUNC_SEPARATE,
OPCODE_STENCIL_OP_SEPARATE,
OPCODE_STENCIL_MASK_SEPARATE,
-
+ /* GL_NV_primitive_restart */
+ OPCODE_PRIMITIVE_RESTART_NV,
/* GL_ARB_shader_objects */
OPCODE_USE_PROGRAM,
OPCODE_UNIFORM_1F,
/* EXT_window_rectangles */
OPCODE_WINDOW_RECTANGLES,
+ /* NV_conservative_raster */
+ OPCODE_SUBPIXEL_PRECISION_BIAS,
+
+ /* NV_conservative_raster_dilate */
+ OPCODE_CONSERVATIVE_RASTER_PARAMETER_F,
+
+ /* NV_conservative_raster_pre_snap_triangles */
+ OPCODE_CONSERVATIVE_RASTER_PARAMETER_I,
+
/* The following three are meta instructions */
OPCODE_ERROR, /* raise compiled-in error */
OPCODE_CONTINUE,
/* for some commands, we need to free malloc'd memory */
case OPCODE_MAP1:
free(get_pointer(&n[6]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_MAP2:
free(get_pointer(&n[10]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_CALL_LISTS:
free(get_pointer(&n[3]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_DRAW_PIXELS:
free(get_pointer(&n[5]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_BITMAP:
free(get_pointer(&n[7]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_POLYGON_STIPPLE:
free(get_pointer(&n[1]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE1D:
free(get_pointer(&n[8]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE2D:
free(get_pointer(&n[9]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE3D:
free(get_pointer(&n[10]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE1D:
free(get_pointer(&n[7]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE2D:
free(get_pointer(&n[9]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE3D:
free(get_pointer(&n[11]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_1D:
free(get_pointer(&n[7]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_2D:
free(get_pointer(&n[8]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_3D:
free(get_pointer(&n[9]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
free(get_pointer(&n[7]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
free(get_pointer(&n[9]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
free(get_pointer(&n[11]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_PROGRAM_STRING_ARB:
free(get_pointer(&n[4])); /* program string */
- n += InstSize[n[0].opcode];
break;
case OPCODE_UNIFORM_1FV:
case OPCODE_UNIFORM_2FV:
case OPCODE_UNIFORM_3UIV:
case OPCODE_UNIFORM_4UIV:
free(get_pointer(&n[3]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_UNIFORM_MATRIX22:
case OPCODE_UNIFORM_MATRIX33:
case OPCODE_UNIFORM_MATRIX34:
case OPCODE_UNIFORM_MATRIX43:
free(get_pointer(&n[4]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_PROGRAM_UNIFORM_1FV:
case OPCODE_PROGRAM_UNIFORM_2FV:
case OPCODE_PROGRAM_UNIFORM_3UIV:
case OPCODE_PROGRAM_UNIFORM_4UIV:
free(get_pointer(&n[4]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_PROGRAM_UNIFORM_MATRIX22F:
case OPCODE_PROGRAM_UNIFORM_MATRIX33F:
case OPCODE_PROGRAM_UNIFORM_MATRIX34F:
case OPCODE_PROGRAM_UNIFORM_MATRIX43F:
free(get_pointer(&n[5]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_PIXEL_MAP:
free(get_pointer(&n[3]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_WINDOW_RECTANGLES:
free(get_pointer(&n[3]));
- n += InstSize[n[0].opcode];
break;
case OPCODE_CONTINUE:
n = (Node *) get_pointer(&n[1]);
done = GL_TRUE;
break;
default:
- /* Most frequent case */
- n += InstSize[n[0].opcode];
- break;
+ /* just increment 'n' pointer, below */
+ ;
+ }
+
+ if (opcode != OPCODE_CONTINUE) {
+ assert(InstSize[opcode] > 0);
+ n += InstSize[opcode];
}
}
}
GLuint nopNode;
Node *n;
+ assert(bytes <= BLOCK_SIZE * sizeof(Node));
+
if (opcode < OPCODE_EXT_0) {
if (InstSize[opcode] == 0) {
/* save instruction size now */
/* GL_ARB_draw_instanced. */
static void GLAPIENTRY
-save_DrawArraysInstancedARB(GLenum mode,
- GLint first,
- GLsizei count,
- GLsizei primcount)
+save_DrawArraysInstancedARB(UNUSED GLenum mode,
+ UNUSED GLint first,
+ UNUSED GLsizei count,
+ UNUSED GLsizei primcount)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
}
static void GLAPIENTRY
-save_DrawElementsInstancedARB(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- GLsizei primcount)
+save_DrawElementsInstancedARB(UNUSED GLenum mode,
+ UNUSED GLsizei count,
+ UNUSED GLenum type,
+ UNUSED const GLvoid *indices,
+ UNUSED GLsizei primcount)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
}
static void GLAPIENTRY
-save_DrawElementsInstancedBaseVertexARB(GLenum mode,
- GLsizei count,
- GLenum type,
- const GLvoid *indices,
- GLsizei primcount,
- GLint basevertex)
+save_DrawElementsInstancedBaseVertexARB(UNUSED GLenum mode,
+ UNUSED GLsizei count,
+ UNUSED GLenum type,
+ UNUSED const GLvoid *indices,
+ UNUSED GLsizei primcount,
+ UNUSED GLint basevertex)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
/* GL_ARB_base_instance. */
static void GLAPIENTRY
-save_DrawArraysInstancedBaseInstance(GLenum mode,
- GLint first,
- GLsizei count,
- GLsizei primcount,
- GLuint baseinstance)
+save_DrawArraysInstancedBaseInstance(UNUSED GLenum mode,
+ UNUSED GLint first,
+ UNUSED GLsizei count,
+ UNUSED GLsizei primcount,
+ UNUSED GLuint baseinstance)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
}
static void APIENTRY
-save_DrawElementsInstancedBaseInstance(GLenum mode,
- GLsizei count,
- GLenum type,
- const void *indices,
- GLsizei primcount,
- GLuint baseinstance)
+save_DrawElementsInstancedBaseInstance(UNUSED GLenum mode,
+ UNUSED GLsizei count,
+ UNUSED GLenum type,
+ UNUSED const void *indices,
+ UNUSED GLsizei primcount,
+ UNUSED GLuint baseinstance)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
}
static void APIENTRY
-save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
- GLsizei count,
- GLenum type,
- const void *indices,
- GLsizei primcount,
- GLint basevertex,
- GLuint baseinstance)
+save_DrawElementsInstancedBaseVertexBaseInstance(UNUSED GLenum mode,
+ UNUSED GLsizei count,
+ UNUSED GLenum type,
+ UNUSED const void *indices,
+ UNUSED GLsizei primcount,
+ UNUSED GLint basevertex,
+ UNUSED GLuint baseinstance)
{
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_OPERATION,
n[1].i = num;
n[2].e = type;
save_pointer(&n[3], lists_copy);
- };
+ }
/* After this, we don't know what state we're in. Invalidate all
* cached information previously gathered:
}
-static void GLAPIENTRY
-save_PolygonOffsetEXT(GLfloat factor, GLfloat bias)
-{
- GET_CURRENT_CONTEXT(ctx);
- /* XXX mult by DepthMaxF here??? */
- save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias);
-}
-
static void GLAPIENTRY
save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp)
{
_mesa_compile_error(ctx, GL_INVALID_OPERATION, "recursive glBegin");
}
else {
- Node *n;
-
ctx->Driver.CurrentSavePrimitive = mode;
- /* Give the driver an opportunity to hook in an optimized
- * display list compiler.
- */
- if (vbo_save_NotifyBegin(ctx, mode))
- return;
-
- SAVE_FLUSH_VERTICES(ctx);
- n = alloc_instruction(ctx, OPCODE_BEGIN, 1);
- if (n) {
- n[1].e = mode;
- }
-
- if (ctx->ExecuteFlag) {
- CALL_Begin(ctx->Exec, (mode));
- }
+ vbo_save_NotifyBegin(ctx, mode);
}
}
index_error();
}
+static void GLAPIENTRY
+save_PrimitiveRestartNV(void)
+{
+ /* Note: this is used when outside a glBegin/End pair in a display list */
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ (void) alloc_instruction(ctx, OPCODE_PRIMITIVE_RESTART_NV, 0);
+ if (ctx->ExecuteFlag) {
+ CALL_PrimitiveRestartNV(ctx->Exec, ());
+ }
+}
+
+
static void GLAPIENTRY
save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
n[2].i = x;
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform1ui(ctx->Exec, (location, x));*/
+ CALL_Uniform1ui(ctx->Exec, (location, x));
}
}
n[3].i = y;
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform2ui(ctx->Exec, (location, x, y));*/
+ CALL_Uniform2ui(ctx->Exec, (location, x, y));
}
}
n[4].i = z;
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform3ui(ctx->Exec, (location, x, y, z));*/
+ CALL_Uniform3ui(ctx->Exec, (location, x, y, z));
}
}
n[5].i = w;
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w));*/
+ CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w));
}
}
save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform1uiv(ctx->Exec, (location, count, v));*/
+ CALL_Uniform1uiv(ctx->Exec, (location, count, v));
}
}
save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform2uiv(ctx->Exec, (location, count, v));*/
+ CALL_Uniform2uiv(ctx->Exec, (location, count, v));
}
}
save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform3uiv(ctx->Exec, (location, count, v));*/
+ CALL_Uniform3uiv(ctx->Exec, (location, count, v));
}
}
save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
- /*CALL_Uniform4uiv(ctx->Exec, (location, count, v));*/
+ CALL_Uniform4uiv(ctx->Exec, (location, count, v));
}
}
}
}
+
+/** GL_NV_conservative_raster */
+static void GLAPIENTRY
+save_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_SUBPIXEL_PRECISION_BIAS, 2);
+ if (n) {
+ n[1].ui = xbits;
+ n[2].ui = ybits;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_SubpixelPrecisionBiasNV(ctx->Exec, (xbits, ybits));
+ }
+}
+
+/** GL_NV_conservative_raster_dilate */
+static void GLAPIENTRY
+save_ConservativeRasterParameterfNV(GLenum pname, GLfloat param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_F, 2);
+ if (n) {
+ n[1].e = pname;
+ n[2].f = param;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConservativeRasterParameterfNV(ctx->Exec, (pname, param));
+ }
+}
+
+/** GL_NV_conservative_raster_pre_snap_triangles */
+static void GLAPIENTRY
+save_ConservativeRasterParameteriNV(GLenum pname, GLint param)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_I, 2);
+ if (n) {
+ n[1].e = pname;
+ n[2].i = param;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_ConservativeRasterParameteriNV(ctx->Exec, (pname, param));
+ }
+}
+
+
/**
* Save an error-generating command into display list.
*
n[5].i, n[6].i, n[7].i, n[8].i,
n[9].i, n[10].e));
break;
+ case OPCODE_PRIMITIVE_RESTART_NV:
+ CALL_PrimitiveRestartNV(ctx->Exec, ());
+ break;
+
case OPCODE_USE_PROGRAM:
CALL_UseProgram(ctx->Exec, (n[1].ui));
break;
CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_1UI:
- /*CALL_Uniform1uiARB(ctx->Exec, (n[1].i, n[2].i));*/
+ CALL_Uniform1ui(ctx->Exec, (n[1].i, n[2].i));
break;
case OPCODE_UNIFORM_2UI:
- /*CALL_Uniform2uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i));*/
+ CALL_Uniform2ui(ctx->Exec, (n[1].i, n[2].i, n[3].i));
break;
case OPCODE_UNIFORM_3UI:
- /*CALL_Uniform3uiARB(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));*/
+ CALL_Uniform3ui(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
break;
case OPCODE_UNIFORM_4UI:
- /*CALL_Uniform4uiARB(ctx->Exec,
- (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
- */
+ CALL_Uniform4ui(ctx->Exec,
+ (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
break;
case OPCODE_UNIFORM_1UIV:
- /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i,
- get_pointer(&n[3])));*/
+ CALL_Uniform1uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_2UIV:
- /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i,
- get_pointer(&n[3])));*/
+ CALL_Uniform2uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_3UIV:
- /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i,
- get_pointer(&n[3])));*/
+ CALL_Uniform3uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_4UIV:
- /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i,
- get_pointer(&n[3])));*/
+ CALL_Uniform4uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_MATRIX22:
CALL_UniformMatrix2fv(ctx->Exec,
ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3])));
break;
+ /* GL_NV_conservative_raster */
+ case OPCODE_SUBPIXEL_PRECISION_BIAS:
+ CALL_SubpixelPrecisionBiasNV(ctx->Exec, (n[1].ui, n[2].ui));
+ break;
+
+ /* GL_NV_conservative_raster_dilate */
+ case OPCODE_CONSERVATIVE_RASTER_PARAMETER_F:
+ CALL_ConservativeRasterParameterfNV(ctx->Exec, (n[1].e, n[2].f));
+ break;
+
+ /* GL_NV_conservative_raster_pre_snap_triangles */
+ case OPCODE_CONSERVATIVE_RASTER_PARAMETER_I:
+ CALL_ConservativeRasterParameteriNV(ctx->Exec, (n[1].e, n[2].i));
+ break;
+
case OPCODE_CONTINUE:
n = (Node *) get_pointer(&n[1]);
break;
/* increment n to point to next compiled command */
if (opcode != OPCODE_CONTINUE) {
+ assert(InstSize[opcode] > 0);
n += InstSize[opcode];
}
}
vbo_save_NewList(ctx, name, mode);
- ctx->CurrentDispatch = ctx->Save;
- _glapi_set_dispatch(ctx->CurrentDispatch);
+ ctx->CurrentServerDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentServerDispatch);
+ if (ctx->MarshalExec == NULL) {
+ ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+ }
}
ctx->ExecuteFlag = GL_TRUE;
ctx->CompileFlag = GL_FALSE;
- ctx->CurrentDispatch = ctx->Exec;
- _glapi_set_dispatch(ctx->CurrentDispatch);
+ ctx->CurrentServerDispatch = ctx->Exec;
+ _glapi_set_dispatch(ctx->CurrentServerDispatch);
+ if (ctx->MarshalExec == NULL) {
+ ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+ }
}
/* also restore API function pointers to point to "save" versions */
if (save_compile_flag) {
- ctx->CurrentDispatch = ctx->Save;
- _glapi_set_dispatch(ctx->CurrentDispatch);
+ ctx->CurrentServerDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentServerDispatch);
+ if (ctx->MarshalExec == NULL) {
+ ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+ }
}
}
/* also restore API function pointers to point to "save" versions */
if (save_compile_flag) {
- ctx->CurrentDispatch = ctx->Save;
- _glapi_set_dispatch(ctx->CurrentDispatch);
+ ctx->CurrentServerDispatch = ctx->Save;
+ _glapi_set_dispatch(ctx->CurrentServerDispatch);
+ if (ctx->MarshalExec == NULL) {
+ ctx->CurrentClientDispatch = ctx->CurrentServerDispatch;
+ }
}
}
SET_BlendColorEXT(table, save_BlendColorEXT);
#endif
- /* 3. GL_EXT_polygon_offset */
- SET_PolygonOffsetEXT(table, save_PolygonOffsetEXT);
-
/* 6. GL_EXT_texture3d */
#if 0
SET_CopyTexSubImage3DEXT(table, save_CopyTexSubImage3D);
SET_ClearBufferuiv(table, save_ClearBufferuiv);
SET_ClearBufferfv(table, save_ClearBufferfv);
SET_ClearBufferfi(table, save_ClearBufferfi);
-#if 0
SET_Uniform1ui(table, save_Uniform1ui);
SET_Uniform2ui(table, save_Uniform2ui);
SET_Uniform3ui(table, save_Uniform3ui);
SET_Uniform2uiv(table, save_Uniform2uiv);
SET_Uniform3uiv(table, save_Uniform3uiv);
SET_Uniform4uiv(table, save_Uniform4uiv);
-#else
- (void) save_Uniform1ui;
- (void) save_Uniform2ui;
- (void) save_Uniform3ui;
- (void) save_Uniform4ui;
- (void) save_Uniform1uiv;
- (void) save_Uniform2uiv;
- (void) save_Uniform3uiv;
- (void) save_Uniform4uiv;
-#endif
/* These are: */
SET_BeginTransformFeedback(table, save_BeginTransformFeedback);
SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv);
SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv);
- /* GL_EXT_polygon_offset_clamp */
+ /* GL_{ARB,EXT}_polygon_offset_clamp */
SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT);
/* GL_EXT_window_rectangles */
SET_WindowRectanglesEXT(table, save_WindowRectanglesEXT);
+
+ /* GL_NV_conservative_raster */
+ SET_SubpixelPrecisionBiasNV(table, save_SubpixelPrecisionBiasNV);
+
+ /* GL_NV_conservative_raster_dilate */
+ SET_ConservativeRasterParameterfNV(table, save_ConservativeRasterParameterfNV);
+
+ /* GL_NV_conservative_raster_pre_snap_triangles */
+ SET_ConservativeRasterParameteriNV(table, save_ConservativeRasterParameteriNV);
}
}
/* increment n to point to next compiled command */
if (opcode != OPCODE_CONTINUE) {
+ assert(InstSize[opcode] > 0);
n += InstSize[opcode];
}
}
vfmt->VertexAttrib3fvARB = save_VertexAttrib3fvARB;
vfmt->VertexAttrib4fARB = save_VertexAttrib4fARB;
vfmt->VertexAttrib4fvARB = save_VertexAttrib4fvARB;
+
+ vfmt->PrimitiveRestartNV = save_PrimitiveRestartNV;
}